1use core::{future::poll_fn, marker::PhantomData, task::Poll};
10
11use cortex_m::asm;
12use embassy_hal_internal::{
13 Peri, PeripheralType, atomic_ring_buffer::RingBuffer, interrupt::InterruptExt as _,
14};
15use embassy_sync::waitqueue::AtomicWaker;
16use embedded_hal_1::i2c::SevenBitAddress;
17
18use crate::{
19 dtc::{Channel as DtcChannel, DtcInterruptHandler, Instance as DtcInstance},
20 event_link::{IcuInterrupt as _, InterruptEvent},
21 gpio::{Flex, Pin, PortFunction, WithOpenDrain},
22 interrupt::{
23 self,
24 typelevel::{Handler as InterruptHandler, Interrupt as InterruptType},
25 },
26 module_stop::ModuleStop,
27 pac::{self, iic::vals::Cks},
28 write_protect::ProtectedModify,
29};
30
31#[allow(private_bounds)]
33pub trait TransferMode: SealedTransferMode {}
34trait SealedTransferMode {}
35
36pub struct Blocking;
38
39pub struct Async<RxInt: InterruptType, TeInt: InterruptType, TxInt: InterruptType> {
41 _rx: PhantomData<RxInt>,
42 _te: PhantomData<TeInt>,
43 _tx: PhantomData<TxInt>,
44}
45
46pub struct Dtc<RxInt: InterruptType, TxDtc: DtcInstance> {
48 rx_dtc: PhantomData<RxInt>,
49 tx_dtc: DtcChannel<TxDtc>,
50}
51
52impl TransferMode for Blocking {}
53impl SealedTransferMode for Blocking {}
54
55impl<RxInt: InterruptType, TeInt: InterruptType, TxInt: InterruptType> TransferMode
56 for Async<RxInt, TeInt, TxInt>
57{
58}
59
60impl<RxInt: InterruptType, TeInt: InterruptType, TxInt: InterruptType> SealedTransferMode
61 for Async<RxInt, TeInt, TxInt>
62{
63}
64
65impl<RxInt: InterruptType, TxDtc: DtcInstance> TransferMode for Dtc<RxInt, TxDtc> {}
66impl<RxInt: InterruptType, TxDtc: DtcInstance> SealedTransferMode for Dtc<RxInt, TxDtc> {}
67
68#[allow(private_bounds)]
74pub struct I2c<'d, I: Instance, M: TransferMode> {
75 _instance: PhantomData<&'d I>,
76 mode: M,
77 _scl: Flex<'d, WithOpenDrain>,
79 _sda: Flex<'d, WithOpenDrain>,
80}
81
82#[derive(Copy, Clone, Debug)]
84#[cfg_attr(feature = "defmt", derive(defmt::Format))]
85pub struct ClockConfig {
86 pub divider: Divider,
88
89 pub low: u8,
91
92 pub high: u8,
94}
95
96#[derive(Copy, Clone, Debug)]
98#[allow(missing_docs)]
99#[cfg_attr(feature = "defmt", derive(defmt::Format))]
100pub enum Divider {
101 Div1 = 0x0,
102 Div2 = 0x01,
103 Div4 = 0x02,
104 Div8 = 0x03,
105 Div16 = 0x04,
106 Div32 = 0x05,
107 Div64 = 0x06,
108 Div128 = 0x07,
109}
110
111#[derive(Debug, Copy, Clone, Default)]
113#[cfg_attr(feature = "defmt", derive(defmt::Format))]
114pub enum I2cSpeed {
115 #[default]
117 Normal,
118
119 Fast,
121
122 #[cfg(any(ra4l1, ra6m5))]
124 FastModePlus,
125}
126
127pub struct RxInterruptHandler<I: Instance> {
129 _phantom: PhantomData<I>,
130}
131
132pub struct TeInterruptHandler<I: Instance> {
134 _phantom: PhantomData<I>,
135}
136
137pub struct TxInterruptHandler<I: Instance> {
139 _phantom: PhantomData<I>,
140}
141
142#[allow(private_bounds)]
144pub trait Instance: SealedInstance + ModuleStop + PeripheralType + 'static + Send {}
145
146pub(crate) trait SealedInstance {
147 #[cfg(feature = "defmt")]
148 const PERIPHERAL: &'static str;
149 #[cfg(not(feature = "defmt"))]
150 const PERIPHERAL: () = ();
151
152 const RX_INTERRUPT_EVENT: InterruptEvent;
153 const TE_INTERRUPT_EVENT: InterruptEvent;
154 const TX_INTERRUPT_EVENT: InterruptEvent;
155
156 fn regs() -> pac::iic::Iic;
157
158 fn rx_waker() -> &'static AtomicWaker;
160
161 fn tx_waker() -> &'static AtomicWaker;
163
164 fn te_waker() -> &'static AtomicWaker;
166
167 fn tx_buffer() -> &'static RingBuffer;
170}
171
172#[allow(private_bounds)]
174pub trait SclPin<I: Instance>: SealedSclPin<I> {}
175
176pub(crate) trait SealedSclPin<I: SealedInstance>: Pin + PeripheralType {
177 const PERIPHERAL_FUNC: PortFunction;
178
179 #[inline(always)]
180 fn set_as_scl(&self) {
181 trace!("P{}{:02}: SclPin::new", self.port(), self.pin());
182 self.set_as_pf(Self::PERIPHERAL_FUNC);
183 }
184}
185
186#[allow(private_bounds)]
188pub trait SdaPin<I: Instance>: SealedSdaPin<I> {}
189
190pub(crate) trait SealedSdaPin<I: SealedInstance>: Pin {
191 const PERIPHERAL_FUNC: PortFunction;
192
193 #[inline(always)]
194 fn set_as_sda(&self) {
195 trace!("P{}{:02}: SdaPin::new", self.port(), self.pin());
196 self.set_as_pf(Self::PERIPHERAL_FUNC);
197 }
198}
199
200impl From<Divider> for Cks {
201 fn from(value: Divider) -> Self {
202 Self::from_bits(value as u8)
203 }
204}
205
206macro_rules! instance_impl {
207 ($instance:ident, $rx_int:ident, $te_int:ident, $tx_int:ident) => {
208 paste::paste! {
209 impl crate::i2c::Instance for crate::peripherals::$instance {}
210 impl crate::i2c::SealedInstance for crate::peripherals::$instance {
211 #[cfg(feature = "defmt")]
212 const PERIPHERAL: &'static str = concat!(stringify!($instance), ": ");
213
214 const RX_INTERRUPT_EVENT: crate::event_link::InterruptEvent = crate::event_link::InterruptEvent::$rx_int;
215 const TE_INTERRUPT_EVENT: crate::event_link::InterruptEvent = crate::event_link::InterruptEvent::$te_int;
216 const TX_INTERRUPT_EVENT: crate::event_link::InterruptEvent = crate::event_link::InterruptEvent::$tx_int;
217
218 #[inline(always)]
219 fn regs() -> pac::iic::Iic {
220 let instance_ptr = crate::pac::$instance.as_ptr();
224 unsafe { crate::pac::iic::Iic::from_ptr(instance_ptr) }
225 }
226
227 fn rx_waker() -> &'static embassy_sync::waitqueue::AtomicWaker {
229 static RX_WAKER: embassy_sync::waitqueue::AtomicWaker = embassy_sync::waitqueue::AtomicWaker::new();
230 &RX_WAKER
231 }
232
233 fn te_waker() -> &'static embassy_sync::waitqueue::AtomicWaker {
235 static TE_WAKER: embassy_sync::waitqueue::AtomicWaker = embassy_sync::waitqueue::AtomicWaker::new();
236 &TE_WAKER
237 }
238
239 fn tx_waker() -> &'static embassy_sync::waitqueue::AtomicWaker {
241 static TX_WAKER: embassy_sync::waitqueue::AtomicWaker = embassy_sync::waitqueue::AtomicWaker::new();
242 &TX_WAKER
243 }
244
245 fn tx_buffer() -> &'static embassy_hal_internal::atomic_ring_buffer::RingBuffer {
246 static TX_BUF: embassy_hal_internal::atomic_ring_buffer::RingBuffer = embassy_hal_internal::atomic_ring_buffer::RingBuffer::new();
247 &TX_BUF
248 }
249 }
250 }
251 };
252}
253pub(crate) use instance_impl;
254
255impl<'d, I: Instance> I2c<'d, I, Blocking> {
256 #[inline]
268 pub fn new_blocking<C: SclPin<I>, D: SdaPin<I>>(
269 iic: Peri<'d, I>,
270 scl: Peri<'d, C>,
271 sda: Peri<'d, D>,
272 speed: I2cSpeed,
273 ) -> Self {
274 Self::new_inner(iic, scl, sda, speed, Blocking {})
275 }
276
277 fn blocking_read(&self, address: u8, data: &mut [u8]) -> Result<(), I2cError> {
278 let iic = I::regs();
279 let r_addr = (address << 1) | 0x01;
280 let data_len = data.len();
281
282 while iic.iccr2().read().bbsy() {
283 asm::nop();
284 }
285
286 iic.iccr2().modify(|r| r.set_st(true));
287
288 while !iic.icsr2().read().tdre() {
289 asm::nop();
290 }
291
292 iic.icdrt().write_value(r_addr);
293
294 let mut status = iic.icsr2().read();
295 while !status.rdrf() {
296 if status.nackf() {
297 iic.iccr2().modify(|r| r.set_sp(true));
298 return Err(I2cError::Nack);
299 }
300 asm::nop();
301 status = iic.icsr2().read();
302 }
303
304 let _ = iic.icdrr().read();
306
307 for (i, byte) in data.iter_mut().enumerate() {
308 if i == (data_len - 1) {
309 iic.icmr3().protected_modify(|r| r.set_ackbt(true));
310 }
311 while !iic.icsr2().read().rdrf() {
312 asm::nop();
313 }
314 *byte = iic.icdrr().read();
315 }
316
317 while !iic.icsr2().read().rdrf() {
318 asm::nop();
319 }
320
321 iic.iccr2().modify(|r| r.set_sp(true));
322
323 let _ = iic.icdrr().read();
325
326 while !iic.icsr2().read().stop() {
327 asm::nop()
328 }
329
330 iic.icmr3().modify(|r| r.set_wait(false));
331 iic.icsr2().modify(|r| r.set_stop(false));
332
333 Ok(())
334 }
335
336 fn blocking_write(&self, address: u8, data: &[u8]) -> Result<(), I2cError> {
337 let iic = I::regs();
338
339 let w_addr = (address << 1) | 0x00;
342
343 while iic.iccr2().read().bbsy() {
344 asm::nop();
345 }
346 iic.iccr2().modify(|r| r.set_st(true));
347
348 while !iic.icsr2().read().tdre() {
349 if iic.icsr2().read().nackf() {
350 return Err(I2cError::Nack);
351 }
352 asm::nop();
353 }
354
355 iic.icdrt().write_value(w_addr);
356 while !iic.icsr2().read().tdre() {
357 asm::nop();
358 }
359
360 if iic.icsr2().read().nackf() {
361 iic.iccr2().modify(|r| r.set_sp(true));
362 return Err(I2cError::Nack);
363 }
364
365 for byte in data.iter() {
366 while !iic.icsr2().read().tdre() {
367 asm::nop();
368 }
369 iic.icdrt().write_value(*byte);
370 }
371
372 while !iic.icsr2().read().tend() {
373 asm::nop();
374 }
375
376 iic.iccr2().modify(|r| r.set_sp(true));
377
378 while !iic.icsr2().read().stop() {
379 asm::nop();
380 }
381
382 iic.icsr2().modify(|r| {
383 r.set_stop(false);
384 r.set_nackf(false);
385 });
386
387 Ok(())
388 }
389}
390
391impl<'d, I: Instance, RxInt: InterruptType, TxDtc: DtcInstance> I2c<'d, I, Dtc<RxInt, TxDtc>> {
392 pub fn new_dtc<C: SclPin<I>, D: SdaPin<I>>(
406 iic: Peri<'d, I>,
407 scl: Peri<'d, C>,
408 sda: Peri<'d, D>,
409 speed: I2cSpeed,
410 tx_dtc: Peri<'d, TxDtc>,
411 irqs: impl interrupt::typelevel::Binding<RxInt, RxInterruptHandler<I>>
412 + interrupt::typelevel::Binding<TxDtc::Int, DtcInterruptHandler<TxDtc>>
413 + Clone
414 + 'd,
415 ) -> Self {
416 let tx_dtc = DtcChannel::new(tx_dtc, irqs);
417 let dtc = Dtc {
418 tx_dtc,
419 rx_dtc: PhantomData,
420 };
421
422 Self::new_inner(iic, scl, sda, speed, dtc)
423 }
424
425 async fn dtc_write(&mut self, address: u8, data: &[u8]) -> Result<usize, I2cError> {
426 let iic = I::regs();
427
428 if data.is_empty() {
429 return Ok(0);
430 }
431
432 let w_addr = (address << 1) | 0x00;
433
434 while iic.iccr2().read().bbsy() {}
435
436 iic.icsr2().modify(|r| {
437 r.set_start(false);
438 r.set_stop(false);
439 });
440
441 iic.icier().write(|r| {
442 r.set_stie(true);
443 r.set_spie(true);
444 r.set_tie(true);
445 });
446
447 let addr = [w_addr];
448
449 let tx1 = self
450 .mode
451 .tx_dtc
452 .prepare_write(&addr, iic.icdrt().as_ptr() as *mut _, false);
453 let tx2 = self
454 .mode
455 .tx_dtc
456 .prepare_write(data, iic.icdrt().as_ptr() as *mut _, true);
457 let chain = [tx1, tx2];
458
459 let tx = unsafe { self.mode.tx_dtc.write_chain(&chain, I::TX_INTERRUPT_EVENT) };
461
462 iic.iccr2().modify(|r| r.set_st(true));
463
464 tx.await.expect("DTC transfer failed");
465
466 while !iic.icsr2().read().tend() {}
468
469 iic.iccr2().modify(|r| r.set_sp(true));
471
472 while !iic.icsr2().read().stop() {}
473
474 iic.icsr2().modify(|r| {
475 r.set_stop(false);
476 r.set_nackf(false);
477 });
478
479 Ok(addr.len())
480 }
481
482 async fn dtc_read(&self, address: u8, data: &mut [u8]) -> Result<(), I2cError> {
483 let iic = I::regs();
484 let r_addr = (address << 1) | 0x01;
485 let data_len = data.len();
486
487 iic.icier().write(|r| r.set_rie(true));
488
489 while iic.iccr2().read().bbsy() {
490 asm::nop();
491 }
492
493 iic.iccr2().modify(|r| r.set_st(true));
494
495 while !iic.icsr2().read().tdre() {
496 asm::nop();
497 }
498
499 iic.icdrt().write_value(r_addr);
500
501 let mut status = iic.icsr2().read();
502 while !status.rdrf() {
503 if status.nackf() {
504 iic.iccr2().modify(|r| r.set_sp(true));
505 return Err(I2cError::Nack);
506 }
507 asm::nop();
508 status = iic.icsr2().read();
509 }
510
511 let _ = iic.icdrr().read();
513
514 for (i, byte) in data.iter_mut().enumerate() {
515 if i == (data_len - 1) {
516 iic.icmr3().protected_modify(|r| r.set_ackbt(true));
517 }
518
519 *byte = poll_fn(|cx| {
520 if iic.icsr2().read().rdrf() {
521 let byte = iic.icdrr().read();
522 Poll::Ready(byte)
523 } else {
524 I::rx_waker().register(cx.waker());
525 Poll::Pending
526 }
527 })
528 .await;
529 }
530
531 poll_fn(|cx| {
532 if iic.icsr2().read().rdrf() {
533 Poll::Ready(())
534 } else {
535 I::rx_waker().register(cx.waker());
536 Poll::Pending
537 }
538 })
539 .await;
540
541 iic.iccr2().modify(|r| r.set_sp(true));
542
543 let _ = iic.icdrr().read();
545
546 while !iic.icsr2().read().stop() {
547 asm::nop()
548 }
549
550 iic.icmr3().modify(|r| r.set_wait(false));
551 iic.icsr2().modify(|r| r.set_stop(false));
552
553 iic.icier().write(|r| r.set_rie(false));
554
555 Ok(())
556 }
557}
558
559impl<'d, I: Instance, RxInt: InterruptType, TeInt: InterruptType, TxInt: InterruptType>
560 I2c<'d, I, Async<RxInt, TeInt, TxInt>>
561{
562 pub fn new_async<C: SclPin<I>, D: SdaPin<I>>(
572 iic: Peri<'d, I>,
573 scl: Peri<'d, C>,
574 sda: Peri<'d, D>,
575 speed: I2cSpeed,
576 tx_buffer: &'d mut [u8],
577 irqs: impl interrupt::typelevel::Binding<RxInt, RxInterruptHandler<I>>
578 + interrupt::typelevel::Binding<TeInt, TeInterruptHandler<I>>
579 + interrupt::typelevel::Binding<TxInt, TxInterruptHandler<I>>
580 + 'd,
581 ) -> Self {
582 let _ = irqs;
583 let tx_len = tx_buffer.len();
584
585 unsafe { I::tx_buffer().init(tx_buffer.as_mut_ptr(), tx_len) };
588
589 unsafe {
591 RxInt::IRQ.enable();
593 TeInt::IRQ.enable();
594 TxInt::IRQ.enable();
595
596 RxInt::IRQ.icu_enable(I::RX_INTERRUPT_EVENT);
598 TeInt::IRQ.icu_enable(I::TE_INTERRUPT_EVENT);
599 TxInt::IRQ.icu_enable(I::TX_INTERRUPT_EVENT);
600 }
601
602 let iic_regs = I::regs();
603
604 iic_regs.icier().modify(|r| {
605 r.set_tie(true);
606 r.set_teie(false);
607 });
608
609 TeInt::IRQ.icu_unpend();
610 TxInt::IRQ.icu_unpend();
611
612 Self::new_inner(
613 iic,
614 scl,
615 sda,
616 speed,
617 Async {
618 _rx: PhantomData,
619 _te: PhantomData,
620 _tx: PhantomData,
621 },
622 )
623 }
624
625 async fn write(&self, address: u8, data: &[u8]) -> Result<usize, I2cError> {
626 let iic = I::regs();
627
628 if data.is_empty() {
629 return Ok(0);
630 }
631
632 let w_addr = (address << 1) | 0x00;
633
634 while iic.iccr2().read().bbsy() {}
635
636 iic.icsr2().modify(|r| {
637 r.set_start(false);
638 r.set_stop(false);
639 });
640
641 iic.icier().write(|r| {
642 r.set_stie(true);
643 r.set_spie(true);
644 r.set_tie(true);
645 });
646
647 let mut written: usize = 0;
648 let mut writer = unsafe { I::tx_buffer().writer() };
649
650 let out = writer.push_slice();
651 if out.is_empty() {
652 error!("{}TX buffer is full", I::PERIPHERAL);
653 }
654 out[0] = w_addr;
655 writer.push_done(1);
656 let mut started = false;
657
658 let ret = poll_fn(|cx| {
659 if written < data.len() {
660 I::tx_waker().register(cx.waker());
661
662 if I::tx_buffer().is_full() {
663 debug!("{}TX buffer full in async write", I::PERIPHERAL);
664 return Poll::Pending;
665 }
666
667 let out = writer.push_slice();
668 let chunk_len = out.len().min(data.len().saturating_sub(written));
669 out[..chunk_len].copy_from_slice(&data[written..(written + chunk_len)]);
670
671 writer.push_done(chunk_len);
672
673 written += chunk_len;
674
675 if !started {
676 started = true;
688 iic.iccr2().modify(|r| r.set_st(true));
689 }
690
691 if written < data.len() {
692 return Poll::Pending;
693 }
694
695 I::te_waker().register(cx.waker());
697
698 if !iic.icsr2().read().tend() {
699 return Poll::Pending;
700 }
701 } else {
702 I::te_waker().register(cx.waker());
703
704 if !iic.icsr2().read().tend() {
705 return Poll::Pending;
706 }
707 }
708
709 Poll::Ready(Ok(written))
710 })
711 .await?;
712
713 iic.iccr2().modify(|r| r.set_sp(true));
715
716 while !iic.icsr2().read().stop() {}
717
718 iic.icsr2().modify(|r| {
719 r.set_stop(false);
720 r.set_nackf(false);
721 });
722
723 Ok(ret)
724 }
725
726 async fn read_byte(&self) -> u8 {
727 let iic = I::regs();
728
729 poll_fn(|cx| {
730 if iic.icsr2().read().rdrf() {
731 let byte = iic.icdrr().read();
732 Poll::Ready(byte)
733 } else {
734 I::rx_waker().register(cx.waker());
735 Poll::Pending
736 }
737 })
738 .await
739 }
740
741 async fn read(&self, address: u8, data: &mut [u8]) -> Result<(), I2cError> {
742 let iic = I::regs();
743 let r_addr = (address << 1) | 0x01;
744 let data_len = data.len();
745
746 iic.icier().write(|r| r.set_rie(true));
747
748 while iic.iccr2().read().bbsy() {
749 asm::nop();
750 }
751
752 iic.iccr2().modify(|r| r.set_st(true));
753
754 while !iic.icsr2().read().tdre() {
755 asm::nop();
756 }
757
758 iic.icdrt().write_value(r_addr);
759
760 let mut status = iic.icsr2().read();
761 while !status.rdrf() {
762 if status.nackf() {
763 iic.iccr2().modify(|r| r.set_sp(true));
764 return Err(I2cError::Nack);
765 }
766 asm::nop();
767 status = iic.icsr2().read();
768 }
769
770 let _ = iic.icdrr().read();
772
773 for (i, byte) in data.iter_mut().enumerate() {
774 if i == (data_len - 1) {
775 iic.icmr3().protected_modify(|r| r.set_ackbt(true));
776 }
777
778 *byte = self.read_byte().await;
779 }
780
781 poll_fn(|cx| {
782 if iic.icsr2().read().rdrf() {
783 Poll::Ready(())
784 } else {
785 I::rx_waker().register(cx.waker());
786 Poll::Pending
787 }
788 })
789 .await;
790
791 iic.iccr2().modify(|r| r.set_sp(true));
792
793 let _ = iic.icdrr().read();
795
796 while !iic.icsr2().read().stop() {
797 asm::nop()
798 }
799
800 iic.icmr3().modify(|r| r.set_wait(false));
801 iic.icsr2().modify(|r| r.set_stop(false));
802
803 iic.icier().write(|r| r.set_rie(false));
804
805 Ok(())
806 }
807}
808
809#[allow(private_bounds)]
810impl<'d, I: Instance, M: TransferMode> I2c<'d, I, M> {
811 #[inline]
812 fn new_inner<C: SclPin<I>, D: SdaPin<I>>(
813 iic: Peri<'d, I>,
814 scl: Peri<'d, C>,
815 sda: Peri<'d, D>,
816 speed: I2cSpeed,
817 mode: M,
818 ) -> Self {
819 let clock_config = crate::clock::clock_status();
820
821 #[rustfmt::skip]
822 let clk_config = match clock_config.peripheral_b.to_MHz(){
823 24 => {
824 [
825 ClockConfig { divider: Divider::Div4, low: 25, high: 24 },
826 ClockConfig { divider: Divider::Div1, low: 24, high: 16 },
827 ]
828 },
829 32 => {
830 [
831 ClockConfig { divider: Divider::Div8, low: 15, high: 13 },
832 ClockConfig { divider: Divider::Div2, low: 18, high: 9 },
833 ]
834 }
835 40 => {
836 warn!("Uh this isn't right");
837 [
838 ClockConfig { divider: Divider::Div4, low: 25, high: 24 },
839 ClockConfig { divider: Divider::Div1, low: 24, high: 16 },
840 ]
841 },
842 _ => unimplemented!()
843 };
844
845 let config = match speed {
846 I2cSpeed::Normal => clk_config[0],
848 I2cSpeed::Fast => clk_config[1],
850 #[cfg(any(ra4l1, ra6m5))]
851 I2cSpeed::FastModePlus => todo!(),
852 };
853
854 Self::new_with_clock_config(iic, scl, sda, config, mode)
855 }
856 fn new_with_clock_config<C: SclPin<I>, D: SdaPin<I>>(
868 iic: Peri<'d, I>,
869 scl: Peri<'d, C>,
870 sda: Peri<'d, D>,
871 clocks: ClockConfig,
872 mode: M,
873 ) -> Self {
874 let _ = iic;
875 I::start_module();
876
877 let iic = I::regs();
878
879 iic.iccr1().write(|r| r.set_ice(false));
880 iic.iccr1().modify(|r| r.set_iicrst(true));
881 iic.iccr1().modify(|r| r.set_ice(true));
882
883 iic.icmr1().modify(|r| r.set_cks(clocks.divider.into()));
884
885 iic.icbrl().modify(|r| r.set_brl(clocks.low));
888 iic.icbrh().modify(|r| r.set_brh(clocks.high));
889
890 iic.iccr1().modify(|r| r.set_iicrst(false));
891
892 scl.set_as_scl();
896 sda.set_as_sda();
897
898 Self {
899 _instance: PhantomData,
900 mode,
901 _scl: Flex::new(scl),
902 _sda: Flex::new(sda),
903 }
904 }
905}
906
907impl<RxInt: InterruptType, TeInt: InterruptType, TxInt: InterruptType> Drop
908 for Async<RxInt, TeInt, TxInt>
909{
910 fn drop(&mut self) {
911 RxInt::IRQ.icu_disable();
912 TeInt::IRQ.icu_disable();
913 TxInt::IRQ.icu_disable();
914 }
915}
916
917impl<RxInt: InterruptType, TxDtc: DtcInstance> Drop for Dtc<RxInt, TxDtc> {
918 fn drop(&mut self) {
919 RxInt::IRQ.icu_disable();
920 TxDtc::Int::IRQ.dtc_disable();
921 }
922}
923
924impl<'d, I: Instance, M: TransferMode> Drop for I2c<'d, I, M> {
925 fn drop(&mut self) {
926 I::stop_module();
927 }
928}
929
930macro_rules! scl_pin {
931 ($instance:ident, $pin:ident, $pfunc:ident) => {
932 impl crate::i2c::SclPin<crate::peripherals::$instance> for crate::peripherals::$pin {}
933 impl crate::i2c::SealedSclPin<crate::peripherals::$instance> for crate::peripherals::$pin {
934 const PERIPHERAL_FUNC: crate::gpio::PortFunction = crate::gpio::PortFunction::$pfunc;
935 }
936 };
937}
938pub(crate) use scl_pin;
939
940macro_rules! sda_pin {
941 ($instance:ident, $pin:ident, $pfunc:ident) => {
942 impl crate::i2c::SdaPin<crate::peripherals::$instance> for crate::peripherals::$pin {}
943 impl crate::i2c::SealedSdaPin<crate::peripherals::$instance> for crate::peripherals::$pin {
944 const PERIPHERAL_FUNC: crate::gpio::PortFunction = crate::gpio::PortFunction::$pfunc;
945 }
946 };
947}
948pub(crate) use sda_pin;
949
950#[derive(Debug, PartialEq, Eq, Copy, Clone)]
952#[cfg_attr(feature = "defmt", derive(defmt::Format))]
953pub enum I2cError {
954 Arbitration,
956
957 Nack,
959
960 Overrun,
962}
963
964impl core::fmt::Display for I2cError {
965 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
966 let message = match self {
967 Self::Arbitration => "Arbitration Lost",
968 Self::Nack => "ACK Not Received",
969 Self::Overrun => "Buffer Overrun",
970 };
971
972 write!(f, "{}", message)
973 }
974}
975
976impl core::error::Error for I2cError {}
977
978impl embedded_hal_1::i2c::Error for I2cError {
979 fn kind(&self) -> embedded_hal_1::i2c::ErrorKind {
980 match *self {
981 Self::Arbitration => embedded_hal_1::i2c::ErrorKind::ArbitrationLoss,
982 Self::Nack => embedded_hal_1::i2c::ErrorKind::NoAcknowledge(
983 embedded_hal_1::i2c::NoAcknowledgeSource::Unknown,
984 ),
985 Self::Overrun => embedded_hal_1::i2c::ErrorKind::Overrun,
986 }
987 }
988}
989
990impl<'d, I: Instance, M: TransferMode> embedded_hal_1::i2c::ErrorType for I2c<'d, I, M> {
991 type Error = I2cError;
992}
993
994impl<'d, I: Instance> embedded_hal_1::i2c::I2c<SevenBitAddress> for I2c<'d, I, Blocking> {
995 fn transaction(
996 &mut self,
997 address: u8,
998 operations: &mut [embedded_hal_1::i2c::Operation<'_>],
999 ) -> Result<(), Self::Error> {
1000 for op in operations.iter_mut() {
1001 match op {
1002 embedded_hal_1::i2c::Operation::Read(buffer) => {
1003 self.blocking_read(address, buffer)?;
1004 }
1005 embedded_hal_1::i2c::Operation::Write(data) => {
1006 self.blocking_write(address, data)?;
1007 }
1008 }
1009 }
1010
1011 Ok(())
1012 }
1013}
1014
1015impl<'d, I: Instance, RxInt: InterruptType, TeInt: InterruptType, TxInt: InterruptType>
1016 embedded_hal_async::i2c::I2c for I2c<'d, I, Async<RxInt, TeInt, TxInt>>
1017{
1018 async fn transaction(
1019 &mut self,
1020 address: u8,
1021 operations: &mut [embedded_hal_1::i2c::Operation<'_>],
1022 ) -> Result<(), Self::Error> {
1023 for op in operations.iter_mut() {
1024 match op {
1025 embedded_hal_1::i2c::Operation::Read(buffer) => {
1026 I2c::read(self, address, buffer).await?;
1027 }
1028 embedded_hal_1::i2c::Operation::Write(data) => {
1029 I2c::write(self, address, data).await?;
1030 }
1031 }
1032 }
1033
1034 Ok(())
1035 }
1036}
1037
1038impl<'d, I: Instance, RxInt: InterruptType, TxDtc: DtcInstance> embedded_hal_async::i2c::I2c
1039 for I2c<'d, I, Dtc<RxInt, TxDtc>>
1040{
1041 async fn transaction(
1042 &mut self,
1043 address: u8,
1044 operations: &mut [embedded_hal_1::i2c::Operation<'_>],
1045 ) -> Result<(), Self::Error> {
1046 for op in operations.iter_mut() {
1047 match op {
1048 embedded_hal_1::i2c::Operation::Read(buffer) => {
1049 I2c::dtc_read(self, address, buffer).await?;
1050 }
1051 embedded_hal_1::i2c::Operation::Write(data) => {
1052 I2c::dtc_write(self, address, data).await?;
1053 }
1054 }
1055 }
1056
1057 Ok(())
1058 }
1059}
1060
1061impl<I: Instance, TeInt: InterruptType> InterruptHandler<TeInt> for TeInterruptHandler<I> {
1062 unsafe fn on_interrupt() {
1065 trace!("{}TeInt", I::PERIPHERAL);
1066 TeInt::IRQ.icu_unpend();
1067 let iic = I::regs();
1068 iic.icier().modify(|r| r.set_teie(false));
1069 I::te_waker().wake();
1070 }
1071}
1072
1073impl<I: Instance, TxInt: InterruptType> InterruptHandler<TxInt> for TxInterruptHandler<I> {
1074 unsafe fn on_interrupt() {
1075 trace!("{}TxInt", I::PERIPHERAL);
1076 TxInt::IRQ.icu_unpend();
1077
1078 let iic = I::regs();
1079 let mut tx_reader = unsafe { I::tx_buffer().reader() };
1080 let out_buf = tx_reader.pop_slice();
1081 let out_len = out_buf.len();
1082
1083 if out_buf.is_empty() {
1084 iic.icier().modify(|r| {
1085 r.set_tie(false);
1086 r.set_teie(true);
1087 });
1088
1089 return;
1090 }
1091
1092 iic.icdrt().write_value(out_buf[0]);
1093
1094 tx_reader.pop_done(1);
1095
1096 if out_len == 1 {
1097 iic.icier().modify(|r| {
1098 r.set_tie(false);
1099 r.set_teie(true);
1100 });
1101 return;
1102 }
1103
1104 I::tx_waker().wake();
1105 }
1106}
1107
1108impl<I: Instance, RxInt: InterruptType> InterruptHandler<RxInt> for RxInterruptHandler<I> {
1109 unsafe fn on_interrupt() {
1110 trace!("{}RxI", I::PERIPHERAL);
1111
1112 RxInt::IRQ.icu_unpend();
1113
1114 I::rx_waker().wake();
1115 }
1116}