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) {
551 let mut future = ClearBusFuture::new(*self, reset_fsm);
552 let start = Instant::now();
553 while future.poll_completion().is_pending() {
554 if start.elapsed() > CLEAR_BUS_TIMEOUT_MS {
555 break;
556 }
557 }
558 }
559
560 async fn clear_bus(&self) {
561 let clear_bus = ClearBusFuture::new(*self, true);
562 let start = Instant::now();
563
564 embassy_futures::select::select(clear_bus, async {
565 while start.elapsed() < CLEAR_BUS_TIMEOUT_MS {
566 embassy_futures::yield_now().await;
567 }
568 })
569 .await;
570 }
571
572 pub(super) fn force_scl_low(&self, low: bool) {
573 cfg_select! {
574 i2c_master_has_pd_en => self.set_scl_pd(low),
575 _ => self.force_pin_low(low, self.config.scl_pin.pin_number(), &self.info.scl_output),
576 }
577 }
578
579 pub(super) fn force_sda_low(&self, low: bool) {
580 cfg_select! {
581 i2c_master_has_pd_en => self.set_sda_pd(low),
582 _ => self.force_pin_low(low, self.config.sda_pin.pin_number(), &self.info.sda_output),
583 }
584 }
585
586 #[cfg(i2c_master_has_pd_en)]
588 fn restore_force_out(&self) {
589 self.regs().ctr().modify(|_, w| {
590 w.scl_force_out().open_drain();
591 w.sda_force_out().open_drain()
592 });
593 self.update_registers();
594 }
595
596 #[cfg(not(i2c_master_has_pd_en))]
597 fn force_pin_low(
598 &self,
599 low: bool,
600 pin_number: Option<u8>,
601 output_signal: &crate::gpio::OutputSignal,
602 ) {
603 use crate::gpio::AnyPin;
604 let Some(n) = pin_number else { return };
605 let pin = unsafe { AnyPin::steal(n) };
606 if low {
607 pin.set_output_high(false);
608 output_signal.disconnect_from(&pin);
609 } else {
610 output_signal.connect_to(&pin);
611 }
612 }
613
614 #[cfg(i2c_master_has_pd_en)]
618 fn set_scl_pd(&self, low: bool) {
619 if low {
620 self.regs()
621 .ctr()
622 .modify(|_, w| w.scl_force_out().direct_output());
623 }
624 self.regs()
625 .scl_sp_conf()
626 .modify(|_, w| w.scl_pd_en().bit(low));
627 if !low {
628 let sp = self.regs().scl_sp_conf().read();
629 if sp.scl_pd_en().bit_is_clear() && sp.sda_pd_en().bit_is_clear() {
630 self.restore_force_out();
631 return;
632 }
633 }
634 self.update_registers();
635 }
636
637 #[cfg(i2c_master_has_pd_en)]
641 fn set_sda_pd(&self, low: bool) {
642 if low {
643 self.regs()
644 .ctr()
645 .modify(|_, w| w.sda_force_out().direct_output());
646 }
647 self.regs()
648 .scl_sp_conf()
649 .modify(|_, w| w.sda_pd_en().bit(low));
650 if !low {
651 let sp = self.regs().scl_sp_conf().read();
652 if sp.scl_pd_en().bit_is_clear() && sp.sda_pd_en().bit_is_clear() {
653 self.restore_force_out();
654 return;
655 }
656 }
657 self.update_registers();
658 }
659
660 fn reset_command_list(&self) {
662 for cmd in self.regs().comd_iter() {
663 cmd.reset();
664 }
665 }
666
667 fn setup_write<'a, I>(
675 &self,
676 addr: I2cAddress,
677 bytes: &[u8],
678 start: bool,
679 stop: bool,
680 cmd_iterator: &mut I,
681 ) -> Result<(), Error>
682 where
683 I: Iterator<Item = &'a COMD>,
684 {
685 let max_len = if start {
688 I2C_CHUNK_SIZE
689 } else {
690 I2C_CHUNK_SIZE + 1
691 };
692 if bytes.len() > max_len {
693 return Err(Error::FifoExceeded);
694 }
695
696 if start {
697 add_cmd(cmd_iterator, Command::Start)?;
698 }
699
700 let write_len = if start { bytes.len() + 1 } else { bytes.len() };
701 if write_len > 0 {
703 if cfg!(i2c_master_version = "1") && !(start || stop) {
711 add_cmd(
714 cmd_iterator,
715 Command::Write {
716 ack_exp: Ack::Ack,
717 ack_check_en: true,
718 length: (write_len as u8) - 1,
719 },
720 )?;
721 add_cmd(
722 cmd_iterator,
723 Command::Write {
724 ack_exp: Ack::Ack,
725 ack_check_en: true,
726 length: 1,
727 },
728 )?;
729 } else {
730 add_cmd(
731 cmd_iterator,
732 Command::Write {
733 ack_exp: Ack::Ack,
734 ack_check_en: true,
735 length: write_len as u8,
736 },
737 )?;
738 }
739 }
740
741 if start {
742 match addr {
744 I2cAddress::SevenBit(addr) => {
745 self.write_fifo((addr << 1) | OperationType::Write as u8);
746 }
747 }
748 }
749 for b in bytes {
750 self.write_fifo(*b);
751 }
752
753 Ok(())
754 }
755
756 fn setup_read<'a, I>(
766 &self,
767 addr: I2cAddress,
768 buffer: &mut [u8],
769 start: bool,
770 stop: bool,
771 will_continue: bool,
772 cmd_iterator: &mut I,
773 ) -> Result<(), Error>
774 where
775 I: Iterator<Item = &'a COMD>,
776 {
777 if buffer.is_empty() {
778 return Err(Error::ZeroLengthInvalid);
779 }
780 let (max_len, initial_len) = if will_continue {
781 (I2C_CHUNK_SIZE + 1, buffer.len())
782 } else {
783 (I2C_CHUNK_SIZE, buffer.len() - 1)
784 };
785 if buffer.len() > max_len {
786 return Err(Error::FifoExceeded);
787 }
788
789 if start {
790 add_cmd(cmd_iterator, Command::Start)?;
791 add_cmd(
793 cmd_iterator,
794 Command::Write {
795 ack_exp: Ack::Ack,
796 ack_check_en: true,
797 length: 1,
798 },
799 )?;
800 }
801
802 if initial_len > 0 {
803 let extra_commands = if cfg!(i2c_master_version = "1") {
804 match (start, will_continue) {
805 (true, _) => 0,
807 (false, true) => 2,
809 (false, false) => 1 - stop as u8,
811 }
812 } else {
813 0
814 };
815
816 add_cmd(
817 cmd_iterator,
818 Command::Read {
819 ack_value: Ack::Ack,
820 length: initial_len as u8 - extra_commands,
821 },
822 )?;
823 for _ in 0..extra_commands {
824 add_cmd(
825 cmd_iterator,
826 Command::Read {
827 ack_value: Ack::Ack,
828 length: 1,
829 },
830 )?;
831 }
832 }
833
834 if !will_continue {
835 add_cmd(
838 cmd_iterator,
839 Command::Read {
840 ack_value: Ack::Nack,
841 length: 1,
842 },
843 )?;
844 }
845
846 self.update_registers();
847
848 if start {
849 match addr {
851 I2cAddress::SevenBit(addr) => {
852 self.write_fifo((addr << 1) | OperationType::Read as u8);
853 }
854 }
855 }
856 Ok(())
857 }
858
859 fn read_all_from_fifo(&self, buffer: &mut [u8]) -> Result<(), Error> {
861 if self.regs().sr().read().rxfifo_cnt().bits() < buffer.len() as u8 {
862 return Err(Error::ExecutionIncomplete);
863 }
864
865 for byte in buffer.iter_mut() {
867 *byte = self.read_fifo();
868 }
869
870 debug_assert!(self.regs().sr().read().rxfifo_cnt().bits() == 0);
873
874 Ok(())
875 }
876
877 fn clear_all_interrupts(&self) {
879 self.regs()
880 .int_clr()
881 .write(|w| unsafe { w.bits(property!("i2c_master.ll_intr_mask")) });
882 }
883
884 async fn wait_for_completion(&self, deadline: Option<Instant>) -> Result<(), Error> {
885 I2cFuture::new(Event::TxComplete | Event::EndDetect, *self, deadline).await?;
886 self.check_all_commands_done(deadline).await
887 }
888
889 fn wait_for_completion_blocking(&self, deadline: Option<Instant>) -> Result<(), Error> {
891 let mut future =
892 I2cFuture::new_blocking(Event::TxComplete | Event::EndDetect, *self, deadline);
893 loop {
894 if let Poll::Ready(result) = future.poll_completion() {
895 result?;
896 return self.check_all_commands_done_blocking(deadline);
897 }
898 }
899 }
900
901 fn all_commands_done(&self, deadline: Option<Instant>) -> Result<bool, Error> {
902 let now = if deadline.is_some() {
906 Instant::now()
907 } else {
908 Instant::EPOCH
909 };
910
911 self.check_errors()?;
912
913 for cmd_reg in self.regs().comd_iter() {
914 let cmd = cmd_reg.read();
915
916 if cmd.bits() != 0x0 && !cmd.opcode().is_end() && !cmd.command_done().bit_is_set() {
918 if let Some(deadline) = deadline
920 && now > deadline
921 {
922 return Err(Error::ExecutionIncomplete);
923 }
924
925 return Ok(false);
926 }
927
928 if cmd.opcode().is_end() {
930 break;
931 }
932 if cmd.opcode().is_stop() {
933 #[cfg(i2c_master_version = "1")]
934 if self.regs().sr().read().scl_state_last() == 6 {
937 self.check_errors()?;
938 } else {
939 continue;
940 }
941 break;
942 }
943 }
944 Ok(true)
945 }
946
947 fn check_all_commands_done_blocking(&self, deadline: Option<Instant>) -> Result<(), Error> {
949 while !self.all_commands_done(deadline)? {}
951 self.check_errors()?;
952
953 Ok(())
954 }
955
956 async fn check_all_commands_done(&self, deadline: Option<Instant>) -> Result<(), Error> {
958 while !self.all_commands_done(deadline)? {
960 embassy_futures::yield_now().await;
961 }
962 self.check_errors()?;
963
964 Ok(())
965 }
966
967 fn check_errors(&self) -> Result<(), Error> {
974 let r = self.regs().int_raw().read();
975
976 if r.nack().bit_is_set() {
978 return Err(Error::AcknowledgeCheckFailed(estimate_ack_failed_reason(
979 self.regs(),
980 )));
981 }
982 if r.arbitration_lost().bit_is_set() {
983 return Err(Error::ArbitrationLost);
984 }
985
986 #[cfg(not(i2c_master_version = "1"))]
987 if r.trans_complete().bit_is_set() && self.regs().sr().read().resp_rec().bit_is_clear() {
988 return Err(Error::AcknowledgeCheckFailed(
989 AcknowledgeCheckFailedReason::Data,
990 ));
991 }
992
993 #[cfg(i2c_master_has_fsm_timeouts)]
994 {
995 if r.scl_st_to().bit_is_set() {
996 return Err(Error::Timeout);
997 }
998 if r.scl_main_st_to().bit_is_set() {
999 return Err(Error::Timeout);
1000 }
1001 }
1002 if r.time_out().bit_is_set() {
1003 return Err(Error::Timeout);
1004 }
1005
1006 Ok(())
1007 }
1008
1009 fn update_registers(&self) {
1016 #[cfg(i2c_master_has_conf_update)]
1019 self.regs().ctr().modify(|_, w| w.conf_upgate().set_bit());
1020 }
1021
1022 fn set_frequency(&self, config: &Config) -> Result<(), ConfigError> {
1023 version::set_frequency(self, config)
1024 }
1025
1026 fn reset_fifo(&self) {
1027 version::reset_fifo(self);
1028 }
1029
1030 fn read_fifo(&self) -> u8 {
1031 version::read_fifo(self.regs())
1032 }
1033
1034 fn write_fifo(&self, data: u8) {
1035 version::write_fifo(self.regs(), data);
1036 }
1037
1038 fn start_transmission(&self) {
1040 self.regs().ctr().modify(|_, w| w.trans_start().set_bit());
1042 }
1043
1044 fn start_write_operation(
1045 &self,
1046 address: I2cAddress,
1047 buffer: &[u8],
1048 start: bool,
1049 stop: bool,
1050 deadline: Deadline,
1051 ) -> Result<Option<Instant>, Error> {
1052 let cmd_iterator = &mut self.regs().comd_iter();
1053
1054 self.setup_write(address, buffer, start, stop, cmd_iterator)?;
1055
1056 if stop {
1057 add_cmd(cmd_iterator, Command::Stop)?;
1058 }
1059 if !(start && stop) {
1060 add_cmd(cmd_iterator, Command::End)?;
1064 }
1065
1066 self.start_transmission();
1067
1068 Ok(deadline.start(buffer.len() + address.bytes()))
1069 }
1070
1071 fn start_read_operation(
1081 &self,
1082 address: I2cAddress,
1083 buffer: &mut [u8],
1084 start: bool,
1085 will_continue: bool,
1086 stop: bool,
1087 deadline: Deadline,
1088 ) -> Result<Option<Instant>, Error> {
1089 debug_assert!(buffer.len() <= I2C_FIFO_SIZE);
1093
1094 let cmd_iterator = &mut self.regs().comd_iter();
1095
1096 self.setup_read(address, buffer, start, stop, will_continue, cmd_iterator)?;
1097
1098 if stop {
1099 add_cmd(cmd_iterator, Command::Stop)?;
1100 }
1101 if !(start && stop) {
1102 add_cmd(cmd_iterator, Command::End)?;
1104 }
1105
1106 self.start_transmission();
1107
1108 Ok(deadline.start(buffer.len() + address.bytes()))
1109 }
1110
1111 fn write_operation_blocking(
1119 &self,
1120 address: I2cAddress,
1121 bytes: &[u8],
1122 start: bool,
1123 stop: bool,
1124 deadline: Deadline,
1125 ) -> Result<(), Error> {
1126 address.validate()?;
1127
1128 self.reset_before_transmission();
1129
1130 if bytes.is_empty() && !start && !stop {
1133 return Ok(());
1134 }
1135
1136 let deadline = self.start_write_operation(address, bytes, start, stop, deadline)?;
1137 self.wait_for_completion_blocking(deadline)?;
1138
1139 Ok(())
1140 }
1141
1142 fn read_operation_blocking(
1152 &self,
1153 address: I2cAddress,
1154 buffer: &mut [u8],
1155 start: bool,
1156 stop: bool,
1157 will_continue: bool,
1158 deadline: Deadline,
1159 ) -> Result<(), Error> {
1160 address.validate()?;
1161 self.reset_before_transmission();
1162
1163 if buffer.is_empty() {
1166 return Ok(());
1167 }
1168
1169 let deadline =
1170 self.start_read_operation(address, buffer, start, will_continue, stop, deadline)?;
1171 self.wait_for_completion_blocking(deadline)?;
1172 self.read_all_from_fifo(buffer)?;
1173
1174 Ok(())
1175 }
1176
1177 async fn write_operation(
1185 &self,
1186 address: I2cAddress,
1187 bytes: &[u8],
1188 start: bool,
1189 stop: bool,
1190 deadline: Deadline,
1191 ) -> Result<(), Error> {
1192 address.validate()?;
1193 self.reset_before_transmission();
1194
1195 if bytes.is_empty() && !start && !stop {
1198 return Ok(());
1199 }
1200
1201 let deadline = self.start_write_operation(address, bytes, start, stop, deadline)?;
1202 self.wait_for_completion(deadline).await?;
1203
1204 Ok(())
1205 }
1206
1207 async fn read_operation(
1217 &self,
1218 address: I2cAddress,
1219 buffer: &mut [u8],
1220 start: bool,
1221 stop: bool,
1222 will_continue: bool,
1223 deadline: Deadline,
1224 ) -> Result<(), Error> {
1225 address.validate()?;
1226 self.reset_before_transmission();
1227
1228 if buffer.is_empty() {
1231 return Ok(());
1232 }
1233
1234 let deadline =
1235 self.start_read_operation(address, buffer, start, will_continue, stop, deadline)?;
1236 self.wait_for_completion(deadline).await?;
1237 self.read_all_from_fifo(buffer)?;
1238
1239 Ok(())
1240 }
1241
1242 fn read_blocking(
1243 &self,
1244 address: I2cAddress,
1245 buffer: &mut [u8],
1246 start: bool,
1247 stop: bool,
1248 will_continue: bool,
1249 deadline: Deadline,
1250 ) -> Result<(), Error> {
1251 let chunk_count = VariableChunkIterMut::new(buffer).count();
1252 for (idx, chunk) in VariableChunkIterMut::new(buffer).enumerate() {
1253 self.read_operation_blocking(
1254 address,
1255 chunk,
1256 start && idx == 0,
1257 stop && idx == chunk_count - 1,
1258 will_continue || idx < chunk_count - 1,
1259 deadline,
1260 )?;
1261 }
1262
1263 Ok(())
1264 }
1265
1266 fn write_blocking(
1267 &self,
1268 address: I2cAddress,
1269 buffer: &[u8],
1270 start: bool,
1271 stop: bool,
1272 deadline: Deadline,
1273 ) -> Result<(), Error> {
1274 if buffer.is_empty() {
1275 return self.write_operation_blocking(address, &[], start, stop, deadline);
1276 }
1277
1278 let chunk_count = VariableChunkIter::new(buffer).count();
1279 for (idx, chunk) in VariableChunkIter::new(buffer).enumerate() {
1280 self.write_operation_blocking(
1281 address,
1282 chunk,
1283 start && idx == 0,
1284 stop && idx == chunk_count - 1,
1285 deadline,
1286 )?;
1287 }
1288
1289 Ok(())
1290 }
1291
1292 async fn read(
1293 &self,
1294 address: I2cAddress,
1295 buffer: &mut [u8],
1296 start: bool,
1297 stop: bool,
1298 will_continue: bool,
1299 deadline: Deadline,
1300 ) -> Result<(), Error> {
1301 let chunk_count = VariableChunkIterMut::new(buffer).count();
1302 for (idx, chunk) in VariableChunkIterMut::new(buffer).enumerate() {
1303 self.read_operation(
1304 address,
1305 chunk,
1306 start && idx == 0,
1307 stop && idx == chunk_count - 1,
1308 will_continue || idx < chunk_count - 1,
1309 deadline,
1310 )
1311 .await?;
1312 }
1313
1314 Ok(())
1315 }
1316
1317 async fn write(
1318 &self,
1319 address: I2cAddress,
1320 buffer: &[u8],
1321 start: bool,
1322 stop: bool,
1323 deadline: Deadline,
1324 ) -> Result<(), Error> {
1325 if buffer.is_empty() {
1326 return self
1327 .write_operation(address, &[], start, stop, deadline)
1328 .await;
1329 }
1330
1331 let chunk_count = VariableChunkIter::new(buffer).count();
1332 for (idx, chunk) in VariableChunkIter::new(buffer).enumerate() {
1333 self.write_operation(
1334 address,
1335 chunk,
1336 start && idx == 0,
1337 stop && idx == chunk_count - 1,
1338 deadline,
1339 )
1340 .await?;
1341 }
1342
1343 Ok(())
1344 }
1345
1346 pub(super) fn transaction_impl<'a>(
1347 &self,
1348 address: I2cAddress,
1349 operations: impl Iterator<Item = Operation<'a>>,
1350 ) -> Result<(), Error> {
1351 address.validate()?;
1352 self.ensure_idle_blocking();
1353
1354 let mut deadline = Deadline::None;
1355
1356 if let SoftwareTimeout::Transaction(timeout) = self.config.config.software_timeout {
1357 deadline = Deadline::Fixed(Instant::now() + timeout);
1358 }
1359
1360 let mut last_op: Option<OpKind> = None;
1361 let mut op_iter = operations
1363 .filter(|op| op.is_write() || !op.is_empty())
1364 .peekable();
1365
1366 while let Some(op) = op_iter.next() {
1367 let next_op = op_iter.peek().map(|v| v.kind());
1368 let kind = op.kind();
1369 match op {
1370 Operation::Write(buffer) => {
1371 if let SoftwareTimeout::PerByte(timeout) = self.config.config.software_timeout {
1375 deadline = Deadline::PerByte(timeout);
1376 }
1377 self.write_blocking(
1378 address,
1379 buffer,
1380 !matches!(last_op, Some(OpKind::Write)),
1381 next_op.is_none(),
1382 deadline,
1383 )?;
1384 }
1385 Operation::Read(buffer) => {
1386 if let SoftwareTimeout::PerByte(timeout) = self.config.config.software_timeout {
1387 deadline = Deadline::PerByte(timeout);
1388 }
1389 self.read_blocking(
1394 address,
1395 buffer,
1396 !matches!(last_op, Some(OpKind::Read)),
1397 next_op.is_none(),
1398 matches!(next_op, Some(OpKind::Read)),
1399 deadline,
1400 )?;
1401 }
1402 }
1403
1404 last_op = Some(kind);
1405 }
1406
1407 Ok(())
1408 }
1409
1410 pub(super) async fn transaction_impl_async<'a>(
1411 &self,
1412 address: I2cAddress,
1413 operations: impl Iterator<Item = Operation<'a>>,
1414 ) -> Result<(), Error> {
1415 address.validate()?;
1416 self.ensure_idle().await;
1417
1418 let mut deadline = Deadline::None;
1419
1420 if let SoftwareTimeout::Transaction(timeout) = self.config.config.software_timeout {
1421 deadline = Deadline::Fixed(Instant::now() + timeout);
1422 }
1423
1424 let mut last_op: Option<OpKind> = None;
1425 let mut op_iter = operations
1427 .filter(|op| op.is_write() || !op.is_empty())
1428 .peekable();
1429
1430 while let Some(op) = op_iter.next() {
1431 let next_op = op_iter.peek().map(|v| v.kind());
1432 let kind = op.kind();
1433 match op {
1434 Operation::Write(buffer) => {
1435 if let SoftwareTimeout::PerByte(timeout) = self.config.config.software_timeout {
1436 deadline = Deadline::PerByte(timeout);
1437 }
1438 self.write(
1442 address,
1443 buffer,
1444 !matches!(last_op, Some(OpKind::Write)),
1445 next_op.is_none(),
1446 deadline,
1447 )
1448 .await?;
1449 }
1450 Operation::Read(buffer) => {
1451 if let SoftwareTimeout::PerByte(timeout) = self.config.config.software_timeout {
1452 deadline = Deadline::PerByte(timeout);
1453 }
1454 self.read(
1459 address,
1460 buffer,
1461 !matches!(last_op, Some(OpKind::Read)),
1462 next_op.is_none(),
1463 matches!(next_op, Some(OpKind::Read)),
1464 deadline,
1465 )
1466 .await?;
1467 }
1468 }
1469
1470 last_op = Some(kind);
1471 }
1472
1473 Ok(())
1474 }
1475}
1476
1477struct VariableChunkIterMut<'a, T> {
1480 buffer: &'a mut [T],
1481}
1482
1483impl<'a, T> VariableChunkIterMut<'a, T> {
1484 fn new(buffer: &'a mut [T]) -> Self {
1485 Self { buffer }
1486 }
1487}
1488
1489impl<'a, T> Iterator for VariableChunkIterMut<'a, T> {
1490 type Item = &'a mut [T];
1491
1492 fn next(&mut self) -> Option<Self::Item> {
1493 if self.buffer.is_empty() {
1494 return None;
1495 }
1496
1497 let s = calculate_chunk_size(self.buffer.len());
1498 let (chunk, remaining) = core::mem::take(&mut self.buffer).split_at_mut(s);
1499 self.buffer = remaining;
1500 Some(chunk)
1501 }
1502}
1503
1504struct VariableChunkIter<'a, T> {
1507 buffer: &'a [T],
1508}
1509
1510impl<'a, T> VariableChunkIter<'a, T> {
1511 fn new(buffer: &'a [T]) -> Self {
1512 Self { buffer }
1513 }
1514}
1515
1516impl<'a, T> Iterator for VariableChunkIter<'a, T> {
1517 type Item = &'a [T];
1518
1519 fn next(&mut self) -> Option<Self::Item> {
1520 if self.buffer.is_empty() {
1521 return None;
1522 }
1523
1524 let s = calculate_chunk_size(self.buffer.len());
1525 let (chunk, remaining) = core::mem::take(&mut self.buffer).split_at(s);
1526 self.buffer = remaining;
1527 Some(chunk)
1528 }
1529}
1530
1531fn calculate_chunk_size(remaining: usize) -> usize {
1532 if remaining <= I2C_CHUNK_SIZE {
1533 remaining
1534 } else if remaining > I2C_CHUNK_SIZE + 2 {
1535 I2C_CHUNK_SIZE
1536 } else {
1537 I2C_CHUNK_SIZE - 2
1538 }
1539}
1540
1541#[cfg(i2c_master_has_hw_bus_clear)]
1542mod bus_clear {
1543 use esp_rom_sys::rom::ets_delay_us;
1544
1545 use super::*;
1546
1547 #[must_use = "futures do nothing unless you `.await` or poll them"]
1548 pub struct ClearBusFuture<'a> {
1549 driver: Driver<'a>,
1550 }
1551
1552 impl<'a> ClearBusFuture<'a> {
1553 const BUS_CLEAR_BITS: u8 = 9;
1555 const DELAY_US: u32 = 5; pub fn new(driver: Driver<'a>, reset_fsm: bool) -> Self {
1558 if reset_fsm {
1561 driver.do_fsm_reset();
1564 }
1565
1566 let mut this = Self { driver };
1567
1568 ets_delay_us(Self::DELAY_US);
1571
1572 this.configure(Self::BUS_CLEAR_BITS);
1573 this
1574 }
1575
1576 fn configure(&mut self, bits: u8) {
1577 self.driver.regs().scl_sp_conf().modify(|_, w| {
1578 unsafe { w.scl_rst_slv_num().bits(bits) };
1579 w.scl_rst_slv_en().bit(bits > 0)
1580 });
1581 self.driver.update_registers();
1582 }
1583
1584 fn is_done(&self) -> bool {
1585 self.driver
1586 .regs()
1587 .scl_sp_conf()
1588 .read()
1589 .scl_rst_slv_en()
1590 .bit_is_clear()
1591 }
1592
1593 pub fn poll_completion(&mut self) -> Poll<()> {
1594 if self.is_done() {
1595 Poll::Ready(())
1596 } else {
1597 Poll::Pending
1598 }
1599 }
1600 }
1601
1602 impl Drop for ClearBusFuture<'_> {
1603 fn drop(&mut self) {
1604 use crate::gpio::AnyPin;
1605 if !self.is_done() {
1606 self.configure(0);
1607 }
1608
1609 let sda = self
1611 .driver
1612 .config
1613 .sda_pin
1614 .pin_number()
1615 .map(|n| unsafe { AnyPin::steal(n) });
1616 let scl = self
1617 .driver
1618 .config
1619 .scl_pin
1620 .pin_number()
1621 .map(|n| unsafe { AnyPin::steal(n) });
1622
1623 if let (Some(sda), Some(scl)) = (sda, scl) {
1624 ets_delay_us(Self::DELAY_US);
1626
1627 sda.set_output_high(true);
1628 scl.set_output_high(false);
1629
1630 self.driver.info.scl_output.disconnect_from(&scl);
1631 self.driver.info.sda_output.disconnect_from(&sda);
1632
1633 sda.set_output_high(false);
1635 ets_delay_us(Self::DELAY_US);
1636
1637 scl.set_output_high(true);
1639 ets_delay_us(Self::DELAY_US);
1640
1641 sda.set_output_high(true);
1643 ets_delay_us(Self::DELAY_US);
1644
1645 self.driver.info.sda_output.connect_to(&sda);
1646 self.driver.info.scl_output.connect_to(&scl);
1647 }
1648
1649 self.driver.clear_all_interrupts();
1651 }
1652 }
1653}
1654
1655#[cfg(not(i2c_master_has_hw_bus_clear))]
1656mod bus_clear {
1657 use super::*;
1658 use crate::gpio::AnyPin;
1659
1660 enum State {
1666 Idle,
1667 SendStop,
1668
1669 SendClock(u8, bool),
1673 }
1674
1675 #[must_use = "futures do nothing unless you `.await` or poll them"]
1676 pub struct ClearBusFuture<'a> {
1677 driver: Driver<'a>,
1678 wait: Instant,
1679 state: State,
1680 reset_fsm: bool,
1681 pins: Option<(AnyPin<'static>, AnyPin<'static>)>,
1682 }
1683
1684 impl<'a> ClearBusFuture<'a> {
1685 const BUS_CLEAR_BITS: u8 = 9;
1687 const SCL_DELAY: Duration = Duration::from_micros(5);
1689
1690 pub fn new(driver: Driver<'a>, reset_fsm: bool) -> Self {
1691 let sda = driver
1692 .config
1693 .sda_pin
1694 .pin_number()
1695 .map(|n| unsafe { AnyPin::steal(n) });
1696 let scl = driver
1697 .config
1698 .scl_pin
1699 .pin_number()
1700 .map(|n| unsafe { AnyPin::steal(n) });
1701
1702 let (Some(sda), Some(scl)) = (sda, scl) else {
1703 if reset_fsm {
1705 driver.do_fsm_reset();
1706 }
1707 return Self {
1708 driver,
1709 wait: Instant::now(),
1710 state: State::Idle,
1711 reset_fsm: false,
1712 pins: None,
1713 };
1714 };
1715
1716 sda.set_output_high(true);
1717 scl.set_output_high(false);
1718
1719 driver.info.scl_output.disconnect_from(&scl);
1720 driver.info.sda_output.disconnect_from(&sda);
1721
1722 let state = State::SendClock(Self::BUS_CLEAR_BITS, false);
1728
1729 Self {
1730 driver,
1731 wait: Instant::now() + Self::SCL_DELAY,
1732 state,
1733 reset_fsm,
1734 pins: Some((sda, scl)),
1735 }
1736 }
1737 }
1738
1739 impl ClearBusFuture<'_> {
1740 pub fn poll_completion(&mut self) -> Poll<()> {
1741 let now = Instant::now();
1742
1743 match self.state {
1744 State::Idle => {
1745 if let Some((sda, _scl)) = self.pins.as_ref() {
1746 if !sda.is_input_high() {
1748 return Poll::Pending;
1749 }
1750 }
1751 return Poll::Ready(());
1752 }
1753 _ if now < self.wait => {
1754 return Poll::Pending;
1756 }
1757 State::SendStop => {
1758 if let Some((sda, _scl)) = self.pins.as_ref() {
1759 sda.set_output_high(true); }
1761 self.state = State::Idle;
1762 return Poll::Pending;
1763 }
1764 State::SendClock(0, false) => {
1765 if let Some((sda, scl)) = self.pins.as_ref() {
1766 sda.set_output_high(false);
1768 scl.set_output_high(true);
1769 }
1770 self.state = State::SendStop;
1771 }
1772 State::SendClock(n, false) => {
1773 if let Some((sda, scl)) = self.pins.as_ref() {
1774 scl.set_output_high(true);
1775 if sda.is_input_high() {
1776 sda.set_output_high(false);
1777 self.wait = Instant::now() + Self::SCL_DELAY;
1780 self.state = State::SendStop;
1781 return Poll::Pending;
1782 }
1783 }
1784 self.state = State::SendClock(n - 1, true);
1785 }
1786 State::SendClock(n, true) => {
1787 if let Some((_sda, scl)) = self.pins.as_ref() {
1788 scl.set_output_high(false);
1789 }
1790 self.state = State::SendClock(n, false);
1791 }
1792 }
1793 self.wait = Instant::now() + Self::SCL_DELAY;
1794
1795 Poll::Pending
1796 }
1797 }
1798
1799 impl Drop for ClearBusFuture<'_> {
1800 fn drop(&mut self) {
1801 if let Some((sda, scl)) = self.pins.take() {
1802 scl.set_output_high(true);
1804 sda.set_output_high(true);
1805
1806 if self.reset_fsm {
1809 self.driver.do_fsm_reset();
1810 }
1811
1812 self.driver.info.sda_output.connect_to(&sda);
1813 self.driver.info.scl_output.connect_to(&scl);
1814
1815 self.driver.clear_all_interrupts();
1818 }
1819 }
1820 }
1821}
1822
1823use bus_clear::ClearBusFuture;
1824
1825impl Future for ClearBusFuture<'_> {
1826 type Output = ();
1827
1828 fn poll(mut self: Pin<&mut Self>, ctx: &mut Context<'_>) -> Poll<Self::Output> {
1829 let pending = self.poll_completion();
1830 if pending.is_pending() {
1831 ctx.waker().wake_by_ref();
1832 }
1833 pending
1834 }
1835}
1836
1837#[doc(hidden)]
1839#[non_exhaustive]
1840pub struct State {
1841 pub waker: AtomicWaker,
1843}
1844
1845pub trait Instance: crate::private::Sealed + any::Degrade {
1847 #[doc(hidden)]
1848 fn parts(&self) -> (&Info, &State);
1850
1851 #[doc(hidden)]
1853 #[inline(always)]
1854 fn info(&self) -> &Info {
1855 self.parts().0
1856 }
1857
1858 #[doc(hidden)]
1860 #[inline(always)]
1861 fn state(&self) -> &State {
1862 self.parts().1
1863 }
1864}
1865
1866fn add_cmd<'a, I>(cmd_iterator: &mut I, command: Command) -> Result<(), Error>
1871where
1872 I: Iterator<Item = &'a COMD>,
1873{
1874 let cmd = cmd_iterator.next().ok_or(Error::CommandNumberExceeded)?;
1875
1876 cmd.write(|w| match command {
1877 Command::Start => w.opcode().rstart(),
1878 Command::Stop => w.opcode().stop(),
1879 Command::End => w.opcode().end(),
1880 Command::Write {
1881 ack_exp,
1882 ack_check_en,
1883 length,
1884 } => unsafe {
1885 w.opcode().write();
1886 w.ack_exp().bit(ack_exp == Ack::Nack);
1887 w.ack_check_en().bit(ack_check_en);
1888 w.byte_num().bits(length);
1889 w
1890 },
1891 Command::Read { ack_value, length } => unsafe {
1892 w.opcode().read();
1893 w.ack_value().bit(ack_value == Ack::Nack);
1894 w.byte_num().bits(length);
1895 w
1896 },
1897 });
1898
1899 Ok(())
1900}
1901
1902fn estimate_ack_failed_reason(_register_block: &RegisterBlock) -> AcknowledgeCheckFailedReason {
1905 cfg_select! {
1906 i2c_master_can_estimate_nack_reason => {
1907 if _register_block.fifo_st().read().txfifo_raddr().bits() <= 1 {
1909 AcknowledgeCheckFailedReason::Address
1910 } else {
1911 AcknowledgeCheckFailedReason::Data
1912 }
1913 }
1914 _ => AcknowledgeCheckFailedReason::Unknown,
1915 }
1916}
1917
1918for_each_i2c_master!(
1919 ($id:literal, $inst:ident, $peri:ident, $scl:ident, $sda:ident) => {
1920 impl Instance for crate::peripherals::$inst<'_> {
1921 fn parts(&self) -> (&Info, &State) {
1922 #[handler]
1923 #[ram]
1924 pub(super) fn irq_handler() {
1925 async_handler(&PERIPHERAL, &STATE);
1926 }
1927
1928 static STATE: State = State {
1929 waker: AtomicWaker::new(),
1930 };
1931
1932 static PERIPHERAL: Info = Info {
1933 #[cfg(soc_has_i2c1)]
1934 id: $id,
1935 register_block: crate::peripherals::$inst::ptr(),
1936 peripheral: crate::system::Peripheral::$peri,
1937 async_handler: irq_handler,
1938 scl_output: OutputSignal::$scl,
1939 scl_input: InputSignal::$scl,
1940 sda_output: OutputSignal::$sda,
1941 sda_input: InputSignal::$sda,
1942 clock_instance: paste::paste! { crate::soc::clocks::I2cInstance::[<I2c $id>] },
1943 };
1944 (&PERIPHERAL, &STATE)
1945 }
1946 }
1947 };
1948);
1949
1950crate::any_peripheral! {
1951 pub peripheral AnyI2c<'d> {
1953 #[cfg(i2c_master_i2c0)]
1954 I2c0(crate::peripherals::I2C0<'d>),
1955 #[cfg(i2c_master_i2c1)]
1956 I2c1(crate::peripherals::I2C1<'d>),
1957 }
1958}
1959
1960impl Instance for AnyI2c<'_> {
1961 fn parts(&self) -> (&Info, &State) {
1962 any::delegate!(self, i2c => { i2c.parts() })
1963 }
1964}
1965
1966impl AnyI2c<'_> {
1967 fn bind_peri_interrupt(&self, handler: InterruptHandler) {
1968 any::delegate!(self, i2c => { i2c.bind_peri_interrupt(handler) })
1969 }
1970
1971 pub(super) fn disable_peri_interrupt_on_all_cores(&self) {
1972 any::delegate!(self, i2c => { i2c.disable_peri_interrupt_on_all_cores() })
1973 }
1974
1975 pub(super) fn set_interrupt_handler(&self, handler: InterruptHandler) {
1976 self.disable_peri_interrupt_on_all_cores();
1977
1978 self.info().enable_listen(EnumSet::all(), false);
1979 self.info().clear_interrupts(EnumSet::all());
1980
1981 self.bind_peri_interrupt(handler);
1982 }
1983}