1use crate::hal::blocking::i2c::{Read, Write, WriteRead};
6
7#[cfg(any(
8 feature = "stm32l451",
9 feature = "stm32l452",
10 feature = "stm32l462",
11 feature = "stm32l496",
12 feature = "stm32l4a6",
13 feature = "stm32l4r9",
20 feature = "stm32l4s9",
21))]
22use crate::pac::I2C4;
23use crate::pac::{i2c1, I2C1, I2C2, I2C3};
24
25use crate::rcc::{Clocks, Enable, RccBus, Reset};
26use crate::time::Hertz;
27use cast::{u16, u8};
28use core::ops::Deref;
29
30#[non_exhaustive]
32#[derive(Debug)]
33pub enum Error {
34 Bus,
36 Arbitration,
38 Nack,
40 }
45
46#[doc(hidden)]
47pub(self) mod private {
48 pub trait Sealed {}
49}
50
51pub trait SclPin<I2C>: private::Sealed {}
53
54pub trait SdaPin<I2C>: private::Sealed {}
56
57macro_rules! pins {
58 ($spi:ident, $af:literal, SCL: [$($scl:ident),*], SDA: [$($sda:ident),*]) => {
59 $(
60 impl super::private::Sealed for $scl<Alternate<OpenDrain, $af>> {}
61 impl super::SclPin<$spi> for $scl<Alternate<OpenDrain, $af>> {}
62 )*
63 $(
64 impl super::private::Sealed for $sda<Alternate<OpenDrain, $af>> {}
65 impl super::SdaPin<$spi> for $sda<Alternate<OpenDrain, $af>> {}
66 )*
67 }
68}
69
70pub struct I2c<I2C, PINS> {
72 i2c: I2C,
73 pins: PINS,
74}
75
76pub struct Config {
77 presc: u8,
78 sclh: u8,
79 scll: u8,
80 scldel: u8,
81 sdadel: u8,
82}
83
84impl Config {
85 pub fn new(freq: Hertz, clocks: Clocks) -> Self {
86 let freq = freq.raw();
87 assert!(freq <= 1_000_000);
88
89 let i2cclk = clocks.pclk1().raw();
98 let ratio = i2cclk / freq - 4;
99 let (presc, scll, sclh, sdadel, scldel) = if freq >= 100_000 {
100 let presc = ratio / 387;
103
104 let sclh = ((ratio / (presc + 1)) - 3) / 3;
105 let scll = 2 * (sclh + 1) - 1;
106
107 let (sdadel, scldel) = if freq > 400_000 {
108 let sdadel = 0;
110 let scldel = i2cclk / 4_000_000 / (presc + 1) - 1;
111
112 (sdadel, scldel)
113 } else {
114 let sdadel = i2cclk / 8_000_000 / (presc + 1);
116 let scldel = i2cclk / 2_000_000 / (presc + 1) - 1;
117
118 (sdadel, scldel)
119 };
120
121 (presc, scll, sclh, sdadel, scldel)
122 } else {
123 let presc = ratio / 514;
126
127 let sclh = ((ratio / (presc + 1)) - 2) / 2;
128 let scll = sclh;
129
130 let sdadel = i2cclk / 2_000_000 / (presc + 1);
131 let scldel = i2cclk / 800_000 / (presc + 1) - 1;
132
133 (presc, scll, sclh, sdadel, scldel)
134 };
135
136 macro_rules! u8_or_panic {
137 ($value: expr, $message: literal) => {
138 match u8($value) {
139 Ok(value) => value,
140 Err(_) => panic!($message),
141 }
142 };
143 }
144
145 let presc = u8_or_panic!(presc, "I2C pres");
146 assert!(presc < 16);
147
148 let scldel = u8_or_panic!(scldel, "I2C scldel");
149 assert!(scldel < 16);
150
151 let sdadel = u8_or_panic!(sdadel, "I2C sdadel");
152 assert!(sdadel < 16);
153
154 let sclh = u8_or_panic!(sclh, "I2C sclh");
155 let scll = u8_or_panic!(scll, "I2C scll");
156
157 Self {
158 presc,
159 sclh,
160 scll,
161 scldel,
162 sdadel,
163 }
164 }
165
166 pub fn with_timing(timing_bits: u32) -> Self {
168 Self {
169 presc: ((timing_bits >> 28) & 0xf) as u8,
170 scldel: ((timing_bits >> 20) & 0xf) as u8,
171 sdadel: ((timing_bits >> 16) & 0xf) as u8,
172 sclh: ((timing_bits >> 8) & 0xff) as u8,
173 scll: (timing_bits & 0xff) as u8,
174 }
175 }
176}
177
178macro_rules! hal {
179 ($i2c_type: ident, $i2cX: ident) => {
180 impl<SCL, SDA> I2c<$i2c_type, (SCL, SDA)> {
181 pub fn $i2cX(
182 i2c: $i2c_type,
183 pins: (SCL, SDA),
184 config: Config,
185 apb1: &mut <$i2c_type as RccBus>::Bus,
186 ) -> Self
187 where
188 SCL: SclPin<$i2c_type>,
189 SDA: SdaPin<$i2c_type>,
190 {
191 <$i2c_type>::enable(apb1);
192 <$i2c_type>::reset(apb1);
193 Self::new(i2c, pins, config)
194 }
195 }
196 };
197}
198
199hal!(I2C1, i2c1);
200hal!(I2C2, i2c2);
201hal!(I2C3, i2c3);
202
203#[cfg(any(
204 feature = "stm32l451",
205 feature = "stm32l452",
206 feature = "stm32l462",
207 feature = "stm32l496",
208 feature = "stm32l4a6",
209 feature = "stm32l4r9",
216 feature = "stm32l4s9",
217))]
218hal!(I2C4, i2c4);
219
220impl<SCL, SDA, I2C> I2c<I2C, (SCL, SDA)>
221where
222 I2C: Deref<Target = i2c1::RegisterBlock>,
223{
224 fn new(i2c: I2C, pins: (SCL, SDA), config: Config) -> Self
226 where
227 SCL: SclPin<I2C>,
228 SDA: SdaPin<I2C>,
229 {
230 i2c.cr1.modify(|_, w| w.pe().clear_bit());
232 i2c.timingr.write(|w| {
234 w.presc()
235 .bits(config.presc)
236 .scll()
237 .bits(config.scll)
238 .sclh()
239 .bits(config.sclh)
240 .sdadel()
241 .bits(config.sdadel)
242 .scldel()
243 .bits(config.scldel)
244 });
245
246 i2c.cr1.write(|w| w.pe().set_bit());
248
249 I2c { i2c, pins }
250 }
251
252 pub fn free(self) -> (I2C, (SCL, SDA)) {
254 (self.i2c, self.pins)
255 }
256}
257
258macro_rules! flush_txdr {
261 ($i2c:expr) => {
262 if $i2c.isr.read().txis().bit_is_set() {
264 $i2c.txdr.write(|w| w.txdata().bits(0));
265 }
266
267 if $i2c.isr.read().txe().is_not_empty() {
269 $i2c.isr.write(|w| w.txe().set_bit());
270 }
271 };
272}
273
274macro_rules! busy_wait {
275 ($i2c:expr, $flag:ident, $variant:ident) => {
276 loop {
277 let isr = $i2c.isr.read();
278
279 if isr.$flag().$variant() {
280 break;
281 } else if isr.berr().is_error() {
282 $i2c.icr.write(|w| w.berrcf().set_bit());
283 return Err(Error::Bus);
284 } else if isr.arlo().is_lost() {
285 $i2c.icr.write(|w| w.arlocf().set_bit());
286 return Err(Error::Arbitration);
287 } else if isr.nackf().bit_is_set() {
288 $i2c.icr.write(|w| w.stopcf().set_bit().nackcf().set_bit());
289 flush_txdr!($i2c);
290 return Err(Error::Nack);
291 } else {
292 }
294 }
295 };
296}
297
298impl<PINS, I2C> Write for I2c<I2C, PINS>
299where
300 I2C: Deref<Target = i2c1::RegisterBlock>,
301{
302 type Error = Error;
303
304 fn write(&mut self, addr: u8, bytes: &[u8]) -> Result<(), Error> {
305 assert!(bytes.len() < 256);
307
308 while self.i2c.cr2.read().start().bit_is_set() {}
312
313 self.i2c.cr2.write(|w| {
317 w.start()
318 .set_bit()
319 .sadd()
320 .bits(u16(addr << 1 | 0))
321 .add10()
322 .clear_bit()
323 .rd_wrn()
324 .write()
325 .nbytes()
326 .bits(bytes.len() as u8)
327 .autoend()
328 .software()
329 });
330
331 for byte in bytes {
332 busy_wait!(self.i2c, txis, is_empty);
336
337 self.i2c.txdr.write(|w| w.txdata().bits(*byte));
339 }
340
341 busy_wait!(self.i2c, tc, is_complete);
343
344 self.i2c.cr2.write(|w| w.stop().set_bit());
346
347 Ok(())
348 }
350}
351
352impl<PINS, I2C> Read for I2c<I2C, PINS>
353where
354 I2C: Deref<Target = i2c1::RegisterBlock>,
355{
356 type Error = Error;
357
358 fn read(&mut self, addr: u8, buffer: &mut [u8]) -> Result<(), Error> {
359 assert!(buffer.len() < 256 && buffer.len() > 0);
361
362 while self.i2c.cr2.read().start().bit_is_set() {}
366
367 self.i2c.cr2.write(|w| {
371 w.sadd()
372 .bits((addr << 1 | 0) as u16)
373 .rd_wrn()
374 .read()
375 .nbytes()
376 .bits(buffer.len() as u8)
377 .start()
378 .set_bit()
379 .autoend()
380 .automatic()
381 });
382
383 for byte in buffer {
384 busy_wait!(self.i2c, rxne, is_not_empty);
386
387 *byte = self.i2c.rxdr.read().rxdata().bits();
388 }
389
390 Ok(())
393 }
395}
396
397impl<PINS, I2C> WriteRead for I2c<I2C, PINS>
398where
399 I2C: Deref<Target = i2c1::RegisterBlock>,
400{
401 type Error = Error;
402
403 fn write_read(&mut self, addr: u8, bytes: &[u8], buffer: &mut [u8]) -> Result<(), Error> {
404 assert!(bytes.len() < 256 && bytes.len() > 0);
406 assert!(buffer.len() < 256 && buffer.len() > 0);
407
408 while self.i2c.cr2.read().start().bit_is_set() {}
412
413 self.i2c.cr2.write(|w| {
417 w.start()
418 .set_bit()
419 .sadd()
420 .bits(u16(addr << 1 | 0))
421 .add10()
422 .clear_bit()
423 .rd_wrn()
424 .write()
425 .nbytes()
426 .bits(bytes.len() as u8)
427 .autoend()
428 .software()
429 });
430
431 for byte in bytes {
432 busy_wait!(self.i2c, txis, is_empty);
435
436 self.i2c.txdr.write(|w| w.txdata().bits(*byte));
438 }
439
440 busy_wait!(self.i2c, tc, is_complete);
442
443 self.i2c.cr2.write(|w| {
445 w.sadd()
446 .bits(u16(addr << 1 | 1))
447 .add10()
448 .clear_bit()
449 .rd_wrn()
450 .read()
451 .nbytes()
452 .bits(buffer.len() as u8)
453 .start()
454 .set_bit()
455 .autoend()
456 .automatic()
457 });
458
459 for byte in buffer {
460 busy_wait!(self.i2c, rxne, is_not_empty);
462
463 *byte = self.i2c.rxdr.read().rxdata().bits();
464 }
465
466 Ok(())
467 }
468}
469
470#[cfg(any(feature = "stm32l431", feature = "stm32l451", feature = "stm32l471"))]
471mod stm32l4x1_pins {
472 #[cfg(any(feature = "stm32l451"))]
473 use super::I2C4;
474 use super::{I2C1, I2C2, I2C3};
475 use crate::gpio::*;
476 #[cfg(not(feature = "stm32l471"))]
477 use gpioa::{PA10, PA7, PA9};
478 #[cfg(not(feature = "stm32l471"))]
479 use gpiob::PB4;
480 use gpiob::{PB10, PB11, PB13, PB14, PB6, PB7, PB8, PB9};
481 use gpioc::{PC0, PC1};
482
483 pins!(I2C1, 4, SCL: [PB6, PB8], SDA: [PB7, PB9]);
484
485 #[cfg(not(feature = "stm32l471"))]
486 pins!(I2C1, 4, SCL: [PA9], SDA: [PA10]);
487
488 pins!(I2C2, 4, SCL: [PB10, PB13], SDA: [PB11, PB14]);
489
490 pins!(I2C3, 4, SCL: [PC0], SDA: [PC1]);
491
492 #[cfg(not(feature = "stm32l471"))]
493 pins!(I2C3, 4, SCL: [PA7], SDA: [PB4]);
494 #[cfg(not(any(feature = "stm32l431", feature = "stm32l471")))]
495 pins!(I2C4, 4, SCL: [PD12], SDA: [PD13]);
496 #[cfg(not(any(feature = "stm32l431", feature = "stm32l471")))]
497 pins!(I2C4, 3, SCL: [PB10], SDA: [PB11]);
498}
499
500#[cfg(any(
501 feature = "stm32l412",
502 feature = "stm32l422",
503 feature = "stm32l432",
504 feature = "stm32l442",
505 feature = "stm32l452",
506 feature = "stm32l462"
507))]
508mod stm32l4x2_pins {
509 #[cfg(not(any(feature = "stm32l432", feature = "stm32l442")))]
510 use super::I2C2;
511 #[cfg(any(feature = "stm32l452", feature = "stm32l462"))]
512 use super::I2C4;
513 use super::{I2C1, I2C3};
514 use crate::gpio::*;
515 use gpioa::{PA10, PA7, PA9};
516 #[cfg(not(any(feature = "stm32l432", feature = "stm32l442")))]
517 use gpiob::{PB10, PB11, PB13, PB14, PB8, PB9};
518 use gpiob::{PB4, PB6, PB7};
519 #[cfg(not(any(feature = "stm32l432", feature = "stm32l442")))]
520 use gpioc::{PC0, PC1};
521
522 pins!(I2C1, 4, SCL: [PA9, PB6], SDA: [PA10, PB7]);
523
524 #[cfg(not(any(feature = "stm32l432", feature = "stm32l442")))]
525 pins!(I2C1, 4, SCL: [PB8], SDA: [PB9]);
526 #[cfg(not(any(feature = "stm32l432", feature = "stm32l442")))]
527 pins!(I2C2, 4, SCL: [PB10, PB13], SDA: [PB11, PB14]);
528
529 pins!(I2C3, 4, SCL: [PA7], SDA: [PB4]);
530
531 #[cfg(not(any(feature = "stm32l432", feature = "stm32l442")))]
532 pins!(I2C3, 4, SCL: [PC0], SDA: [PC1]);
533 #[cfg(any(feature = "stm32l452", feature = "stm32l462"))]
534 pins!(I2C4, 2, SCL: [PC0], SDA: [PC1]);
535 #[cfg(any(feature = "stm32l452", feature = "stm32l462"))]
536 pins!(I2C4, 3, SCL: [PB10], SDA: [PB11]);
537 #[cfg(any(feature = "stm32l452", feature = "stm32l462"))]
538 pins!(I2C4, 4, SCL: [PD12], SDA: [PD13]);
539}
540
541#[cfg(any(feature = "stm32l433", feature = "stm32l443"))]
542mod stm32l4x3_pins {
543 use super::{I2C1, I2C2, I2C3};
544 use crate::gpio::*;
545 use gpioa::{PA10, PA7, PA9};
546 use gpiob::{PB10, PB11, PB13, PB14, PB4, PB6, PB7, PB8, PB9};
547 use gpioc::{PC0, PC1};
548
549 pins!(I2C1, 4, SCL: [PA9, PB6, PB8], SDA: [PA10, PB7, PB9]);
550
551 pins!(I2C2, 4, SCL: [PB10, PB13], SDA: [PB11, PB14]);
552
553 pins!(I2C3, 4, SCL: [PA7, PC0], SDA: [PB4, PC1]);
554}
555
556#[cfg(any(feature = "stm32l475"))]
557mod stm32l4x5_pins {
558 use super::{I2C1, I2C2, I2C3};
559 use crate::gpio::*;
560 use gpiob::{PB10, PB11, PB13, PB14, PB6, PB7, PB8, PB9};
561 use gpioc::{PC0, PC1};
562
563 pins!(I2C1, 4, SCL: [PB6, PB8], SDA: [PB7, PB9]);
564
565 pins!(I2C2, 4, SCL: [PB10, PB13], SDA: [PB11, PB14]);
566
567 pins!(I2C3, 4, SCL: [PC0], SDA: [PC1]);
568}
569
570#[cfg(any(
571 feature = "stm32l476",
572 feature = "stm32l486",
573 feature = "stm32l496",
574 feature = "stm32l4a6"
575))]
576mod stm32l4x6_pins {
577 #[cfg(any(feature = "stm32l496", feature = "stm32l4a6"))]
578 use super::I2C4;
579 use super::{I2C1, I2C2, I2C3};
580 use crate::gpio::*;
581 #[cfg(any(feature = "stm32l496", feature = "stm32l4a6"))]
582 use gpioa::PA7;
583 #[cfg(any(feature = "stm32l496", feature = "stm32l4a6"))]
584 use gpiob::PB4;
585 use gpiob::{PB10, PB11, PB13, PB14, PB6, PB7, PB8, PB9};
586 use gpioc::{PC0, PC1};
587 #[cfg(any(feature = "stm32l496", feature = "stm32l4a6"))]
588 use gpiod::{PD12, PD13};
589 use gpiof::{PF0, PF1};
590 #[cfg(any(feature = "stm32l496", feature = "stm32l4a6"))]
591 use gpiof::{PF14, PF15};
592 use gpiog::{PG13, PG14, PG7, PG8};
593
594 pins!(I2C1, 4, SCL: [PB6, PB8], SDA: [PB7, PB9]);
595
596 pins!(I2C2, 4, SCL: [PB10, PB13, PF1], SDA: [PB11, PB14, PF0]);
597
598 pins!(I2C3, 4, SCL: [PC0, PG7, PG14], SDA: [PC1, PG8, PG13]);
599
600 #[cfg(any(feature = "stm32l496", feature = "stm32l4a6"))]
601 pins!(I2C3, 4, SCL: [PA7], SDA: [PB4]);
602 #[cfg(any(feature = "stm32l496", feature = "stm32l4a6"))]
603 pins!(I2C4, 4, SCL: [PD12, PF14], SDA: [PD13, PF15]);
604
605 }
612
613#[cfg(any(
614 feature = "stm32l4r9",
621 feature = "stm32l4s9",
622))]
623mod stm32l4r9_pins {
624 use super::{I2C1, I2C2, I2C3, I2C4};
625 use crate::gpio::*;
626 use gpioa::PA7;
627 use gpiob::{PB10, PB11, PB13, PB14, PB4, PB6, PB7, PB8, PB9};
628 use gpioc::{PC0, PC1, PC9};
629 use gpiod::{PD12, PD13};
630 use gpiof::{PF0, PF1, PF14, PF15};
631 use gpiog::{PG13, PG14, PG7, PG8};
632 pins!(I2C1, 4, SCL: [PB6, PB8, PG14], SDA: [PB7, PB9, PG13]);
635
636 pins!(I2C2, 4, SCL: [PB10, PB13, PF1], SDA: [PB11, PB14, PF0]);
637 pins!(I2C3, 4, SCL: [PA7, PC0, PG7], SDA: [PB4, PC1, PC9, PG8]);
640 pins!(I2C4, 3, SCL: [PB10], SDA: [PB11]);
643 pins!(I2C4, 3, SCL: [PD12, PF14], SDA: [PD13, PF15]);
644 pins!(I2C4, 5, SCL: [PB6], SDA: [PB7]);
645}