1use core::{
16 future::Future,
17 marker::PhantomData,
18 pin::Pin,
19 task::{Context, Poll},
20};
21
22use enumset::{EnumSet, EnumSetType};
23
24use crate::{
25 Async,
26 Blocking,
27 DriverMode,
28 asynch::AtomicWaker,
29 gpio::{
30 DriveMode,
31 InputSignal,
32 OutputConfig,
33 OutputSignal,
34 PinGuard,
35 Pull,
36 interconnect::{self, PeripheralInput, PeripheralOutput},
37 },
38 handler,
39 i2c::master::I2cAddress,
40 interrupt::InterruptHandler,
41 pac::i2c0::RegisterBlock,
42 private,
43 ram,
44 rtc_cntl::WakeLock,
45 system::PeripheralGuard,
46};
47
48pub const FIFO_SIZE: usize = property!("i2c_master.fifo_size");
50
51#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
53#[cfg_attr(feature = "defmt", derive(defmt::Format))]
54#[non_exhaustive]
55pub enum Error {
56 Timeout,
58 ArbitrationLost,
60}
61
62impl embedded_hal::i2c::Error for Error {
63 fn kind(&self) -> embedded_hal::i2c::ErrorKind {
64 match self {
65 Self::ArbitrationLost => embedded_hal::i2c::ErrorKind::ArbitrationLoss,
66 _ => embedded_hal::i2c::ErrorKind::Other,
67 }
68 }
69}
70
71#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, procmacros::BuilderLite)]
73#[cfg_attr(feature = "defmt", derive(defmt::Format))]
74#[non_exhaustive]
75pub struct Config {
76 address: I2cAddress,
78}
79
80impl Config {
81 pub fn new(address: impl Into<I2cAddress>) -> Self {
83 Config {
84 address: address.into(),
85 }
86 }
87}
88
89#[derive(Debug, Clone, Copy, PartialEq)]
91#[cfg_attr(feature = "defmt", derive(defmt::Format))]
92#[non_exhaustive]
93pub enum ConfigError {
94 AddressInvalid,
96}
97
98impl core::error::Error for ConfigError {}
99
100impl core::fmt::Display for ConfigError {
101 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
102 match self {
103 ConfigError::AddressInvalid => write!(f, "Provided address is invalid"),
104 }
105 }
106}
107
108#[derive(Debug, Copy, Clone, Eq, PartialEq)]
110#[cfg_attr(feature = "defmt", derive(defmt::Format))]
111pub enum Command {
112 Read,
114 Write(usize),
116}
117
118#[derive(Debug, Copy, Clone, Eq, PartialEq)]
120#[cfg_attr(feature = "defmt", derive(defmt::Format))]
121pub enum ReadStatus {
122 Done,
124 NeedMoreBytes,
126 LeftoverBytes(u16),
128}
129
130#[derive(Debug)]
132#[cfg_attr(feature = "defmt", derive(defmt::Format))]
133pub struct I2cSlave<'d, Dm: DriverMode> {
134 i2c: AnyI2c<'d>,
135 phantom: PhantomData<Dm>,
136 guard: PeripheralGuard,
137 config: DriverConfig,
138}
139
140#[derive(Debug)]
141#[cfg_attr(feature = "defmt", derive(defmt::Format))]
142struct DriverConfig {
143 config: Config,
144 sda_pin: PinGuard,
145 scl_pin: PinGuard,
146}
147
148impl<Dm: DriverMode> embedded_hal::i2c::ErrorType for I2cSlave<'_, Dm> {
149 type Error = Error;
150}
151
152impl<'d> I2cSlave<'d, Blocking> {
153 pub fn new(i2c: impl Instance + 'd, config: Config) -> Result<Self, ConfigError> {
155 let guard = PeripheralGuard::new(i2c.info().peripheral);
156
157 let sda_pin = PinGuard::new_unconnected();
158 let scl_pin = PinGuard::new_unconnected();
159
160 let mut slave = I2cSlave {
161 i2c: i2c.degrade(),
162 phantom: PhantomData,
163 guard,
164 config: DriverConfig {
165 config,
166 sda_pin,
167 scl_pin,
168 },
169 };
170
171 slave.apply_config(&config)?;
172 Ok(slave)
173 }
174
175 pub fn into_async(self) -> I2cSlave<'d, Async> {
177 self.i2c
178 .set_interrupt_handler(self.driver().info.async_handler);
179
180 I2cSlave {
181 i2c: self.i2c,
182 phantom: PhantomData,
183 guard: self.guard,
184 config: self.config,
185 }
186 }
187}
188
189impl<'d> I2cSlave<'d, Async> {
190 pub fn into_blocking(self) -> I2cSlave<'d, Blocking> {
192 self.i2c.disable_peri_interrupt();
193
194 I2cSlave {
195 i2c: self.i2c,
196 phantom: PhantomData,
197 guard: self.guard,
198 config: self.config,
199 }
200 }
201}
202
203impl<'d, Dm: DriverMode> I2cSlave<'d, Dm> {
204 fn driver(&self) -> Driver<'_> {
205 Driver {
206 info: self.i2c.info(),
207 state: self.i2c.state(),
208 config: &self.config,
209 }
210 }
211
212 pub fn with_sda(mut self, sda: impl PeripheralInput<'d> + PeripheralOutput<'d>) -> Self {
214 let info = self.driver().info;
215 let input = info.sda_input;
216 let output = info.sda_output;
217 Driver::connect_pin(sda.into(), input, output, &mut self.config.sda_pin);
218 self
219 }
220
221 pub fn with_scl(mut self, scl: impl PeripheralInput<'d> + PeripheralOutput<'d>) -> Self {
223 let info = self.driver().info;
224 let input = info.scl_input;
225 let output = info.scl_output;
226 Driver::connect_pin(scl.into(), input, output, &mut self.config.scl_pin);
227 self
228 }
229
230 pub fn apply_config(&mut self, config: &Config) -> Result<(), ConfigError> {
232 self.config.config = *config;
233 self.driver().setup(config)?;
234 Ok(())
235 }
236}
237
238impl<'d, Dm: DriverMode> I2cSlave<'d, Dm> {
239 pub fn listen(&mut self, buffer: &mut [u8]) -> Result<Command, Error> {
246 let regs = self.driver().info.regs();
247
248 self.driver().reset_fifo();
249
250 regs.scl_stretch_conf().modify(|_, w| unsafe {
251 w.stretch_protect_num().bits(0x3ff);
252 w.slave_scl_stretch_en().set_bit()
253 });
254
255 regs.int_clr().write(|w| unsafe { w.bits(0x3fff) });
256 regs.scl_stretch_conf()
257 .modify(|_, w| w.slave_scl_stretch_clr().set_bit());
258 self.driver().update_registers();
259
260 let mut bytes_read = 0;
261 loop {
262 self.driver().check_errors()?;
263 if let Some(res) = self.driver().listen_step(buffer, &mut bytes_read) {
264 return res;
265 }
266 }
267 }
268
269 pub fn respond_to_read(&mut self, buffer: &[u8]) -> Result<ReadStatus, Error> {
274 let regs = self.driver().info.regs();
275 let mut bytes_written = 0;
276 let initial_write = core::cmp::min(buffer.len(), FIFO_SIZE);
277 for &byte in buffer.iter().take(initial_write) {
278 regs.data().write(|w| unsafe { w.fifo_rdata().bits(byte) });
279 }
280 bytes_written += initial_write;
281
282 regs.scl_stretch_conf()
283 .modify(|_, w| w.slave_scl_stretch_clr().set_bit());
284 regs.int_clr().write(|w| unsafe { w.bits(0x3fff) });
285 self.driver().update_registers();
286
287 loop {
288 self.driver().check_errors()?;
289 if let Some(res) = self
290 .driver()
291 .respond_to_read_step(buffer, &mut bytes_written)
292 {
293 return res;
294 }
295 }
296 }
297}
298
299impl<'d> I2cSlave<'d, Async> {
300 pub async fn listen_async(&mut self, buffer: &mut [u8]) -> Result<Command, Error> {
302 let regs = self.driver().info.regs();
303 let state = self.i2c.state();
304
305 self.driver().reset_fifo();
306
307 regs.scl_stretch_conf().modify(|_, w| unsafe {
308 w.stretch_protect_num().bits(0x3ff);
309 w.slave_scl_stretch_en().set_bit()
310 });
311
312 regs.int_clr().write(|w| unsafe { w.bits(0x3fff) });
313 regs.scl_stretch_conf()
314 .modify(|_, w| w.slave_scl_stretch_clr().set_bit());
315 self.driver().update_registers();
316
317 let mut bytes_read = 0;
318 loop {
319 I2cSlaveFuture::new(regs, state, Event::SlaveStretch | Event::TransComplete).await?;
320 if let Some(res) = self.driver().listen_step(buffer, &mut bytes_read) {
321 return res;
322 }
323 }
324 }
325
326 pub async fn respond_to_read_async(&mut self, buffer: &[u8]) -> Result<ReadStatus, Error> {
328 let regs = self.driver().info.regs();
329 let state = self.i2c.state();
330
331 let mut bytes_written = 0;
332 let initial_write = core::cmp::min(buffer.len(), FIFO_SIZE);
333 for &byte in buffer.iter().take(initial_write) {
334 regs.data().write(|w| unsafe { w.fifo_rdata().bits(byte) });
335 }
336 bytes_written += initial_write;
337
338 regs.scl_stretch_conf()
339 .modify(|_, w| w.slave_scl_stretch_clr().set_bit());
340 regs.int_clr().write(|w| unsafe { w.bits(0x3fff) });
341 self.driver().update_registers();
342
343 loop {
344 I2cSlaveFuture::new(
345 regs,
346 state,
347 Event::SlaveStretch | Event::TransComplete | Event::Nack,
348 )
349 .await?;
350
351 if let Some(res) = self
352 .driver()
353 .respond_to_read_step(buffer, &mut bytes_written)
354 {
355 return res;
356 }
357 }
358 }
359}
360
361impl<Dm: DriverMode> private::Sealed for I2cSlave<'_, Dm> {}
362
363#[derive(Debug, EnumSetType)]
364#[cfg_attr(feature = "defmt", derive(defmt::Format))]
365#[non_exhaustive]
366pub(crate) enum Event {
367 SlaveStretch,
368 TransComplete,
369 Nack,
370}
371
372#[must_use = "futures do nothing unless you `.await` or poll them"]
373struct I2cSlaveFuture<'a> {
374 regs: &'a RegisterBlock,
375 state: &'a State,
376 events: EnumSet<Event>,
377 _wake_lock: WakeLock,
378}
379
380impl<'a> I2cSlaveFuture<'a> {
381 pub fn new(regs: &'a RegisterBlock, state: &'a State, events: EnumSet<Event>) -> Self {
382 regs.int_ena().modify(|_, w| {
383 if events.contains(Event::SlaveStretch) {
384 w.slave_stretch().set_bit();
385 }
386 if events.contains(Event::TransComplete) {
387 w.trans_complete().set_bit();
388 }
389 if events.contains(Event::Nack) {
390 w.nack().set_bit();
391 }
392 w.arbitration_lost().set_bit();
393 w.time_out().set_bit();
394 w
395 });
396
397 Self {
398 regs,
399 state,
400 events,
401 _wake_lock: WakeLock::new(),
402 }
403 }
404}
405
406impl Future for I2cSlaveFuture<'_> {
407 type Output = Result<(), Error>;
408
409 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
410 self.state.waker.register(cx.waker());
411
412 let raw = self.regs.int_raw().read();
413
414 if raw.arbitration_lost().bit_is_set() {
415 return Poll::Ready(Err(Error::ArbitrationLost));
416 }
417 if raw.time_out().bit_is_set() {
418 return Poll::Ready(Err(Error::Timeout));
419 }
420
421 let mut triggered = false;
422 if self.events.contains(Event::SlaveStretch) && raw.slave_stretch().bit_is_set() {
423 triggered = true;
424 }
425 if self.events.contains(Event::TransComplete) && raw.trans_complete().bit_is_set() {
426 triggered = true;
427 }
428 if self.events.contains(Event::Nack) && raw.nack().bit_is_set() {
429 triggered = true;
430 }
431
432 if triggered {
433 Poll::Ready(Ok(()))
434 } else {
435 self.regs.int_ena().modify(|_, w| {
436 if self.events.contains(Event::SlaveStretch) {
437 w.slave_stretch().set_bit();
438 }
439 if self.events.contains(Event::TransComplete) {
440 w.trans_complete().set_bit();
441 }
442 if self.events.contains(Event::Nack) {
443 w.nack().set_bit();
444 }
445 w.arbitration_lost().set_bit();
446 w.time_out().set_bit();
447 w
448 });
449 Poll::Pending
450 }
451 }
452}
453
454impl Drop for I2cSlaveFuture<'_> {
455 fn drop(&mut self) {
456 self.regs.int_ena().write(|w| unsafe { w.bits(0) });
457 }
458}
459
460#[ram]
461fn async_handler(info: &Info, state: &State) {
462 info.regs().int_ena().write(|w| unsafe { w.bits(0) });
463 state.waker.wake();
464}
465
466#[non_exhaustive]
468pub struct State {
469 pub(crate) waker: AtomicWaker,
470}
471
472impl core::fmt::Debug for State {
473 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
474 f.debug_struct("State")
475 .field("waker", &"<AtomicWaker>")
476 .finish()
477 }
478}
479
480#[derive(Debug)]
482#[non_exhaustive]
483pub struct Info {
484 pub(crate) register_block: *const RegisterBlock,
485 pub(crate) peripheral: crate::system::Peripheral,
486 pub(crate) async_handler: InterruptHandler,
487 pub(crate) scl_output: OutputSignal,
488 pub(crate) scl_input: InputSignal,
489 pub(crate) sda_output: OutputSignal,
490 pub(crate) sda_input: InputSignal,
491}
492
493impl Info {
494 pub(crate) fn regs(&self) -> &RegisterBlock {
495 unsafe { &*self.register_block }
496 }
497}
498
499unsafe impl Sync for Info {}
500
501pub trait Instance: crate::private::Sealed + any::Degrade {
503 #[doc(hidden)]
504 fn parts(&self) -> (&Info, &State);
505
506 #[doc(hidden)]
507 #[inline(always)]
508 fn info(&self) -> &Info {
509 self.parts().0
510 }
511
512 #[doc(hidden)]
513 #[inline(always)]
514 fn state(&self) -> &State {
515 self.parts().1
516 }
517}
518
519#[allow(dead_code)]
520struct Driver<'a> {
521 info: &'a Info,
522 state: &'a State,
523 config: &'a DriverConfig,
524}
525
526impl Driver<'_> {
527 fn regs(&self) -> &RegisterBlock {
528 self.info.regs()
529 }
530
531 fn connect_pin(
532 pin: crate::gpio::interconnect::OutputSignal<'_>,
533 input: InputSignal,
534 output: OutputSignal,
535 guard: &mut PinGuard,
536 ) {
537 pin.set_output_high(true);
538 pin.apply_output_config(
539 &OutputConfig::default()
540 .with_drive_mode(DriveMode::OpenDrain)
541 .with_pull(Pull::Up),
542 );
543 pin.set_output_enable(true);
544 pin.set_input_enable(true);
545 input.connect_to(&pin);
546 *guard = interconnect::OutputSignal::connect_with_guard(pin, output);
547 }
548
549 fn init_slave(&self) {
550 self.regs().ctr().write(|w| {
551 w.ms_mode().clear_bit(); w.sda_force_out().set_bit();
553 w.scl_force_out().set_bit();
554 #[cfg(i2c_master_has_arbitration_en)]
555 w.arbitration_en().clear_bit();
556 w.tx_lsb_first().clear_bit();
557 w.rx_lsb_first().clear_bit();
558 w
559 });
560
561 self.reset_fifo();
562
563 self.regs().fifo_conf().modify(|_, w| {
564 w.nonfifo_en().clear_bit();
565 w
566 });
567 }
568
569 fn set_slave_addr(&self, address: I2cAddress) -> Result<(), ConfigError> {
570 match address {
571 I2cAddress::SevenBit(addr) if addr <= 0x7F => {
572 self.regs().slave_addr().write(|w| unsafe {
573 w.slave_addr().bits(addr as u16);
574 w.addr_10bit_en().bit(false)
575 });
576 Ok(())
577 }
578 _ => Err(ConfigError::AddressInvalid),
579 }
580 }
581
582 fn update_registers(&self) {
583 #[cfg(i2c_master_has_conf_update)]
584 self.regs().ctr().modify(|_, w| w.conf_upgate().set_bit());
585 }
586
587 fn setup(&self, config: &Config) -> Result<(), ConfigError> {
588 self.init_slave();
589 self.set_slave_addr(config.address)?;
590
591 let regs = self.regs();
592 regs.to().modify(|_, w| unsafe {
593 w.time_out_en().set_bit();
594 w.time_out_value().bits(14);
595 w
596 });
597
598 regs.clk_conf().modify(|_, w| w.sclk_sel().clear_bit());
599 self.set_slave_addr(config.address)?;
600
601 regs.ctr()
602 .modify(|_, w| w.addr_broadcasting_en().clear_bit());
603
604 regs.fifo_conf().modify(|_, w| {
605 w.fifo_prt_en().set_bit();
606 unsafe { w.txfifo_wm_thrhd().bits(0) }
607 });
608
609 regs.fifo_conf().modify(|_, w| w.fifo_prt_en().set_bit());
610 regs.ctr().write(|w| w.rx_full_ack_level().clear_bit());
611
612 regs.fifo_conf()
613 .modify(|_, w| unsafe { w.rxfifo_wm_thrhd().bits(0x1F) });
614
615 regs.sda_hold().write(|w| unsafe { w.time().bits(10u16) });
616 regs.sda_sample().write(|w| unsafe { w.time().bits(10u16) });
617
618 regs.int_ena().write(|w| unsafe { w.bits(0) });
619 regs.int_clr().write(|w| unsafe { w.bits(0x3fff) });
620
621 regs.scl_stretch_conf().modify(|_, w| unsafe {
622 w.stretch_protect_num().bits(0x3ff);
623 w.slave_scl_stretch_en().set_bit()
624 });
625
626 regs.scl_stretch_conf()
627 .modify(|_, w| w.slave_scl_stretch_clr().set_bit());
628 self.update_registers();
629
630 Ok(())
631 }
632
633 fn reset_fifo(&self) {
634 self.regs()
635 .fifo_conf()
636 .modify(|_, w| w.tx_fifo_rst().set_bit());
637 self.regs()
638 .fifo_conf()
639 .modify(|_, w| w.tx_fifo_rst().clear_bit());
640 self.regs()
641 .fifo_conf()
642 .modify(|_, w| w.rx_fifo_rst().set_bit());
643 self.regs()
644 .fifo_conf()
645 .modify(|_, w| w.rx_fifo_rst().clear_bit());
646 }
647
648 fn reset_fsm(&self) {
649 #[cfg(i2c_master_has_reliable_fsm_reset)]
650 {
651 self.regs().ctr().modify(|_, w| w.fsm_rst().set_bit());
652 }
653 #[cfg(not(i2c_master_has_reliable_fsm_reset))]
654 {
655 crate::system::PeripheralClockControl::reset(self.info.peripheral);
656 self.setup(&self.config.config).ok();
657 }
658 }
659
660 fn check_errors(&self) -> Result<(), Error> {
661 let r = self.regs().int_raw().read();
662
663 if r.arbitration_lost().bit_is_set() {
664 return Err(Error::ArbitrationLost);
665 }
666 if r.time_out().bit_is_set() {
667 return Err(Error::Timeout);
668 }
669 Ok(())
670 }
671
672 fn listen_step(
673 &self,
674 buffer: &mut [u8],
675 bytes_read: &mut usize,
676 ) -> Option<Result<Command, Error>> {
677 let regs = self.regs();
678 let ints = regs.int_raw().read();
679
680 if ints.slave_stretch().bit_is_set() {
681 let cause = regs.sr().read().stretch_cause().bits();
682 match cause {
683 0 => {
684 let rw = regs.sr().read().slave_rw().bit_is_set();
685 if rw {
686 regs.int_clr()
687 .write(|w| w.slave_stretch().clear_bit_by_one());
688 return Some(Ok(Command::Read));
689 } else {
690 regs.scl_stretch_conf()
691 .modify(|_, w| w.slave_scl_stretch_clr().set_bit());
692 regs.int_clr()
693 .write(|w| w.slave_stretch().clear_bit_by_one());
694 }
695 }
696 2 => {
697 while regs.sr().read().rxfifo_cnt().bits() > 0 && *bytes_read < buffer.len() {
698 buffer[*bytes_read] = regs.data().read().fifo_rdata().bits();
699 *bytes_read += 1;
700 }
701 regs.scl_stretch_conf()
702 .modify(|_, w| w.slave_scl_stretch_clr().set_bit());
703 regs.int_clr()
704 .write(|w| w.slave_stretch().clear_bit_by_one());
705 }
706 _ => {
707 regs.scl_stretch_conf()
708 .modify(|_, w| w.slave_scl_stretch_clr().set_bit());
709 regs.int_clr()
710 .write(|w| w.slave_stretch().clear_bit_by_one());
711 }
712 }
713 }
714
715 while regs.sr().read().rxfifo_cnt().bits() > 0 && *bytes_read < buffer.len() {
716 buffer[*bytes_read] = regs.data().read().fifo_rdata().bits();
717 *bytes_read += 1;
718 }
719
720 if ints.trans_complete().bit_is_set() {
721 regs.int_clr()
722 .write(|w| w.trans_complete().clear_bit_by_one());
723 return Some(Ok(Command::Write(*bytes_read)));
724 }
725
726 None
727 }
728
729 fn respond_to_read_step(
730 &self,
731 buffer: &[u8],
732 bytes_written: &mut usize,
733 ) -> Option<Result<ReadStatus, Error>> {
734 let regs = self.regs();
735 let ints = regs.int_raw().read();
736
737 if ints.trans_complete().bit_is_set() || ints.nack().bit_is_set() {
738 let is_nack = ints.nack().bit_is_set();
739 regs.int_clr().write(|w| {
740 w.trans_complete().clear_bit_by_one();
741 w.nack().clear_bit_by_one()
742 });
743 if is_nack {
744 self.reset_fifo();
745 self.reset_fsm();
746 }
747
748 if *bytes_written > buffer.len() {
749 return Some(Ok(ReadStatus::NeedMoreBytes));
750 } else if *bytes_written < buffer.len() {
751 let rem = (buffer.len() - *bytes_written) as u16;
752 return Some(Ok(ReadStatus::LeftoverBytes(rem)));
753 } else {
754 return Some(Ok(ReadStatus::Done));
755 }
756 }
757
758 if ints.slave_stretch().bit_is_set() {
759 let cause = regs.sr().read().stretch_cause().bits();
760 if cause == 1 {
761 if *bytes_written < buffer.len() {
762 let txfifo_cnt = regs.sr().read().txfifo_cnt().bits() as usize;
763 let free = FIFO_SIZE - txfifo_cnt;
764 let to_write = core::cmp::min(buffer.len() - *bytes_written, free);
765 for i in 0..to_write {
766 regs.data()
767 .write(|w| unsafe { w.fifo_rdata().bits(buffer[*bytes_written + i]) });
768 }
769 *bytes_written += to_write;
770
771 regs.scl_stretch_conf()
772 .modify(|_, w| w.slave_scl_stretch_clr().set_bit());
773 regs.int_clr()
774 .write(|w| w.slave_stretch().clear_bit_by_one());
775 self.update_registers();
776 } else {
777 regs.data().write(|w| unsafe { w.fifo_rdata().bits(0xFF) });
778 *bytes_written += 1;
779 regs.scl_stretch_conf()
780 .modify(|_, w| w.slave_scl_stretch_clr().set_bit());
781 regs.int_clr()
782 .write(|w| w.slave_stretch().clear_bit_by_one());
783 self.update_registers();
784 }
785 } else {
786 regs.scl_stretch_conf()
787 .modify(|_, w| w.slave_scl_stretch_clr().set_bit());
788 regs.int_clr()
789 .write(|w| w.slave_stretch().clear_bit_by_one());
790 self.update_registers();
791 }
792 }
793
794 None
795 }
796}
797
798#[cfg(i2c_slave_i2c0)]
799impl crate::i2c::slave::Instance for crate::peripherals::I2C0<'_> {
800 fn parts(&self) -> (&Info, &State) {
801 #[handler]
802 #[ram]
803 pub(super) fn irq_handler() {
804 async_handler(&PERIPHERAL, &STATE);
805 }
806
807 static STATE: State = State {
808 waker: AtomicWaker::new(),
809 };
810
811 static PERIPHERAL: Info = Info {
812 register_block: crate::peripherals::I2C0::ptr(),
813 peripheral: crate::system::Peripheral::I2cExt0,
814 async_handler: irq_handler,
815 scl_output: OutputSignal::I2CEXT0_SCL,
816 scl_input: InputSignal::I2CEXT0_SCL,
817 sda_output: OutputSignal::I2CEXT0_SDA,
818 sda_input: InputSignal::I2CEXT0_SDA,
819 };
820 (&PERIPHERAL, &STATE)
821 }
822}
823
824#[cfg(i2c_slave_i2c1)]
825impl crate::i2c::slave::Instance for crate::peripherals::I2C1<'_> {
826 fn parts(&self) -> (&Info, &State) {
827 #[handler]
828 #[ram]
829 pub(super) fn irq_handler() {
830 async_handler(&PERIPHERAL, &STATE);
831 }
832
833 static STATE: State = State {
834 waker: AtomicWaker::new(),
835 };
836
837 static PERIPHERAL: Info = Info {
838 register_block: crate::peripherals::I2C1::ptr(),
839 peripheral: crate::system::Peripheral::I2cExt1,
840 async_handler: irq_handler,
841 scl_output: OutputSignal::I2CEXT1_SCL,
842 scl_input: InputSignal::I2CEXT1_SCL,
843 sda_output: OutputSignal::I2CEXT1_SDA,
844 sda_input: InputSignal::I2CEXT1_SDA,
845 };
846 (&PERIPHERAL, &STATE)
847 }
848}
849
850crate::any_peripheral! {
851 pub peripheral AnyI2c<'d> {
853 #[cfg(i2c_slave_i2c0)]
854 I2c0(crate::peripherals::I2C0<'d>),
855 #[cfg(i2c_slave_i2c1)]
856 I2c1(crate::peripherals::I2C1<'d>),
857 }
858}
859
860impl crate::i2c::slave::Instance for AnyI2c<'_> {
861 fn parts(&self) -> (&Info, &State) {
862 any::delegate!(self, i2c => { crate::i2c::slave::Instance::parts(i2c) })
863 }
864}
865
866impl AnyI2c<'_> {
867 fn bind_peri_interrupt(&self, handler: InterruptHandler) {
868 any::delegate!(self, i2c => { i2c.bind_peri_interrupt(handler) })
869 }
870
871 fn disable_peri_interrupt(&self) {
872 any::delegate!(self, i2c => { i2c.disable_peri_interrupt() })
873 }
874
875 fn enable_peri_interrupt(&self, priority: crate::interrupt::Priority) {
876 any::delegate!(self, i2c => { i2c.enable_peri_interrupt(priority) })
877 }
878
879 fn set_interrupt_handler(&self, handler: InterruptHandler) {
880 self.disable_peri_interrupt();
881
882 self.info().regs().int_ena().write(|w| unsafe { w.bits(0) });
883 self.info()
884 .regs()
885 .int_clr()
886 .write(|w| unsafe { w.bits(0x3fff) });
887
888 self.bind_peri_interrupt(handler);
889 self.enable_peri_interrupt(handler.priority());
890 }
891}