1use crate::afio::{self, RInto, Rmp};
24use crate::pac::{self, i2c1};
25use crate::rcc::{BusClock, Clocks, Enable, Rcc, Reset};
26use crate::time::{kHz, Hertz};
27use core::ops::Deref;
28
29pub mod blocking;
30pub use blocking::BlockingI2c;
31
32mod common;
33mod hal_02;
34mod hal_1;
35
36pub use common::{Address, Error, NoAcknowledgeSource};
37use common::{Hal02Operation, Hal1Operation};
38
39#[derive(Debug, Eq, PartialEq)]
40pub enum DutyCycle {
41 Ratio2to1,
42 Ratio16to9,
43}
44
45#[derive(Debug, PartialEq, Eq)]
46pub enum Mode {
47 Standard {
48 frequency: Hertz,
49 },
50 Fast {
51 frequency: Hertz,
52 duty_cycle: DutyCycle,
53 },
54}
55
56impl Mode {
57 pub fn standard(frequency: Hertz) -> Self {
58 Mode::Standard { frequency }
59 }
60
61 pub fn fast(frequency: Hertz, duty_cycle: DutyCycle) -> Self {
62 Mode::Fast {
63 frequency,
64 duty_cycle,
65 }
66 }
67
68 pub fn get_frequency(&self) -> Hertz {
69 match *self {
70 Mode::Standard { frequency } => frequency,
71 Mode::Fast { frequency, .. } => frequency,
72 }
73 }
74}
75
76impl From<Hertz> for Mode {
77 fn from(frequency: Hertz) -> Self {
78 if frequency <= kHz(100) {
79 Self::Standard { frequency }
80 } else {
81 Self::Fast {
82 frequency,
83 duty_cycle: DutyCycle::Ratio2to1,
84 }
85 }
86 }
87}
88
89pub trait I2cExt: Sized + Instance {
90 fn i2c(
91 self,
92 pins: (impl RInto<Self::Scl, 0>, impl RInto<Self::Sda, 0>),
93 mode: impl Into<Mode>,
94 rcc: &mut Rcc,
95 ) -> I2c<Self>;
96}
97
98impl<I2C: Instance> I2cExt for I2C {
99 fn i2c(
100 self,
101 pins: (impl RInto<Self::Scl, 0>, impl RInto<Self::Sda, 0>),
102 mode: impl Into<Mode>,
103 rcc: &mut Rcc,
104 ) -> I2c<Self> {
105 I2c::new(self, pins, mode, rcc)
106 }
107}
108
109pub struct I2c<I2C: Instance> {
111 i2c: I2C,
112 pins: (I2C::Scl, I2C::Sda),
113 mode: Mode,
114 pclk: Hertz,
115}
116
117pub trait Instance:
118 crate::Sealed
119 + Deref<Target = crate::pac::i2c1::RegisterBlock>
120 + Enable
121 + Reset
122 + BusClock
123 + afio::I2cCommon
124{
125}
126
127impl Instance for pac::I2C1 {}
128impl Instance for pac::I2C2 {}
129
130impl<I2C: Instance> I2c<I2C> {
131 pub fn new<const R: u8>(
133 i2c: impl Into<Rmp<I2C, R>>,
134 pins: (impl RInto<I2C::Scl, R>, impl RInto<I2C::Sda, R>),
135 mode: impl Into<Mode>,
136 rcc: &mut Rcc,
137 ) -> Self {
138 i2c.into().i2c(pins, mode, rcc)
139 }
140}
141
142impl<I2C: Instance, const R: u8> Rmp<I2C, R> {
143 pub fn i2c(
145 self,
146 pins: (impl RInto<I2C::Scl, R>, impl RInto<I2C::Sda, R>),
147 mode: impl Into<Mode>,
148 rcc: &mut Rcc,
149 ) -> I2c<I2C> {
150 let mode = mode.into();
151 I2C::enable(rcc);
152 I2C::reset(rcc);
153
154 let pclk1 = I2C::clock(&rcc.clocks);
155
156 assert!(mode.get_frequency() <= kHz(400));
157
158 let mut i2c = I2c {
159 i2c: self.0,
160 pins: (pins.0.rinto(), pins.1.rinto()),
161 mode,
162 pclk: pclk1,
163 };
164 i2c.init();
165 i2c
166 }
167}
168
169impl<I2C: Instance> I2c<I2C> {
170 fn init(&mut self) {
173 let mode = &self.mode;
174 let clock = self.pclk.raw();
176 let clc_mhz = clock / 1_000_000;
177
178 self.i2c
180 .cr2()
181 .write(|w| unsafe { w.freq().bits(clc_mhz as u8) });
182
183 let trise = match mode {
184 Mode::Standard { .. } => clc_mhz + 1,
185 Mode::Fast { .. } => clc_mhz * 300 / 1000 + 1,
186 };
187
188 self.i2c.trise().write(|w| w.trise().set(trise as u8));
190
191 match mode {
192 Mode::Standard { frequency } => {
194 let ccr = (clock / (frequency.raw() * 2)).max(4);
195
196 self.i2c.ccr().write(|w| unsafe {
198 w.f_s().clear_bit();
199 w.duty().clear_bit();
200 w.ccr().bits(ccr as u16)
201 });
202 }
203 Mode::Fast {
204 frequency,
205 duty_cycle,
206 } => match duty_cycle {
207 DutyCycle::Ratio2to1 => {
208 let ccr = (clock / (frequency.raw() * 3)).max(1);
209
210 self.i2c.ccr().write(|w| unsafe {
212 w.f_s().set_bit().duty().clear_bit().ccr().bits(ccr as u16)
213 });
214 }
215 DutyCycle::Ratio16to9 => {
216 let ccr = (clock / (frequency.raw() * 25)).max(1);
217
218 self.i2c.ccr().write(|w| unsafe {
220 w.f_s().set_bit().duty().set_bit().ccr().bits(ccr as u16)
221 });
222 }
223 },
224 }
225
226 self.i2c.cr1().modify(|_, w| w.pe().set_bit());
228 }
229
230 pub fn reset(&mut self) {
232 self.i2c.cr1().write(|w| w.pe().set_bit().swrst().set_bit());
233 self.i2c.cr1().reset();
234 self.init();
235 }
236
237 fn send_start(&mut self) {
239 self.i2c.sr1().write(|w| unsafe { w.bits(0) });
242 self.i2c.cr1().modify(|_, w| w.start().set_bit());
243 }
244
245 fn send_addr(&self, addr: u8, read: bool) {
248 self.i2c
249 .dr()
250 .write(|w| w.dr().set((addr << 1) | (u8::from(read))));
251 }
252
253 fn send_stop(&self) {
255 self.i2c.cr1().modify(|_, w| w.stop().set_bit());
256 }
257
258 pub fn release(self) -> (I2C, (I2C::Scl, I2C::Sda)) {
260 (self.i2c, self.pins)
261 }
262
263 fn check_and_clear_error_flags(&self) -> Result<i2c1::sr1::R, Error> {
264 let sr1 = self.i2c.sr1().read();
267
268 if sr1.timeout().bit_is_set() {
269 self.i2c.sr1().write(|w| w.timeout().clear_bit());
270 return Err(Error::Timeout);
271 }
272
273 if sr1.pecerr().bit_is_set() {
274 self.i2c.sr1().write(|w| w.pecerr().clear_bit());
275 return Err(Error::Crc);
276 }
277
278 if sr1.ovr().bit_is_set() {
279 self.i2c.sr1().write(|w| w.ovr().clear_bit());
280 return Err(Error::Overrun);
281 }
282
283 if sr1.af().bit_is_set() {
284 self.i2c.sr1().write(|w| w.af().clear_bit());
285 return Err(Error::NoAcknowledge(NoAcknowledgeSource::Unknown));
286 }
287
288 if sr1.arlo().bit_is_set() {
289 self.i2c.sr1().write(|w| w.arlo().clear_bit());
290 return Err(Error::ArbitrationLoss);
291 }
292
293 if sr1.berr().bit_is_set() {
296 self.i2c.sr1().write(|w| w.berr().clear_bit());
297 }
298
299 Ok(sr1)
300 }
301
302 #[inline(always)]
304 fn prepare_write(&self, addr: Address) -> Result<(), Error> {
305 while self.i2c.cr1().read().stop().bit_is_set() {}
312
313 self.i2c.sr1().write(|w| unsafe { w.bits(0) });
315 self.i2c.cr1().modify(|_, w| w.start().set_bit());
317
318 while self.check_and_clear_error_flags()?.sb().bit_is_clear() {}
320
321 loop {
323 self.check_and_clear_error_flags()?;
324
325 let sr2 = self.i2c.sr2().read();
326 if !(sr2.msl().bit_is_clear() && sr2.busy().bit_is_clear()) {
327 break;
328 }
329 }
330
331 match addr {
333 Address::Seven(addr) => {
334 self.i2c
335 .dr()
336 .write(|w| unsafe { w.bits(u16::from(addr) << 1) });
337 }
338 Address::Ten(addr) => {
339 let [msbs, lsbs] = addr.to_be_bytes();
340 let msbs = ((msbs & 0b11) << 1) & 0b11110000;
341 let dr = self.i2c.dr();
342 dr.write(|w| unsafe { w.bits(u16::from(msbs)) });
343 dr.write(|w| unsafe { w.bits(u16::from(lsbs)) });
344 }
345 }
346
347 loop {
349 let sr1 = self
351 .check_and_clear_error_flags()
352 .map_err(Error::nack_addr)?;
353
354 if sr1.addr().bit_is_set() {
356 break;
357 }
358 }
359
360 self.i2c.sr2().read();
362
363 Ok(())
364 }
365
366 fn prepare_read(&self, addr: Address, first_transaction: bool) -> Result<(), Error> {
368 while self.i2c.cr1().read().stop().bit_is_set() {}
375
376 self.i2c.sr1().write(|w| unsafe { w.bits(0) });
378 self.i2c
380 .cr1()
381 .modify(|_, w| w.start().set_bit().ack().set_bit());
382
383 while self.i2c.sr1().read().sb().bit_is_clear() {}
385
386 while {
388 let sr2 = self.i2c.sr2().read();
389 sr2.msl().bit_is_clear() && sr2.busy().bit_is_clear()
390 } {}
391
392 match addr {
394 Address::Seven(addr) => {
395 self.i2c
396 .dr()
397 .write(|w| unsafe { w.bits((u16::from(addr) << 1) | 1) });
398 }
399 Address::Ten(addr) => {
400 let [msbs, lsbs] = addr.to_be_bytes();
401 let msbs = ((msbs & 0b11) << 1) | 0b11110000;
402 let dr = self.i2c.dr();
403 if first_transaction {
404 dr.write(|w| unsafe { w.bits(u16::from(msbs)) });
405 dr.write(|w| unsafe { w.bits(u16::from(lsbs)) });
406 }
407 self.i2c.cr1().modify(|_, w| w.start().set_bit());
408 while self.i2c.sr1().read().sb().bit_is_clear() {}
410 dr.write(|w| unsafe { w.bits(u16::from(msbs | 1)) });
411 }
412 }
413
414 loop {
416 self.check_and_clear_error_flags()
417 .map_err(Error::nack_addr)?;
418 if self.i2c.sr1().read().addr().bit_is_set() {
419 break;
420 }
421 }
422
423 self.i2c.sr2().read();
425
426 Ok(())
427 }
428
429 fn write_bytes(&mut self, bytes: impl Iterator<Item = u8>) -> Result<(), Error> {
430 for c in bytes {
432 self.send_byte(c)?;
433 }
434
435 Ok(())
437 }
438
439 fn send_byte(&self, byte: u8) -> Result<(), Error> {
440 while self
443 .check_and_clear_error_flags()
444 .map_err(Error::nack_addr)?
445 .tx_e()
446 .bit_is_clear()
447 {}
448
449 self.i2c.dr().write(|w| unsafe { w.bits(u16::from(byte)) });
451
452 while self
455 .check_and_clear_error_flags()
456 .map_err(Error::nack_data)?
457 .btf()
458 .bit_is_clear()
459 {}
460
461 Ok(())
462 }
463
464 fn recv_byte(&self) -> Result<u8, Error> {
465 loop {
466 self.check_and_clear_error_flags()
468 .map_err(Error::nack_data)?;
469
470 if self.i2c.sr1().read().rx_ne().bit_is_set() {
471 break;
472 }
473 }
474
475 let value = self.i2c.dr().read().bits() as u8;
476 Ok(value)
477 }
478
479 fn read_bytes(&mut self, buffer: &mut [u8]) -> Result<(), Error> {
480 for c in buffer {
482 *c = self.recv_byte()?;
483 }
484
485 Ok(())
486 }
487
488 pub fn read(&mut self, addr: impl Into<Address>, buffer: &mut [u8]) -> Result<(), Error> {
489 self.read_inner(addr.into(), buffer, true)
490 }
491
492 #[inline(always)]
493 fn read_inner(
494 &mut self,
495 addr: Address,
496 buffer: &mut [u8],
497 first_transaction: bool,
498 ) -> Result<(), Error> {
499 if buffer.is_empty() {
500 return Err(Error::Overrun);
501 }
502
503 self.prepare_read(addr, first_transaction)?;
504 self.read_wo_prepare(buffer)
505 }
506
507 fn read_wo_prepare(&mut self, buffer: &mut [u8]) -> Result<(), Error> {
509 if let Some((last, buffer)) = buffer.split_last_mut() {
510 self.read_bytes(buffer)?;
512
513 self.i2c
515 .cr1()
516 .modify(|_, w| w.ack().clear_bit().stop().set_bit());
517
518 *last = self.recv_byte()?;
520
521 while self.i2c.cr1().read().stop().bit_is_set() {}
527
528 Ok(())
530 } else {
531 Err(Error::Overrun)
532 }
533 }
534
535 pub fn write(&mut self, addr: impl Into<Address>, bytes: &[u8]) -> Result<(), Error> {
536 self.prepare_write(addr.into())?;
537 self.write_wo_prepare(bytes)
538 }
539
540 fn write_wo_prepare(&mut self, bytes: &[u8]) -> Result<(), Error> {
542 self.write_bytes(bytes.iter().cloned())?;
543
544 self.i2c.cr1().modify(|_, w| w.stop().set_bit());
546
547 while self.i2c.cr1().read().stop().bit_is_set() {}
553
554 Ok(())
556 }
557
558 pub fn write_iter<B>(&mut self, addr: impl Into<Address>, bytes: B) -> Result<(), Error>
559 where
560 B: IntoIterator<Item = u8>,
561 {
562 self.prepare_write(addr.into())?;
563 self.write_bytes(bytes.into_iter())?;
564
565 self.i2c.cr1().modify(|_, w| w.stop().set_bit());
567
568 while self.i2c.cr1().read().stop().bit_is_set() {}
574
575 Ok(())
577 }
578
579 pub fn write_read(
580 &mut self,
581 addr: impl Into<Address>,
582 bytes: &[u8],
583 buffer: &mut [u8],
584 ) -> Result<(), Error> {
585 let addr = addr.into();
586 self.prepare_write(addr)?;
587 self.write_bytes(bytes.iter().cloned())?;
588 self.read_inner(addr, buffer, false)
589 }
590
591 pub fn write_iter_read<B>(
592 &mut self,
593 addr: impl Into<Address>,
594 bytes: B,
595 buffer: &mut [u8],
596 ) -> Result<(), Error>
597 where
598 B: IntoIterator<Item = u8>,
599 {
600 let addr = addr.into();
601 self.prepare_write(addr)?;
602 self.write_bytes(bytes.into_iter())?;
603 self.read_inner(addr, buffer, false)
604 }
605
606 pub fn transaction<'a>(
607 &mut self,
608 addr: impl Into<Address>,
609 mut ops: impl Iterator<Item = Hal1Operation<'a>>,
610 ) -> Result<(), Error> {
611 let addr = addr.into();
612 if let Some(mut prev_op) = ops.next() {
613 match &prev_op {
615 Hal1Operation::Read(_) => self.prepare_read(addr, true)?,
616 Hal1Operation::Write(_) => self.prepare_write(addr)?,
617 };
618
619 for op in ops {
620 match &mut prev_op {
622 Hal1Operation::Read(rb) => self.read_bytes(rb)?,
623 Hal1Operation::Write(wb) => self.write_bytes(wb.iter().cloned())?,
624 };
625 match (&prev_op, &op) {
627 (Hal1Operation::Read(_), Hal1Operation::Write(_)) => {
628 self.prepare_write(addr)?
629 }
630 (Hal1Operation::Write(_), Hal1Operation::Read(_)) => {
631 self.prepare_read(addr, false)?
632 }
633 _ => {} }
635
636 prev_op = op;
637 }
638
639 match prev_op {
641 Hal1Operation::Read(rb) => self.read_wo_prepare(rb)?,
642 Hal1Operation::Write(wb) => self.write_wo_prepare(wb)?,
643 };
644 }
645
646 Ok(())
648 }
649
650 pub fn transaction_slice(
651 &mut self,
652 addr: impl Into<Address>,
653 ops_slice: &mut [Hal1Operation<'_>],
654 ) -> Result<(), Error> {
655 let addr = addr.into();
656 transaction_impl!(self, addr, ops_slice, Hal1Operation);
657 Ok(())
659 }
660
661 fn transaction_slice_hal_02(
662 &mut self,
663 addr: impl Into<Address>,
664 ops_slice: &mut [Hal02Operation<'_>],
665 ) -> Result<(), Error> {
666 let addr = addr.into();
667 transaction_impl!(self, addr, ops_slice, Hal02Operation);
668 Ok(())
670 }
671}
672
673macro_rules! transaction_impl {
674 ($self:ident, $addr:ident, $ops_slice:ident, $Operation:ident) => {
675 let i2c = $self;
676 let addr = $addr;
677 let mut ops = $ops_slice.iter_mut();
678
679 if let Some(mut prev_op) = ops.next() {
680 match &prev_op {
682 $Operation::Read(_) => i2c.prepare_read(addr, true)?,
683 $Operation::Write(_) => i2c.prepare_write(addr)?,
684 };
685
686 for op in ops {
687 match &mut prev_op {
689 $Operation::Read(rb) => i2c.read_bytes(rb)?,
690 $Operation::Write(wb) => i2c.write_bytes(wb.iter().cloned())?,
691 };
692 match (&prev_op, &op) {
694 ($Operation::Read(_), $Operation::Write(_)) => i2c.prepare_write(addr)?,
695 ($Operation::Write(_), $Operation::Read(_)) => i2c.prepare_read(addr, false)?,
696 _ => {} }
698
699 prev_op = op;
700 }
701
702 match prev_op {
704 $Operation::Read(rb) => i2c.read_wo_prepare(rb)?,
705 $Operation::Write(wb) => i2c.write_wo_prepare(wb)?,
706 };
707 }
708 };
709}
710use transaction_impl;
711
712impl<I2C: Instance> embedded_hal_02::blocking::i2c::WriteIter for I2c<I2C> {
713 type Error = Error;
714
715 fn write<B>(&mut self, addr: u8, bytes: B) -> Result<(), Self::Error>
716 where
717 B: IntoIterator<Item = u8>,
718 {
719 self.write_iter(addr, bytes)
720 }
721}
722
723impl<I2C: Instance> embedded_hal_02::blocking::i2c::WriteIterRead for I2c<I2C> {
724 type Error = Error;
725
726 fn write_iter_read<B>(
727 &mut self,
728 addr: u8,
729 bytes: B,
730 buffer: &mut [u8],
731 ) -> Result<(), Self::Error>
732 where
733 B: IntoIterator<Item = u8>,
734 {
735 self.write_iter_read(addr, bytes, buffer)
736 }
737}