1use super::*;
2use crate::{rtc_cntl::WakeLock, soc::clocks::ClockTree};
3
4#[cfg_attr(i2c_master_version = "1", path = "v1.rs")]
5#[cfg_attr(i2c_master_version = "2", path = "v2.rs")]
6#[cfg_attr(
7 any(i2c_master_version = "3", i2c_master_version = "4"),
8 path = "v3.rs"
9)]
10mod version;
11
12#[must_use = "futures do nothing unless you `.await` or poll them"]
13pub(super) struct I2cFuture<'a> {
14 events: EnumSet<Event>,
15 driver: Driver<'a>,
16 deadline: Option<Instant>,
17 finished: bool,
19 _wake_lock: WakeLock,
20}
21
22impl<'a> I2cFuture<'a> {
23 pub fn new(events: EnumSet<Event>, driver: Driver<'a>, deadline: Option<Instant>) -> Self {
24 driver.regs().int_ena().modify(|_, w| {
25 for event in events {
26 match event {
27 Event::EndDetect => w.end_detect().set_bit(),
28 Event::TxComplete => w.trans_complete().set_bit(),
29 #[cfg(i2c_master_has_tx_fifo_watermark)]
30 Event::TxFifoWatermark => w.txfifo_wm().set_bit(),
31 };
32 }
33
34 w.arbitration_lost().set_bit();
35 w.time_out().set_bit();
36 w.nack().set_bit();
37 #[cfg(i2c_master_has_fsm_timeouts)]
38 {
39 w.scl_main_st_to().set_bit();
40 w.scl_st_to().set_bit();
41 }
42
43 w
44 });
45
46 Self::new_blocking(events, driver, deadline)
47 }
48
49 pub fn new_blocking(
50 events: EnumSet<Event>,
51 driver: Driver<'a>,
52 deadline: Option<Instant>,
53 ) -> Self {
54 Self {
55 events,
56 driver,
57 deadline,
58 finished: false,
59 _wake_lock: WakeLock::new(),
60 }
61 }
62
63 fn is_done(&self) -> bool {
64 !self.driver.info.interrupts().is_disjoint(self.events)
65 }
66
67 fn poll_completion(&mut self) -> Poll<Result<(), Error>> {
68 let now = if self.deadline.is_some() {
72 Instant::now()
73 } else {
74 Instant::EPOCH
75 };
76 let error = self.driver.check_errors();
77
78 let result = if self.is_done() {
79 let result = if error == Err(Error::Timeout) {
81 Ok(())
84 } else {
85 error
86 };
87 Poll::Ready(result)
88 } else if error.is_err() {
89 Poll::Ready(error)
90 } else if let Some(deadline) = self.deadline
91 && now > deadline
92 {
93 Poll::Ready(Err(Error::Timeout))
95 } else {
96 Poll::Pending
97 };
98
99 if result.is_ready() {
100 self.finished = true;
101 }
102
103 result
104 }
105}
106
107impl core::future::Future for I2cFuture<'_> {
108 type Output = Result<(), Error>;
109
110 fn poll(mut self: Pin<&mut Self>, ctx: &mut Context<'_>) -> Poll<Self::Output> {
111 self.driver.state.waker.register(ctx.waker());
112
113 let result = self.poll_completion();
114
115 if result.is_pending() && self.deadline.is_some() {
116 ctx.waker().wake_by_ref();
117 }
118
119 result
120 }
121}
122
123impl Drop for I2cFuture<'_> {
124 fn drop(&mut self) {
125 if !self.finished {
126 let result = self.poll_completion();
127 if result.is_pending() || result == Poll::Ready(Err(Error::Timeout)) {
128 self.driver.reset_fsm(true);
129 }
130 }
131 }
132}
133
134#[ram]
135pub(super) fn async_handler(info: &Info, state: &State) {
136 info.regs().int_ena().write(|w| unsafe { w.bits(0) });
139
140 state.waker.wake();
141}
142
143fn set_filter(
146 register_block: &RegisterBlock,
147 sda_threshold: Option<u8>,
148 scl_threshold: Option<u8>,
149) {
150 cfg_select! {
151 i2c_master_separate_filter_config_registers => {
152 register_block.sda_filter_cfg().modify(|_, w| {
153 if let Some(threshold) = sda_threshold {
154 unsafe { w.sda_filter_thres().bits(threshold) };
155 }
156 w.sda_filter_en().bit(sda_threshold.is_some())
157 });
158 register_block.scl_filter_cfg().modify(|_, w| {
159 if let Some(threshold) = scl_threshold {
160 unsafe { w.scl_filter_thres().bits(threshold) };
161 }
162 w.scl_filter_en().bit(scl_threshold.is_some())
163 });
164 }
165 _ => {
166 register_block.filter_cfg().modify(|_, w| {
167 if let Some(threshold) = sda_threshold {
168 unsafe { w.sda_filter_thres().bits(threshold) };
169 }
170 if let Some(threshold) = scl_threshold {
171 unsafe { w.scl_filter_thres().bits(threshold) };
172 }
173 w.sda_filter_en().bit(sda_threshold.is_some());
174 w.scl_filter_en().bit(scl_threshold.is_some())
175 });
176 }
177 }
178}
179
180#[expect(clippy::too_many_arguments)]
181#[allow(unused)]
182fn configure_clock(
186 info: &Info,
187 scl_low_period: u32,
188 scl_high_period: u32,
189 scl_wait_high_period: u32,
190 sda_hold_time: u32,
191 sda_sample_time: u32,
192 scl_rstart_setup_time: u32,
193 scl_stop_setup_time: u32,
194 scl_start_hold_time: u32,
195 scl_stop_hold_time: u32,
196 timeout: Option<u32>,
197) -> Result<(), ConfigError> {
198 unsafe {
199 info.regs()
201 .scl_low_period()
202 .write(|w| w.scl_low_period().bits(scl_low_period as u16));
203
204 #[cfg(not(i2c_master_version = "1"))]
205 let scl_wait_high_period = scl_wait_high_period
206 .try_into()
207 .map_err(|_| ConfigError::FrequencyOutOfRange)?;
208
209 info.regs().scl_high_period().write(|w| {
210 #[cfg(not(i2c_master_version = "1"))] w.scl_wait_high_period().bits(scl_wait_high_period);
212 w.scl_high_period().bits(scl_high_period as u16)
213 });
214
215 info.regs()
217 .sda_hold()
218 .write(|w| w.time().bits(sda_hold_time as u16));
219 info.regs()
220 .sda_sample()
221 .write(|w| w.time().bits(sda_sample_time as u16));
222
223 info.regs()
225 .scl_rstart_setup()
226 .write(|w| w.time().bits(scl_rstart_setup_time as u16));
227 info.regs()
228 .scl_stop_setup()
229 .write(|w| w.time().bits(scl_stop_setup_time as u16));
230
231 info.regs()
233 .scl_start_hold()
234 .write(|w| w.time().bits(scl_start_hold_time as u16));
235 info.regs()
236 .scl_stop_hold()
237 .write(|w| w.time().bits(scl_stop_hold_time as u16));
238
239 cfg_select! {
240 i2c_master_has_bus_timeout_enable => {
241 info.regs().to().write(|w| {
242 w.time_out_en().bit(timeout.is_some());
243 w.time_out_value().bits(timeout.unwrap_or(1) as _)
244 });
245 }
246 _ => {
247 info.regs()
248 .to()
249 .write(|w| w.time_out().bits(timeout.unwrap_or(1)));
250 }
251 }
252 }
253 Ok(())
254}
255
256#[doc(hidden)]
258#[derive(Debug)]
259#[non_exhaustive]
260#[allow(private_interfaces, reason = "Unstable details")]
261pub struct Info {
262 #[cfg(soc_has_i2c1)]
264 pub id: u8,
265
266 pub register_block: *const RegisterBlock,
270
271 pub peripheral: crate::system::Peripheral,
273
274 pub async_handler: InterruptHandler,
276
277 pub scl_output: OutputSignal,
279
280 pub scl_input: InputSignal,
282
283 pub sda_output: OutputSignal,
285
286 pub sda_input: InputSignal,
288
289 pub clock_instance: crate::soc::clocks::I2cInstance,
291}
292
293impl Info {
294 pub fn regs(&self) -> &RegisterBlock {
296 unsafe { &*self.register_block }
297 }
298
299 pub(super) fn enable_listen(&self, interrupts: EnumSet<Event>, enable: bool) {
301 let reg_block = self.regs();
302
303 reg_block.int_ena().modify(|_, w| {
304 for interrupt in interrupts {
305 match interrupt {
306 Event::EndDetect => w.end_detect().bit(enable),
307 Event::TxComplete => w.trans_complete().bit(enable),
308 #[cfg(i2c_master_has_tx_fifo_watermark)]
309 Event::TxFifoWatermark => w.txfifo_wm().bit(enable),
310 };
311 }
312 w
313 });
314 }
315
316 pub(super) fn interrupts(&self) -> EnumSet<Event> {
317 let mut res = EnumSet::new();
318 let reg_block = self.regs();
319
320 let ints = reg_block.int_raw().read();
321
322 if ints.end_detect().bit_is_set() {
323 res.insert(Event::EndDetect);
324 }
325 if ints.trans_complete().bit_is_set() {
326 res.insert(Event::TxComplete);
327 }
328 #[cfg(i2c_master_has_tx_fifo_watermark)]
329 if ints.txfifo_wm().bit_is_set() {
330 res.insert(Event::TxFifoWatermark);
331 }
332
333 res
334 }
335
336 pub(super) fn clear_interrupts(&self, interrupts: EnumSet<Event>) {
337 let reg_block = self.regs();
338
339 reg_block.int_clr().write(|w| {
340 for interrupt in interrupts {
341 match interrupt {
342 Event::EndDetect => w.end_detect().clear_bit_by_one(),
343 Event::TxComplete => w.trans_complete().clear_bit_by_one(),
344 #[cfg(i2c_master_has_tx_fifo_watermark)]
345 Event::TxFifoWatermark => w.txfifo_wm().clear_bit_by_one(),
346 };
347 }
348 w
349 });
350 }
351}
352
353impl PartialEq for Info {
354 fn eq(&self, other: &Self) -> bool {
355 core::ptr::eq(self.register_block, other.register_block)
356 }
357}
358
359unsafe impl Sync for Info {}
360
361pub(super) struct I2cClockGuard {
362 clock: crate::clock::ll::I2cInstance,
363}
364
365impl I2cClockGuard {
366 pub(super) fn new(i2c: AnyI2c<'_>) -> Self {
367 let clock = i2c.info().clock_instance;
368 ClockTree::with(|clocks| clock.request_function_clock(clocks));
369 Self { clock }
370 }
371}
372
373impl Drop for I2cClockGuard {
374 fn drop(&mut self) {
375 ClockTree::with(|clocks| self.clock.release_function_clock(clocks));
376 }
377}
378
379#[derive(Clone, Copy)]
380enum Deadline {
381 None,
382 Fixed(Instant),
383 PerByte(Duration),
384}
385
386impl Deadline {
387 fn start(self, data_len: usize) -> Option<Instant> {
388 match self {
389 Deadline::None => None,
390 Deadline::Fixed(deadline) => Some(deadline),
391 Deadline::PerByte(duration) => Some(Instant::now() + duration * data_len as u32),
392 }
393 }
394}
395
396#[allow(dead_code)] #[derive(Clone, Copy)]
398pub(super) struct Driver<'a> {
399 pub(super) info: &'a Info,
400 pub(super) state: &'a State,
401 pub(super) config: &'a DriverConfig,
402}
403
404impl Driver<'_> {
405 fn regs(&self) -> &RegisterBlock {
406 self.info.regs()
407 }
408
409 pub(super) fn connect_pin(
410 pin: crate::gpio::interconnect::OutputSignal<'_>,
411 input: InputSignal,
412 output: OutputSignal,
413 guard: &mut PinGuard,
414 ) {
415 pin.set_output_high(true);
417
418 pin.apply_output_config(
419 &OutputConfig::default()
420 .with_drive_mode(DriveMode::OpenDrain)
421 .with_pull(Pull::Up),
422 );
423 pin.set_output_enable(true);
424 pin.set_input_enable(true);
425
426 input.connect_to(&pin);
427
428 *guard = interconnect::OutputSignal::connect_with_guard(pin, output);
429 }
430
431 fn init_master(&self, config: &Config) {
432 self.regs().ctr().write(|w| {
433 w.ms_mode().set_bit();
435 w.sda_force_out().open_drain();
436 w.scl_force_out().open_drain();
437 w.tx_lsb_first().clear_bit();
439 w.rx_lsb_first().clear_bit();
440
441 w.sample_scl_level()
442 .bit(config.scl_sample_level == Level::Low);
443
444 #[cfg(i2c_master_has_arbitration_en)]
445 w.arbitration_en().bit(config.bus_arbitration);
446
447 #[cfg(i2c_master_version = "2")]
448 w.ref_always_on().set_bit();
449
450 w.clk_en().set_bit()
452 });
453 }
454
455 pub(super) fn setup(&self, config: &Config) -> Result<(), ConfigError> {
458 self.init_master(config);
459
460 set_filter(self.regs(), Some(7), Some(7));
463
464 self.set_frequency(config)?;
466
467 #[cfg(i2c_master_has_fsm_timeouts)]
469 {
470 self.regs()
471 .scl_st_time_out()
472 .write(|w| unsafe { w.scl_st_to().bits(config.scl_st_timeout.value()) });
473 self.regs()
474 .scl_main_st_time_out()
475 .write(|w| unsafe { w.scl_main_st_to().bits(config.scl_main_st_timeout.value()) });
476 }
477
478 self.update_registers();
479
480 Ok(())
481 }
482
483 fn do_fsm_reset(&self) {
484 cfg_select! {
485 i2c_master_has_reliable_fsm_reset => {
486 self.regs().ctr().modify(|_, w| w.fsm_rst().set_bit());
488 }
489 _ => {
490 crate::system::PeripheralClockControl::reset(self.info.peripheral);
494
495 self.setup(&self.config.config).ok();
498 }
499 }
500 }
501
502 pub(super) fn reset_fsm(&self, clear_bus: bool) {
510 if clear_bus {
511 self.clear_bus_blocking(true);
512 } else {
513 self.do_fsm_reset();
514 }
515 }
516
517 fn bus_busy(&self) -> bool {
518 self.regs().sr().read().bus_busy().bit_is_set()
519 }
520
521 fn ensure_idle_blocking(&self) {
522 if self.bus_busy() {
523 self.clear_bus_blocking(false);
525 }
526 }
527
528 async fn ensure_idle(&self) {
529 if self.bus_busy() {
530 self.clear_bus().await;
532 }
533 }
534
535 fn reset_before_transmission(&self) {
536 self.clear_all_interrupts();
538
539 self.reset_fifo();
541
542 self.reset_command_list();
544 }
545
546 fn clear_bus_blocking(&self, reset_fsm: bool) {
552 let mut future = ClearBusFuture::new(*self, reset_fsm);
553 let start = Instant::now();
554 while future.poll_completion().is_pending() {
555 if start.elapsed() > CLEAR_BUS_TIMEOUT_MS {
556 break;
557 }
558 }
559 }
560
561 async fn clear_bus(&self) {
562 let clear_bus = ClearBusFuture::new(*self, true);
563 let start = Instant::now();
564
565 embassy_futures::select::select(clear_bus, async {
566 while start.elapsed() < CLEAR_BUS_TIMEOUT_MS {
567 embassy_futures::yield_now().await;
568 }
569 })
570 .await;
571 }
572
573 pub(super) fn force_scl_low(&self, low: bool) {
574 cfg_select! {
575 i2c_master_has_pd_en => self.set_scl_pd(low),
576 _ => self.force_pin_low(low, self.config.scl_pin.pin_number(), &self.info.scl_output),
577 }
578 }
579
580 pub(super) fn force_sda_low(&self, low: bool) {
581 cfg_select! {
582 i2c_master_has_pd_en => self.set_sda_pd(low),
583 _ => self.force_pin_low(low, self.config.sda_pin.pin_number(), &self.info.sda_output),
584 }
585 }
586
587 #[cfg(i2c_master_has_pd_en)]
589 fn restore_force_out(&self) {
590 self.regs().ctr().modify(|_, w| {
591 w.scl_force_out().open_drain();
592 w.sda_force_out().open_drain()
593 });
594 self.update_registers();
595 }
596
597 #[cfg(not(i2c_master_has_pd_en))]
598 fn force_pin_low(
599 &self,
600 low: bool,
601 pin_number: Option<u8>,
602 output_signal: &crate::gpio::OutputSignal,
603 ) {
604 use crate::gpio::AnyPin;
605 let Some(n) = pin_number else { return };
606 let pin = unsafe { AnyPin::steal(n) };
607 if low {
608 pin.set_output_high(false);
609 output_signal.disconnect_from(&pin);
610 } else {
611 output_signal.connect_to(&pin);
612 }
613 }
614
615 #[cfg(i2c_master_has_pd_en)]
619 fn set_scl_pd(&self, low: bool) {
620 if low {
621 self.regs()
622 .ctr()
623 .modify(|_, w| w.scl_force_out().direct_output());
624 }
625 self.regs()
626 .scl_sp_conf()
627 .modify(|_, w| w.scl_pd_en().bit(low));
628 if !low {
629 let sp = self.regs().scl_sp_conf().read();
630 if sp.scl_pd_en().bit_is_clear() && sp.sda_pd_en().bit_is_clear() {
631 self.restore_force_out();
632 return;
633 }
634 }
635 self.update_registers();
636 }
637
638 #[cfg(i2c_master_has_pd_en)]
642 fn set_sda_pd(&self, low: bool) {
643 if low {
644 self.regs()
645 .ctr()
646 .modify(|_, w| w.sda_force_out().direct_output());
647 }
648 self.regs()
649 .scl_sp_conf()
650 .modify(|_, w| w.sda_pd_en().bit(low));
651 if !low {
652 let sp = self.regs().scl_sp_conf().read();
653 if sp.scl_pd_en().bit_is_clear() && sp.sda_pd_en().bit_is_clear() {
654 self.restore_force_out();
655 return;
656 }
657 }
658 self.update_registers();
659 }
660
661 fn reset_command_list(&self) {
663 for cmd in self.regs().comd_iter() {
664 cmd.reset();
665 }
666 }
667
668 fn setup_write<'a, I>(
676 &self,
677 addr: I2cAddress,
678 bytes: &[u8],
679 start: bool,
680 stop: bool,
681 cmd_iterator: &mut I,
682 ) -> Result<(), Error>
683 where
684 I: Iterator<Item = &'a COMD>,
685 {
686 let max_len = if start {
689 I2C_CHUNK_SIZE
690 } else {
691 I2C_CHUNK_SIZE + 1
692 };
693 if bytes.len() > max_len {
694 return Err(Error::FifoExceeded);
695 }
696
697 if start {
698 add_cmd(cmd_iterator, Command::Start)?;
699 }
700
701 let write_len = if start { bytes.len() + 1 } else { bytes.len() };
702 if write_len > 0 {
704 if cfg!(i2c_master_version = "1") && !(start || stop) {
712 add_cmd(
715 cmd_iterator,
716 Command::Write {
717 ack_exp: Ack::Ack,
718 ack_check_en: true,
719 length: (write_len as u8) - 1,
720 },
721 )?;
722 add_cmd(
723 cmd_iterator,
724 Command::Write {
725 ack_exp: Ack::Ack,
726 ack_check_en: true,
727 length: 1,
728 },
729 )?;
730 } else {
731 add_cmd(
732 cmd_iterator,
733 Command::Write {
734 ack_exp: Ack::Ack,
735 ack_check_en: true,
736 length: write_len as u8,
737 },
738 )?;
739 }
740 }
741
742 if start {
743 match addr {
745 I2cAddress::SevenBit(addr) => {
746 self.write_fifo((addr << 1) | OperationType::Write as u8);
747 }
748 }
749 }
750 for b in bytes {
751 self.write_fifo(*b);
752 }
753
754 Ok(())
755 }
756
757 fn setup_read<'a, I>(
767 &self,
768 addr: I2cAddress,
769 buffer: &mut [u8],
770 start: bool,
771 stop: bool,
772 will_continue: bool,
773 cmd_iterator: &mut I,
774 ) -> Result<(), Error>
775 where
776 I: Iterator<Item = &'a COMD>,
777 {
778 if buffer.is_empty() {
779 return Err(Error::ZeroLengthInvalid);
780 }
781 let (max_len, initial_len) = if will_continue {
782 (I2C_CHUNK_SIZE + 1, buffer.len())
783 } else {
784 (I2C_CHUNK_SIZE, buffer.len() - 1)
785 };
786 if buffer.len() > max_len {
787 return Err(Error::FifoExceeded);
788 }
789
790 if start {
791 add_cmd(cmd_iterator, Command::Start)?;
792 add_cmd(
794 cmd_iterator,
795 Command::Write {
796 ack_exp: Ack::Ack,
797 ack_check_en: true,
798 length: 1,
799 },
800 )?;
801 }
802
803 if initial_len > 0 {
804 let extra_commands = if cfg!(i2c_master_version = "1") {
805 match (start, will_continue) {
806 (true, _) => 0,
808 (false, true) => 2,
810 (false, false) => 1 - stop as u8,
812 }
813 } else {
814 0
815 };
816
817 add_cmd(
818 cmd_iterator,
819 Command::Read {
820 ack_value: Ack::Ack,
821 length: initial_len as u8 - extra_commands,
822 },
823 )?;
824 for _ in 0..extra_commands {
825 add_cmd(
826 cmd_iterator,
827 Command::Read {
828 ack_value: Ack::Ack,
829 length: 1,
830 },
831 )?;
832 }
833 }
834
835 if !will_continue {
836 add_cmd(
839 cmd_iterator,
840 Command::Read {
841 ack_value: Ack::Nack,
842 length: 1,
843 },
844 )?;
845 }
846
847 self.update_registers();
848
849 if start {
850 match addr {
852 I2cAddress::SevenBit(addr) => {
853 self.write_fifo((addr << 1) | OperationType::Read as u8);
854 }
855 }
856 }
857 Ok(())
858 }
859
860 fn read_all_from_fifo(&self, buffer: &mut [u8]) -> Result<(), Error> {
862 if self.regs().sr().read().rxfifo_cnt().bits() < buffer.len() as u8 {
863 return Err(Error::ExecutionIncomplete);
864 }
865
866 for byte in buffer.iter_mut() {
868 *byte = self.read_fifo();
869 }
870
871 debug_assert!(self.regs().sr().read().rxfifo_cnt().bits() == 0);
874
875 Ok(())
876 }
877
878 fn clear_all_interrupts(&self) {
880 self.regs()
881 .int_clr()
882 .write(|w| unsafe { w.bits(property!("i2c_master.ll_intr_mask")) });
883 }
884
885 async fn wait_for_completion(&self, deadline: Option<Instant>) -> Result<(), Error> {
886 I2cFuture::new(Event::TxComplete | Event::EndDetect, *self, deadline).await?;
887 self.check_all_commands_done(deadline).await
888 }
889
890 fn wait_for_completion_blocking(&self, deadline: Option<Instant>) -> Result<(), Error> {
892 let mut future =
893 I2cFuture::new_blocking(Event::TxComplete | Event::EndDetect, *self, deadline);
894 loop {
895 if let Poll::Ready(result) = future.poll_completion() {
896 result?;
897 return self.check_all_commands_done_blocking(deadline);
898 }
899 }
900 }
901
902 fn all_commands_done(&self, deadline: Option<Instant>) -> Result<bool, Error> {
903 let now = if deadline.is_some() {
907 Instant::now()
908 } else {
909 Instant::EPOCH
910 };
911
912 self.check_errors()?;
913
914 for cmd_reg in self.regs().comd_iter() {
915 let cmd = cmd_reg.read();
916
917 if cmd.bits() != 0x0 && !cmd.opcode().is_end() && !cmd.command_done().bit_is_set() {
919 if let Some(deadline) = deadline
921 && now > deadline
922 {
923 return Err(Error::ExecutionIncomplete);
924 }
925
926 return Ok(false);
927 }
928
929 if cmd.opcode().is_end() {
931 break;
932 }
933 if cmd.opcode().is_stop() {
934 #[cfg(i2c_master_version = "1")]
935 if self.regs().sr().read().scl_state_last() == 6 {
938 self.check_errors()?;
939 } else {
940 continue;
941 }
942 break;
943 }
944 }
945 Ok(true)
946 }
947
948 fn check_all_commands_done_blocking(&self, deadline: Option<Instant>) -> Result<(), Error> {
950 while !self.all_commands_done(deadline)? {}
952 self.check_errors()?;
953
954 Ok(())
955 }
956
957 async fn check_all_commands_done(&self, deadline: Option<Instant>) -> Result<(), Error> {
959 while !self.all_commands_done(deadline)? {
961 embassy_futures::yield_now().await;
962 }
963 self.check_errors()?;
964
965 Ok(())
966 }
967
968 fn check_errors(&self) -> Result<(), Error> {
976 let r = self.regs().int_raw().read();
977
978 if r.nack().bit_is_set() {
980 return Err(Error::AcknowledgeCheckFailed(estimate_ack_failed_reason(
981 self.regs(),
982 )));
983 }
984 if r.arbitration_lost().bit_is_set() {
985 return Err(Error::ArbitrationLost);
986 }
987
988 #[cfg(not(i2c_master_version = "1"))]
989 if r.trans_complete().bit_is_set() && self.regs().sr().read().resp_rec().bit_is_clear() {
990 return Err(Error::AcknowledgeCheckFailed(
991 AcknowledgeCheckFailedReason::Data,
992 ));
993 }
994
995 #[cfg(i2c_master_has_fsm_timeouts)]
996 {
997 if r.scl_st_to().bit_is_set() {
998 return Err(Error::Timeout);
999 }
1000 if r.scl_main_st_to().bit_is_set() {
1001 return Err(Error::Timeout);
1002 }
1003 }
1004 if r.time_out().bit_is_set() {
1005 return Err(Error::Timeout);
1006 }
1007
1008 Ok(())
1009 }
1010
1011 fn update_registers(&self) {
1021 #[cfg(i2c_master_has_conf_update)]
1024 self.regs().ctr().modify(|_, w| w.conf_upgate().set_bit());
1025 }
1026
1027 fn set_frequency(&self, config: &Config) -> Result<(), ConfigError> {
1028 version::set_frequency(self, config)
1029 }
1030
1031 fn reset_fifo(&self) {
1032 version::reset_fifo(self);
1033 }
1034
1035 fn read_fifo(&self) -> u8 {
1036 version::read_fifo(self.regs())
1037 }
1038
1039 fn write_fifo(&self, data: u8) {
1040 version::write_fifo(self.regs(), data);
1041 }
1042
1043 fn start_transmission(&self) {
1045 self.regs().ctr().modify(|_, w| w.trans_start().set_bit());
1047 }
1048
1049 fn start_write_operation(
1050 &self,
1051 address: I2cAddress,
1052 buffer: &[u8],
1053 start: bool,
1054 stop: bool,
1055 deadline: Deadline,
1056 ) -> Result<Option<Instant>, Error> {
1057 let cmd_iterator = &mut self.regs().comd_iter();
1058
1059 self.setup_write(address, buffer, start, stop, cmd_iterator)?;
1060
1061 if stop {
1062 add_cmd(cmd_iterator, Command::Stop)?;
1063 }
1064 if !(start && stop) {
1065 add_cmd(cmd_iterator, Command::End)?;
1069 }
1070
1071 self.start_transmission();
1072
1073 Ok(deadline.start(buffer.len() + address.bytes()))
1074 }
1075
1076 fn start_read_operation(
1086 &self,
1087 address: I2cAddress,
1088 buffer: &mut [u8],
1089 start: bool,
1090 will_continue: bool,
1091 stop: bool,
1092 deadline: Deadline,
1093 ) -> Result<Option<Instant>, Error> {
1094 debug_assert!(buffer.len() <= I2C_FIFO_SIZE);
1098
1099 let cmd_iterator = &mut self.regs().comd_iter();
1100
1101 self.setup_read(address, buffer, start, stop, will_continue, cmd_iterator)?;
1102
1103 if stop {
1104 add_cmd(cmd_iterator, Command::Stop)?;
1105 }
1106 if !(start && stop) {
1107 add_cmd(cmd_iterator, Command::End)?;
1109 }
1110
1111 self.start_transmission();
1112
1113 Ok(deadline.start(buffer.len() + address.bytes()))
1114 }
1115
1116 fn write_operation_blocking(
1124 &self,
1125 address: I2cAddress,
1126 bytes: &[u8],
1127 start: bool,
1128 stop: bool,
1129 deadline: Deadline,
1130 ) -> Result<(), Error> {
1131 address.validate()?;
1132
1133 self.reset_before_transmission();
1134
1135 if bytes.is_empty() && !start && !stop {
1138 return Ok(());
1139 }
1140
1141 let deadline = self.start_write_operation(address, bytes, start, stop, deadline)?;
1142 self.wait_for_completion_blocking(deadline)?;
1143
1144 Ok(())
1145 }
1146
1147 fn read_operation_blocking(
1157 &self,
1158 address: I2cAddress,
1159 buffer: &mut [u8],
1160 start: bool,
1161 stop: bool,
1162 will_continue: bool,
1163 deadline: Deadline,
1164 ) -> Result<(), Error> {
1165 address.validate()?;
1166 self.reset_before_transmission();
1167
1168 if buffer.is_empty() {
1171 return Ok(());
1172 }
1173
1174 let deadline =
1175 self.start_read_operation(address, buffer, start, will_continue, stop, deadline)?;
1176 self.wait_for_completion_blocking(deadline)?;
1177 self.read_all_from_fifo(buffer)?;
1178
1179 Ok(())
1180 }
1181
1182 async fn write_operation(
1190 &self,
1191 address: I2cAddress,
1192 bytes: &[u8],
1193 start: bool,
1194 stop: bool,
1195 deadline: Deadline,
1196 ) -> Result<(), Error> {
1197 address.validate()?;
1198 self.reset_before_transmission();
1199
1200 if bytes.is_empty() && !start && !stop {
1203 return Ok(());
1204 }
1205
1206 let deadline = self.start_write_operation(address, bytes, start, stop, deadline)?;
1207 self.wait_for_completion(deadline).await?;
1208
1209 Ok(())
1210 }
1211
1212 async fn read_operation(
1222 &self,
1223 address: I2cAddress,
1224 buffer: &mut [u8],
1225 start: bool,
1226 stop: bool,
1227 will_continue: bool,
1228 deadline: Deadline,
1229 ) -> Result<(), Error> {
1230 address.validate()?;
1231 self.reset_before_transmission();
1232
1233 if buffer.is_empty() {
1236 return Ok(());
1237 }
1238
1239 let deadline =
1240 self.start_read_operation(address, buffer, start, will_continue, stop, deadline)?;
1241 self.wait_for_completion(deadline).await?;
1242 self.read_all_from_fifo(buffer)?;
1243
1244 Ok(())
1245 }
1246
1247 fn read_blocking(
1248 &self,
1249 address: I2cAddress,
1250 buffer: &mut [u8],
1251 start: bool,
1252 stop: bool,
1253 will_continue: bool,
1254 deadline: Deadline,
1255 ) -> Result<(), Error> {
1256 let chunk_count = VariableChunkIterMut::new(buffer).count();
1257 for (idx, chunk) in VariableChunkIterMut::new(buffer).enumerate() {
1258 self.read_operation_blocking(
1259 address,
1260 chunk,
1261 start && idx == 0,
1262 stop && idx == chunk_count - 1,
1263 will_continue || idx < chunk_count - 1,
1264 deadline,
1265 )?;
1266 }
1267
1268 Ok(())
1269 }
1270
1271 fn write_blocking(
1272 &self,
1273 address: I2cAddress,
1274 buffer: &[u8],
1275 start: bool,
1276 stop: bool,
1277 deadline: Deadline,
1278 ) -> Result<(), Error> {
1279 if buffer.is_empty() {
1280 return self.write_operation_blocking(address, &[], start, stop, deadline);
1281 }
1282
1283 let chunk_count = VariableChunkIter::new(buffer).count();
1284 for (idx, chunk) in VariableChunkIter::new(buffer).enumerate() {
1285 self.write_operation_blocking(
1286 address,
1287 chunk,
1288 start && idx == 0,
1289 stop && idx == chunk_count - 1,
1290 deadline,
1291 )?;
1292 }
1293
1294 Ok(())
1295 }
1296
1297 async fn read(
1298 &self,
1299 address: I2cAddress,
1300 buffer: &mut [u8],
1301 start: bool,
1302 stop: bool,
1303 will_continue: bool,
1304 deadline: Deadline,
1305 ) -> Result<(), Error> {
1306 let chunk_count = VariableChunkIterMut::new(buffer).count();
1307 for (idx, chunk) in VariableChunkIterMut::new(buffer).enumerate() {
1308 self.read_operation(
1309 address,
1310 chunk,
1311 start && idx == 0,
1312 stop && idx == chunk_count - 1,
1313 will_continue || idx < chunk_count - 1,
1314 deadline,
1315 )
1316 .await?;
1317 }
1318
1319 Ok(())
1320 }
1321
1322 async fn write(
1323 &self,
1324 address: I2cAddress,
1325 buffer: &[u8],
1326 start: bool,
1327 stop: bool,
1328 deadline: Deadline,
1329 ) -> Result<(), Error> {
1330 if buffer.is_empty() {
1331 return self
1332 .write_operation(address, &[], start, stop, deadline)
1333 .await;
1334 }
1335
1336 let chunk_count = VariableChunkIter::new(buffer).count();
1337 for (idx, chunk) in VariableChunkIter::new(buffer).enumerate() {
1338 self.write_operation(
1339 address,
1340 chunk,
1341 start && idx == 0,
1342 stop && idx == chunk_count - 1,
1343 deadline,
1344 )
1345 .await?;
1346 }
1347
1348 Ok(())
1349 }
1350
1351 pub(super) fn transaction_impl<'a>(
1352 &self,
1353 address: I2cAddress,
1354 operations: impl Iterator<Item = Operation<'a>>,
1355 ) -> Result<(), Error> {
1356 address.validate()?;
1357 self.ensure_idle_blocking();
1358
1359 let mut deadline = Deadline::None;
1360
1361 if let SoftwareTimeout::Transaction(timeout) = self.config.config.software_timeout {
1362 deadline = Deadline::Fixed(Instant::now() + timeout);
1363 }
1364
1365 let mut last_op: Option<OpKind> = None;
1366 let mut op_iter = operations
1368 .filter(|op| op.is_write() || !op.is_empty())
1369 .peekable();
1370
1371 while let Some(op) = op_iter.next() {
1372 let next_op = op_iter.peek().map(|v| v.kind());
1373 let kind = op.kind();
1374 match op {
1375 Operation::Write(buffer) => {
1376 if let SoftwareTimeout::PerByte(timeout) = self.config.config.software_timeout {
1380 deadline = Deadline::PerByte(timeout);
1381 }
1382 self.write_blocking(
1383 address,
1384 buffer,
1385 !matches!(last_op, Some(OpKind::Write)),
1386 next_op.is_none(),
1387 deadline,
1388 )?;
1389 }
1390 Operation::Read(buffer) => {
1391 if let SoftwareTimeout::PerByte(timeout) = self.config.config.software_timeout {
1392 deadline = Deadline::PerByte(timeout);
1393 }
1394 self.read_blocking(
1399 address,
1400 buffer,
1401 !matches!(last_op, Some(OpKind::Read)),
1402 next_op.is_none(),
1403 matches!(next_op, Some(OpKind::Read)),
1404 deadline,
1405 )?;
1406 }
1407 }
1408
1409 last_op = Some(kind);
1410 }
1411
1412 Ok(())
1413 }
1414
1415 pub(super) async fn transaction_impl_async<'a>(
1416 &self,
1417 address: I2cAddress,
1418 operations: impl Iterator<Item = Operation<'a>>,
1419 ) -> Result<(), Error> {
1420 address.validate()?;
1421 self.ensure_idle().await;
1422
1423 let mut deadline = Deadline::None;
1424
1425 if let SoftwareTimeout::Transaction(timeout) = self.config.config.software_timeout {
1426 deadline = Deadline::Fixed(Instant::now() + timeout);
1427 }
1428
1429 let mut last_op: Option<OpKind> = None;
1430 let mut op_iter = operations
1432 .filter(|op| op.is_write() || !op.is_empty())
1433 .peekable();
1434
1435 while let Some(op) = op_iter.next() {
1436 let next_op = op_iter.peek().map(|v| v.kind());
1437 let kind = op.kind();
1438 match op {
1439 Operation::Write(buffer) => {
1440 if let SoftwareTimeout::PerByte(timeout) = self.config.config.software_timeout {
1441 deadline = Deadline::PerByte(timeout);
1442 }
1443 self.write(
1447 address,
1448 buffer,
1449 !matches!(last_op, Some(OpKind::Write)),
1450 next_op.is_none(),
1451 deadline,
1452 )
1453 .await?;
1454 }
1455 Operation::Read(buffer) => {
1456 if let SoftwareTimeout::PerByte(timeout) = self.config.config.software_timeout {
1457 deadline = Deadline::PerByte(timeout);
1458 }
1459 self.read(
1464 address,
1465 buffer,
1466 !matches!(last_op, Some(OpKind::Read)),
1467 next_op.is_none(),
1468 matches!(next_op, Some(OpKind::Read)),
1469 deadline,
1470 )
1471 .await?;
1472 }
1473 }
1474
1475 last_op = Some(kind);
1476 }
1477
1478 Ok(())
1479 }
1480}
1481
1482struct VariableChunkIterMut<'a, T> {
1485 buffer: &'a mut [T],
1486}
1487
1488impl<'a, T> VariableChunkIterMut<'a, T> {
1489 fn new(buffer: &'a mut [T]) -> Self {
1490 Self { buffer }
1491 }
1492}
1493
1494impl<'a, T> Iterator for VariableChunkIterMut<'a, T> {
1495 type Item = &'a mut [T];
1496
1497 fn next(&mut self) -> Option<Self::Item> {
1498 if self.buffer.is_empty() {
1499 return None;
1500 }
1501
1502 let s = calculate_chunk_size(self.buffer.len());
1503 let (chunk, remaining) = core::mem::take(&mut self.buffer).split_at_mut(s);
1504 self.buffer = remaining;
1505 Some(chunk)
1506 }
1507}
1508
1509struct VariableChunkIter<'a, T> {
1512 buffer: &'a [T],
1513}
1514
1515impl<'a, T> VariableChunkIter<'a, T> {
1516 fn new(buffer: &'a [T]) -> Self {
1517 Self { buffer }
1518 }
1519}
1520
1521impl<'a, T> Iterator for VariableChunkIter<'a, T> {
1522 type Item = &'a [T];
1523
1524 fn next(&mut self) -> Option<Self::Item> {
1525 if self.buffer.is_empty() {
1526 return None;
1527 }
1528
1529 let s = calculate_chunk_size(self.buffer.len());
1530 let (chunk, remaining) = core::mem::take(&mut self.buffer).split_at(s);
1531 self.buffer = remaining;
1532 Some(chunk)
1533 }
1534}
1535
1536fn calculate_chunk_size(remaining: usize) -> usize {
1537 if remaining <= I2C_CHUNK_SIZE {
1538 remaining
1539 } else if remaining > I2C_CHUNK_SIZE + 2 {
1540 I2C_CHUNK_SIZE
1541 } else {
1542 I2C_CHUNK_SIZE - 2
1543 }
1544}
1545
1546#[cfg(i2c_master_has_hw_bus_clear)]
1547mod bus_clear {
1548 use esp_rom_sys::rom::ets_delay_us;
1549
1550 use super::*;
1551
1552 #[must_use = "futures do nothing unless you `.await` or poll them"]
1553 pub struct ClearBusFuture<'a> {
1554 driver: Driver<'a>,
1555 }
1556
1557 impl<'a> ClearBusFuture<'a> {
1558 const BUS_CLEAR_BITS: u8 = 9;
1560 const DELAY_US: u32 = 5; pub fn new(driver: Driver<'a>, reset_fsm: bool) -> Self {
1563 if reset_fsm {
1566 driver.do_fsm_reset();
1569 }
1570
1571 let mut this = Self { driver };
1572
1573 ets_delay_us(Self::DELAY_US);
1576
1577 this.configure(Self::BUS_CLEAR_BITS);
1578 this
1579 }
1580
1581 fn configure(&mut self, bits: u8) {
1582 self.driver.regs().scl_sp_conf().modify(|_, w| {
1583 unsafe { w.scl_rst_slv_num().bits(bits) };
1584 w.scl_rst_slv_en().bit(bits > 0)
1585 });
1586 self.driver.update_registers();
1587 }
1588
1589 fn is_done(&self) -> bool {
1590 self.driver
1591 .regs()
1592 .scl_sp_conf()
1593 .read()
1594 .scl_rst_slv_en()
1595 .bit_is_clear()
1596 }
1597
1598 pub fn poll_completion(&mut self) -> Poll<()> {
1599 if self.is_done() {
1600 Poll::Ready(())
1601 } else {
1602 Poll::Pending
1603 }
1604 }
1605 }
1606
1607 impl Drop for ClearBusFuture<'_> {
1608 fn drop(&mut self) {
1609 use crate::gpio::AnyPin;
1610 if !self.is_done() {
1611 self.configure(0);
1612 }
1613
1614 let sda = self
1616 .driver
1617 .config
1618 .sda_pin
1619 .pin_number()
1620 .map(|n| unsafe { AnyPin::steal(n) });
1621 let scl = self
1622 .driver
1623 .config
1624 .scl_pin
1625 .pin_number()
1626 .map(|n| unsafe { AnyPin::steal(n) });
1627
1628 if let (Some(sda), Some(scl)) = (sda, scl) {
1629 ets_delay_us(Self::DELAY_US);
1631
1632 sda.set_output_high(true);
1633 scl.set_output_high(false);
1634
1635 self.driver.info.scl_output.disconnect_from(&scl);
1636 self.driver.info.sda_output.disconnect_from(&sda);
1637
1638 sda.set_output_high(false);
1640 ets_delay_us(Self::DELAY_US);
1641
1642 scl.set_output_high(true);
1644 ets_delay_us(Self::DELAY_US);
1645
1646 sda.set_output_high(true);
1648 ets_delay_us(Self::DELAY_US);
1649
1650 self.driver.info.sda_output.connect_to(&sda);
1651 self.driver.info.scl_output.connect_to(&scl);
1652 }
1653
1654 self.driver.clear_all_interrupts();
1656 }
1657 }
1658}
1659
1660#[cfg(not(i2c_master_has_hw_bus_clear))]
1661mod bus_clear {
1662 use super::*;
1663 use crate::gpio::AnyPin;
1664
1665 enum State {
1671 Idle,
1672 SendStop,
1673
1674 SendClock(u8, bool),
1678 }
1679
1680 #[must_use = "futures do nothing unless you `.await` or poll them"]
1681 pub struct ClearBusFuture<'a> {
1682 driver: Driver<'a>,
1683 wait: Instant,
1684 state: State,
1685 reset_fsm: bool,
1686 pins: Option<(AnyPin<'static>, AnyPin<'static>)>,
1687 }
1688
1689 impl<'a> ClearBusFuture<'a> {
1690 const BUS_CLEAR_BITS: u8 = 9;
1692 const SCL_DELAY: Duration = Duration::from_micros(5);
1694
1695 pub fn new(driver: Driver<'a>, reset_fsm: bool) -> Self {
1696 let sda = driver
1697 .config
1698 .sda_pin
1699 .pin_number()
1700 .map(|n| unsafe { AnyPin::steal(n) });
1701 let scl = driver
1702 .config
1703 .scl_pin
1704 .pin_number()
1705 .map(|n| unsafe { AnyPin::steal(n) });
1706
1707 let (Some(sda), Some(scl)) = (sda, scl) else {
1708 if reset_fsm {
1710 driver.do_fsm_reset();
1711 }
1712 return Self {
1713 driver,
1714 wait: Instant::now(),
1715 state: State::Idle,
1716 reset_fsm: false,
1717 pins: None,
1718 };
1719 };
1720
1721 sda.set_output_high(true);
1722 scl.set_output_high(false);
1723
1724 driver.info.scl_output.disconnect_from(&scl);
1725 driver.info.sda_output.disconnect_from(&sda);
1726
1727 let state = State::SendClock(Self::BUS_CLEAR_BITS, false);
1733
1734 Self {
1735 driver,
1736 wait: Instant::now() + Self::SCL_DELAY,
1737 state,
1738 reset_fsm,
1739 pins: Some((sda, scl)),
1740 }
1741 }
1742 }
1743
1744 impl ClearBusFuture<'_> {
1745 pub fn poll_completion(&mut self) -> Poll<()> {
1746 let now = Instant::now();
1747
1748 match self.state {
1749 State::Idle => {
1750 if let Some((sda, _scl)) = self.pins.as_ref() {
1751 if !sda.is_input_high() {
1753 return Poll::Pending;
1754 }
1755 }
1756 return Poll::Ready(());
1757 }
1758 _ if now < self.wait => {
1759 return Poll::Pending;
1761 }
1762 State::SendStop => {
1763 if let Some((sda, _scl)) = self.pins.as_ref() {
1764 sda.set_output_high(true); }
1766 self.state = State::Idle;
1767 return Poll::Pending;
1768 }
1769 State::SendClock(0, false) => {
1770 if let Some((sda, scl)) = self.pins.as_ref() {
1771 sda.set_output_high(false);
1773 scl.set_output_high(true);
1774 }
1775 self.state = State::SendStop;
1776 }
1777 State::SendClock(n, false) => {
1778 if let Some((sda, scl)) = self.pins.as_ref() {
1779 scl.set_output_high(true);
1780 if sda.is_input_high() {
1781 sda.set_output_high(false);
1782 self.wait = Instant::now() + Self::SCL_DELAY;
1785 self.state = State::SendStop;
1786 return Poll::Pending;
1787 }
1788 }
1789 self.state = State::SendClock(n - 1, true);
1790 }
1791 State::SendClock(n, true) => {
1792 if let Some((_sda, scl)) = self.pins.as_ref() {
1793 scl.set_output_high(false);
1794 }
1795 self.state = State::SendClock(n, false);
1796 }
1797 }
1798 self.wait = Instant::now() + Self::SCL_DELAY;
1799
1800 Poll::Pending
1801 }
1802 }
1803
1804 impl Drop for ClearBusFuture<'_> {
1805 fn drop(&mut self) {
1806 if let Some((sda, scl)) = self.pins.take() {
1807 scl.set_output_high(true);
1809 sda.set_output_high(true);
1810
1811 if self.reset_fsm {
1814 self.driver.do_fsm_reset();
1815 }
1816
1817 self.driver.info.sda_output.connect_to(&sda);
1818 self.driver.info.scl_output.connect_to(&scl);
1819
1820 self.driver.clear_all_interrupts();
1823 }
1824 }
1825 }
1826}
1827
1828use bus_clear::ClearBusFuture;
1829
1830impl Future for ClearBusFuture<'_> {
1831 type Output = ();
1832
1833 fn poll(mut self: Pin<&mut Self>, ctx: &mut Context<'_>) -> Poll<Self::Output> {
1834 let pending = self.poll_completion();
1835 if pending.is_pending() {
1836 ctx.waker().wake_by_ref();
1837 }
1838 pending
1839 }
1840}
1841
1842#[doc(hidden)]
1844#[non_exhaustive]
1845pub struct State {
1846 pub waker: AtomicWaker,
1848}
1849
1850pub trait Instance: crate::private::Sealed + any::Degrade {
1852 #[doc(hidden)]
1853 fn parts(&self) -> (&Info, &State);
1855
1856 #[doc(hidden)]
1858 #[inline(always)]
1859 fn info(&self) -> &Info {
1860 self.parts().0
1861 }
1862
1863 #[doc(hidden)]
1865 #[inline(always)]
1866 fn state(&self) -> &State {
1867 self.parts().1
1868 }
1869}
1870
1871fn add_cmd<'a, I>(cmd_iterator: &mut I, command: Command) -> Result<(), Error>
1876where
1877 I: Iterator<Item = &'a COMD>,
1878{
1879 let cmd = cmd_iterator.next().ok_or(Error::CommandNumberExceeded)?;
1880
1881 cmd.write(|w| match command {
1882 Command::Start => w.opcode().rstart(),
1883 Command::Stop => w.opcode().stop(),
1884 Command::End => w.opcode().end(),
1885 Command::Write {
1886 ack_exp,
1887 ack_check_en,
1888 length,
1889 } => unsafe {
1890 w.opcode().write();
1891 w.ack_exp().bit(ack_exp == Ack::Nack);
1892 w.ack_check_en().bit(ack_check_en);
1893 w.byte_num().bits(length);
1894 w
1895 },
1896 Command::Read { ack_value, length } => unsafe {
1897 w.opcode().read();
1898 w.ack_value().bit(ack_value == Ack::Nack);
1899 w.byte_num().bits(length);
1900 w
1901 },
1902 });
1903
1904 Ok(())
1905}
1906
1907fn estimate_ack_failed_reason(_register_block: &RegisterBlock) -> AcknowledgeCheckFailedReason {
1910 cfg_select! {
1911 i2c_master_can_estimate_nack_reason => {
1912 if _register_block.fifo_st().read().txfifo_raddr().bits() <= 1 {
1914 AcknowledgeCheckFailedReason::Address
1915 } else {
1916 AcknowledgeCheckFailedReason::Data
1917 }
1918 }
1919 _ => AcknowledgeCheckFailedReason::Unknown,
1920 }
1921}
1922
1923for_each_i2c_master!(
1924 ($id:literal, $inst:ident, $peri:ident, $scl:ident, $sda:ident) => {
1925 impl Instance for crate::peripherals::$inst<'_> {
1926 fn parts(&self) -> (&Info, &State) {
1927 #[handler]
1928 #[ram]
1929 pub(super) fn irq_handler() {
1930 async_handler(&PERIPHERAL, &STATE);
1931 }
1932
1933 static STATE: State = State {
1934 waker: AtomicWaker::new(),
1935 };
1936
1937 static PERIPHERAL: Info = Info {
1938 #[cfg(soc_has_i2c1)]
1939 id: $id,
1940 register_block: crate::peripherals::$inst::ptr(),
1941 peripheral: crate::system::Peripheral::$peri,
1942 async_handler: irq_handler,
1943 scl_output: OutputSignal::$scl,
1944 scl_input: InputSignal::$scl,
1945 sda_output: OutputSignal::$sda,
1946 sda_input: InputSignal::$sda,
1947 clock_instance: paste::paste! { crate::soc::clocks::I2cInstance::[<I2c $id>] },
1948 };
1949 (&PERIPHERAL, &STATE)
1950 }
1951 }
1952 };
1953);
1954
1955crate::any_peripheral! {
1956 pub peripheral AnyI2c<'d> {
1958 #[cfg(i2c_master_i2c0)]
1959 I2c0(crate::peripherals::I2C0<'d>),
1960 #[cfg(i2c_master_i2c1)]
1961 I2c1(crate::peripherals::I2C1<'d>),
1962 }
1963}
1964
1965impl Instance for AnyI2c<'_> {
1966 fn parts(&self) -> (&Info, &State) {
1967 any::delegate!(self, i2c => { i2c.parts() })
1968 }
1969}
1970
1971impl AnyI2c<'_> {
1972 fn bind_peri_interrupt(&self, handler: InterruptHandler) {
1973 any::delegate!(self, i2c => { i2c.bind_peri_interrupt(handler) })
1974 }
1975
1976 pub(super) fn disable_peri_interrupt_on_all_cores(&self) {
1977 any::delegate!(self, i2c => { i2c.disable_peri_interrupt_on_all_cores() })
1978 }
1979
1980 pub(super) fn set_interrupt_handler(&self, handler: InterruptHandler) {
1981 self.disable_peri_interrupt_on_all_cores();
1982
1983 self.info().enable_listen(EnumSet::all(), false);
1984 self.info().clear_interrupts(EnumSet::all());
1985
1986 self.bind_peri_interrupt(handler);
1987 }
1988}