embassy_nrf/
twim.rs

1//! I2C-compatible Two Wire Interface in master mode (TWIM) driver.
2
3#![macro_use]
4
5use core::future::poll_fn;
6use core::marker::PhantomData;
7use core::sync::atomic::Ordering::SeqCst;
8use core::sync::atomic::compiler_fence;
9use core::task::Poll;
10
11use embassy_embedded_hal::SetConfig;
12use embassy_hal_internal::{Peri, PeripheralType};
13use embassy_sync::waitqueue::AtomicWaker;
14#[cfg(feature = "time")]
15use embassy_time::{Duration, Instant};
16use embedded_hal_1::i2c::Operation;
17pub use pac::twim::vals::Frequency;
18
19use crate::chip::EASY_DMA_SIZE;
20use crate::gpio::Pin as GpioPin;
21use crate::interrupt::typelevel::Interrupt;
22use crate::pac::gpio::vals as gpiovals;
23use crate::pac::twim::vals;
24use crate::util::slice_in_ram;
25use crate::{gpio, interrupt, pac};
26
27/// TWIM config.
28#[non_exhaustive]
29pub struct Config {
30    /// Frequency
31    pub frequency: Frequency,
32
33    /// Enable high drive for the SDA line.
34    pub sda_high_drive: bool,
35
36    /// Enable internal pullup for the SDA line.
37    ///
38    /// Note that using external pullups is recommended for I2C, and
39    /// most boards already have them.
40    pub sda_pullup: bool,
41
42    /// Enable high drive for the SCL line.
43    pub scl_high_drive: bool,
44
45    /// Enable internal pullup for the SCL line.
46    ///
47    /// Note that using external pullups is recommended for I2C, and
48    /// most boards already have them.
49    pub scl_pullup: bool,
50}
51
52impl Default for Config {
53    fn default() -> Self {
54        Self {
55            frequency: Frequency::K100,
56            scl_high_drive: false,
57            sda_pullup: false,
58            sda_high_drive: false,
59            scl_pullup: false,
60        }
61    }
62}
63
64/// TWI error.
65#[derive(Debug, Copy, Clone, Eq, PartialEq)]
66#[cfg_attr(feature = "defmt", derive(defmt::Format))]
67#[non_exhaustive]
68pub enum Error {
69    /// TX buffer was too long.
70    TxBufferTooLong,
71    /// RX buffer was too long.
72    RxBufferTooLong,
73    /// Data transmit failed.
74    Transmit,
75    /// Data reception failed.
76    Receive,
77    /// The buffer is not in data RAM and is larger than the RAM buffer. It's most likely in flash, and nRF's DMA cannot access flash.
78    RAMBufferTooSmall,
79    /// Didn't receive an ACK bit after the address byte. Address might be wrong, or the i2c device chip might not be connected properly.
80    AddressNack,
81    /// Didn't receive an ACK bit after a data byte.
82    DataNack,
83    /// Overrun error.
84    Overrun,
85    /// Timeout error.
86    Timeout,
87}
88
89/// Interrupt handler.
90pub struct InterruptHandler<T: Instance> {
91    _phantom: PhantomData<T>,
92}
93
94impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandler<T> {
95    unsafe fn on_interrupt() {
96        let r = T::regs();
97        let s = T::state();
98
99        if r.events_suspended().read() != 0 {
100            s.end_waker.wake();
101            r.intenclr().write(|w| w.set_suspended(true));
102        }
103        if r.events_stopped().read() != 0 {
104            s.end_waker.wake();
105            r.intenclr().write(|w| w.set_stopped(true));
106        }
107        if r.events_error().read() != 0 {
108            s.end_waker.wake();
109            r.intenclr().write(|w| w.set_error(true));
110        }
111    }
112}
113
114/// TWI driver.
115pub struct Twim<'d> {
116    r: pac::twim::Twim,
117    state: &'static State,
118    tx_ram_buffer: &'d mut [u8],
119    _p: PhantomData<&'d ()>,
120}
121
122impl<'d> Twim<'d> {
123    /// Create a new TWI driver.
124    ///
125    /// `tx_ram_buffer` is required if any write operations will be performed with data that is not in RAM.
126    /// Usually this is static data that the compiler locates in flash instead of RAM. The `tx_ram_buffer`
127    /// needs to be at least as large as the largest write operation that will be executed with a buffer
128    /// that is not in RAM. If all write operations will be performed from RAM, an empty buffer (`&[]`) may
129    /// be used.
130    pub fn new<T: Instance>(
131        _twim: Peri<'d, T>,
132        _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
133        sda: Peri<'d, impl GpioPin>,
134        scl: Peri<'d, impl GpioPin>,
135        config: Config,
136        tx_ram_buffer: &'d mut [u8],
137    ) -> Self {
138        let r = T::regs();
139
140        // Configure pins
141        sda.conf().write(|w| {
142            w.set_dir(gpiovals::Dir::OUTPUT);
143            w.set_input(gpiovals::Input::CONNECT);
144            #[cfg(not(feature = "_nrf54l"))]
145            w.set_drive(match config.sda_high_drive {
146                true => gpiovals::Drive::H0D1,
147                false => gpiovals::Drive::S0D1,
148            });
149            #[cfg(feature = "_nrf54l")]
150            {
151                w.set_drive0(match config.sda_high_drive {
152                    true => gpiovals::Drive::H,
153                    false => gpiovals::Drive::S,
154                });
155                w.set_drive1(gpiovals::Drive::D);
156            }
157            if config.sda_pullup {
158                w.set_pull(gpiovals::Pull::PULLUP);
159            }
160        });
161        scl.conf().write(|w| {
162            w.set_dir(gpiovals::Dir::OUTPUT);
163            w.set_input(gpiovals::Input::CONNECT);
164            #[cfg(not(feature = "_nrf54l"))]
165            w.set_drive(match config.scl_high_drive {
166                true => gpiovals::Drive::H0D1,
167                false => gpiovals::Drive::S0D1,
168            });
169            #[cfg(feature = "_nrf54l")]
170            {
171                w.set_drive0(match config.scl_high_drive {
172                    true => gpiovals::Drive::H,
173                    false => gpiovals::Drive::S,
174                });
175                w.set_drive1(gpiovals::Drive::D);
176            }
177            if config.scl_pullup {
178                w.set_pull(gpiovals::Pull::PULLUP);
179            }
180        });
181
182        // Select pins.
183        r.psel().sda().write_value(sda.psel_bits());
184        r.psel().scl().write_value(scl.psel_bits());
185
186        // Enable TWIM instance.
187        r.enable().write(|w| w.set_enable(vals::Enable::ENABLED));
188
189        let mut twim = Self {
190            r: T::regs(),
191            state: T::state(),
192            tx_ram_buffer,
193            _p: PhantomData {},
194        };
195
196        // Apply runtime peripheral configuration
197        Self::set_config(&mut twim, &config).unwrap();
198
199        // Disable all events interrupts
200        r.intenclr().write(|w| w.0 = 0xFFFF_FFFF);
201
202        T::Interrupt::unpend();
203        unsafe { T::Interrupt::enable() };
204
205        twim
206    }
207
208    /// Set TX buffer, checking that it is in RAM and has suitable length.
209    unsafe fn set_tx_buffer(&mut self, buffer: &[u8]) -> Result<(), Error> {
210        let buffer = if slice_in_ram(buffer) {
211            buffer
212        } else {
213            if buffer.len() > self.tx_ram_buffer.len() {
214                return Err(Error::RAMBufferTooSmall);
215            }
216            trace!("Copying TWIM tx buffer into RAM for DMA");
217            let ram_buffer = &mut self.tx_ram_buffer[..buffer.len()];
218            ram_buffer.copy_from_slice(buffer);
219            &*ram_buffer
220        };
221
222        if buffer.len() > EASY_DMA_SIZE {
223            return Err(Error::TxBufferTooLong);
224        }
225
226        let r = self.r;
227
228        // We're giving the register a pointer to the stack. Since we're
229        // waiting for the I2C transaction to end before this stack pointer
230        // becomes invalid, there's nothing wrong here.
231        r.dma().tx().ptr().write_value(buffer.as_ptr() as u32);
232        r.dma().tx().maxcnt().write(|w|
233            // We're giving it the length of the buffer, so no danger of
234            // accessing invalid memory. We have verified that the length of the
235            // buffer fits in an `u8`, so the cast to `u8` is also fine.
236            //
237            // The MAXCNT field is 8 bits wide and accepts the full range of
238            // values.
239            w.set_maxcnt(buffer.len() as _));
240
241        Ok(())
242    }
243
244    /// Set RX buffer, checking that it has suitable length.
245    unsafe fn set_rx_buffer(&mut self, buffer: &mut [u8]) -> Result<(), Error> {
246        // NOTE: RAM slice check is not necessary, as a mutable
247        // slice can only be built from data located in RAM.
248
249        if buffer.len() > EASY_DMA_SIZE {
250            return Err(Error::RxBufferTooLong);
251        }
252
253        let r = self.r;
254
255        // We're giving the register a pointer to the stack. Since we're
256        // waiting for the I2C transaction to end before this stack pointer
257        // becomes invalid, there's nothing wrong here.
258        r.dma().rx().ptr().write_value(buffer.as_mut_ptr() as u32);
259        r.dma().rx().maxcnt().write(|w|
260            // We're giving it the length of the buffer, so no danger of
261            // accessing invalid memory. We have verified that the length of the
262            // buffer fits in an `u8`, so the cast to the type of maxcnt
263            // is also fine.
264            //
265            // Note that that nrf52840 maxcnt is a wider
266            // type than a u8, so we use a `_` cast rather than a `u8` cast.
267            // The MAXCNT field is thus at least 8 bits wide and accepts the
268            // full range of values that fit in a `u8`.
269            w.set_maxcnt(buffer.len() as _));
270
271        Ok(())
272    }
273
274    fn clear_errorsrc(&mut self) {
275        let r = self.r;
276        r.errorsrc().write(|w| {
277            w.set_anack(true);
278            w.set_dnack(true);
279            w.set_overrun(true);
280        });
281    }
282
283    /// Get Error instance, if any occurred.
284    fn check_errorsrc(&mut self) -> Result<(), Error> {
285        let r = self.r;
286
287        let err = r.errorsrc().read();
288        if err.anack() {
289            return Err(Error::AddressNack);
290        }
291        if err.dnack() {
292            return Err(Error::DataNack);
293        }
294        if err.overrun() {
295            return Err(Error::Overrun);
296        }
297        Ok(())
298    }
299
300    fn check_rx(&self, len: usize) -> Result<(), Error> {
301        let r = self.r;
302        if r.dma().rx().amount().read().0 != len as u32 {
303            Err(Error::Receive)
304        } else {
305            Ok(())
306        }
307    }
308
309    fn check_tx(&self, len: usize) -> Result<(), Error> {
310        let r = self.r;
311        if r.dma().tx().amount().read().0 != len as u32 {
312            Err(Error::Transmit)
313        } else {
314            Ok(())
315        }
316    }
317
318    /// Wait for stop or error
319    fn blocking_wait(&mut self) {
320        let r = self.r;
321        loop {
322            if r.events_suspended().read() != 0 || r.events_stopped().read() != 0 {
323                r.events_suspended().write_value(0);
324                r.events_stopped().write_value(0);
325                break;
326            }
327            if r.events_error().read() != 0 {
328                r.events_error().write_value(0);
329                r.tasks_stop().write_value(1);
330            }
331        }
332    }
333
334    /// Wait for stop or error
335    #[cfg(feature = "time")]
336    fn blocking_wait_timeout(&mut self, timeout: Duration) -> Result<(), Error> {
337        let r = self.r;
338        let deadline = Instant::now() + timeout;
339        loop {
340            if r.events_suspended().read() != 0 || r.events_stopped().read() != 0 {
341                r.events_stopped().write_value(0);
342                break;
343            }
344            if r.events_error().read() != 0 {
345                r.events_error().write_value(0);
346                r.tasks_stop().write_value(1);
347            }
348            if Instant::now() > deadline {
349                r.tasks_stop().write_value(1);
350                return Err(Error::Timeout);
351            }
352        }
353
354        Ok(())
355    }
356
357    /// Wait for stop or error
358    async fn async_wait(&mut self) -> Result<(), Error> {
359        poll_fn(|cx| {
360            let r = self.r;
361            let s = self.state;
362
363            s.end_waker.register(cx.waker());
364            if r.events_suspended().read() != 0 || r.events_stopped().read() != 0 {
365                r.events_stopped().write_value(0);
366
367                return Poll::Ready(Ok(()));
368            }
369
370            // stop if an error occurred
371            if r.events_error().read() != 0 {
372                r.events_error().write_value(0);
373                r.tasks_stop().write_value(1);
374                if let Err(e) = self.check_errorsrc() {
375                    return Poll::Ready(Err(e));
376                } else {
377                    return Poll::Ready(Err(Error::Timeout));
378                }
379            }
380
381            Poll::Pending
382        })
383        .await
384    }
385
386    fn setup_operations(
387        &mut self,
388        address: u8,
389        operations: &mut [Operation<'_>],
390        last_op: Option<&Operation<'_>>,
391        inten: bool,
392    ) -> Result<usize, Error> {
393        let r = self.r;
394
395        compiler_fence(SeqCst);
396
397        r.address().write(|w| w.set_address(address));
398
399        r.events_suspended().write_value(0);
400        r.events_stopped().write_value(0);
401        r.events_error().write_value(0);
402        self.clear_errorsrc();
403
404        if inten {
405            r.intenset().write(|w| {
406                w.set_suspended(true);
407                w.set_stopped(true);
408                w.set_error(true);
409            });
410        } else {
411            r.intenclr().write(|w| {
412                w.set_suspended(true);
413                w.set_stopped(true);
414                w.set_error(true);
415            });
416        }
417
418        assert!(!operations.is_empty());
419        match operations {
420            [Operation::Read(_), Operation::Read(_), ..] => {
421                panic!("Consecutive read operations are not supported!")
422            }
423            [Operation::Read(rd_buffer), Operation::Write(wr_buffer), rest @ ..] => {
424                let stop = rest.is_empty();
425
426                // Set up DMA buffers.
427                unsafe {
428                    self.set_tx_buffer(wr_buffer)?;
429                    self.set_rx_buffer(rd_buffer)?;
430                }
431
432                r.shorts().write(|w| {
433                    w.set_lastrx_dma_tx_start(true);
434                    if stop {
435                        w.set_lasttx_stop(true);
436                    } else {
437                        w.set_lasttx_suspend(true);
438                    }
439                });
440
441                // Start read+write operation.
442                r.tasks_dma().rx().start().write_value(1);
443                if last_op.is_some() {
444                    r.tasks_resume().write_value(1);
445                }
446
447                // TODO: Handle empty write buffer
448                if rd_buffer.is_empty() {
449                    // With a zero-length buffer, LASTRX doesn't fire (because there's no last byte!), so do the STARTTX ourselves.
450                    r.tasks_dma().tx().start().write_value(1);
451                }
452
453                Ok(2)
454            }
455            [Operation::Read(buffer)] => {
456                // Set up DMA buffers.
457                unsafe {
458                    self.set_rx_buffer(buffer)?;
459                }
460
461                r.shorts().write(|w| w.set_lastrx_stop(true));
462
463                // Start read operation.
464                r.tasks_dma().rx().start().write_value(1);
465                if last_op.is_some() {
466                    r.tasks_resume().write_value(1);
467                }
468
469                if buffer.is_empty() {
470                    // With a zero-length buffer, LASTRX doesn't fire (because there's no last byte!), so do the STOP ourselves.
471                    r.tasks_stop().write_value(1);
472                }
473
474                Ok(1)
475            }
476            [Operation::Write(wr_buffer), Operation::Read(rd_buffer)]
477                if !wr_buffer.is_empty() && !rd_buffer.is_empty() =>
478            {
479                // Set up DMA buffers.
480                unsafe {
481                    self.set_tx_buffer(wr_buffer)?;
482                    self.set_rx_buffer(rd_buffer)?;
483                }
484
485                // Start write+read operation.
486                r.shorts().write(|w| {
487                    w.set_lasttx_dma_rx_start(true);
488                    w.set_lastrx_stop(true);
489                });
490
491                r.tasks_dma().tx().start().write_value(1);
492                if last_op.is_some() {
493                    r.tasks_resume().write_value(1);
494                }
495
496                Ok(2)
497            }
498            [Operation::Write(buffer), rest @ ..] => {
499                let stop = rest.is_empty();
500
501                // Set up DMA buffers.
502                unsafe {
503                    self.set_tx_buffer(buffer)?;
504                }
505
506                // Start write operation.
507                r.shorts().write(|w| {
508                    if stop {
509                        w.set_lasttx_stop(true);
510                    } else {
511                        w.set_lasttx_suspend(true);
512                    }
513                });
514
515                r.tasks_dma().tx().start().write_value(1);
516                if last_op.is_some() {
517                    r.tasks_resume().write_value(1);
518                }
519
520                if buffer.is_empty() {
521                    // With a zero-length buffer, LASTTX doesn't fire (because there's no last byte!), so do the STOP/SUSPEND ourselves.
522                    if stop {
523                        r.tasks_stop().write_value(1);
524                    } else {
525                        r.tasks_suspend().write_value(1);
526                    }
527                }
528
529                Ok(1)
530            }
531            [] => unreachable!(),
532        }
533    }
534
535    fn check_operations(&mut self, operations: &[Operation<'_>]) -> Result<(), Error> {
536        compiler_fence(SeqCst);
537        self.check_errorsrc()?;
538
539        assert!(operations.len() == 1 || operations.len() == 2);
540        match operations {
541            [Operation::Read(rd_buffer), Operation::Write(wr_buffer)]
542            | [Operation::Write(wr_buffer), Operation::Read(rd_buffer)] => {
543                self.check_rx(rd_buffer.len())?;
544                self.check_tx(wr_buffer.len())?;
545            }
546            [Operation::Read(buffer)] => {
547                self.check_rx(buffer.len())?;
548            }
549            [Operation::Write(buffer), ..] => {
550                self.check_tx(buffer.len())?;
551            }
552            _ => unreachable!(),
553        }
554        Ok(())
555    }
556
557    // ===========================================
558
559    /// Execute the provided operations on the I2C bus.
560    ///
561    /// Each buffer must have a length of at most 255 bytes on the nRF52832
562    /// and at most 65535 bytes on the nRF52840.
563    ///
564    /// Consecutive `Operation::Read`s are not supported due to hardware
565    /// limitations.
566    ///
567    /// An `Operation::Write` following an `Operation::Read` must have a
568    /// non-empty buffer.
569    pub fn blocking_transaction(&mut self, address: u8, mut operations: &mut [Operation<'_>]) -> Result<(), Error> {
570        let mut last_op = None;
571        while !operations.is_empty() {
572            let ops = self.setup_operations(address, operations, last_op, false)?;
573            let (in_progress, rest) = operations.split_at_mut(ops);
574            self.blocking_wait();
575            self.check_operations(in_progress)?;
576            last_op = in_progress.last();
577            operations = rest;
578        }
579        Ok(())
580    }
581
582    /// Execute the provided operations on the I2C bus with timeout.
583    ///
584    /// See [Self::blocking_transaction].
585    #[cfg(feature = "time")]
586    pub fn blocking_transaction_timeout(
587        &mut self,
588        address: u8,
589        mut operations: &mut [Operation<'_>],
590        timeout: Duration,
591    ) -> Result<(), Error> {
592        let mut last_op = None;
593        while !operations.is_empty() {
594            let ops = self.setup_operations(address, operations, last_op, false)?;
595            let (in_progress, rest) = operations.split_at_mut(ops);
596            self.blocking_wait_timeout(timeout)?;
597            self.check_operations(in_progress)?;
598            last_op = in_progress.last();
599            operations = rest;
600        }
601        Ok(())
602    }
603
604    /// Execute the provided operations on the I2C bus.
605    ///
606    /// Each buffer must have a length of at most 255 bytes on the nRF52832
607    /// and at most 65535 bytes on the nRF52840.
608    ///
609    /// Consecutive `Operation::Read`s are not supported due to hardware
610    /// limitations.
611    ///
612    /// An `Operation::Write` following an `Operation::Read` must have a
613    /// non-empty buffer.
614    pub async fn transaction(&mut self, address: u8, mut operations: &mut [Operation<'_>]) -> Result<(), Error> {
615        let mut last_op = None;
616        while !operations.is_empty() {
617            let ops = self.setup_operations(address, operations, last_op, true)?;
618            let (in_progress, rest) = operations.split_at_mut(ops);
619            self.async_wait().await?;
620            self.check_operations(in_progress)?;
621            last_op = in_progress.last();
622            operations = rest;
623        }
624        Ok(())
625    }
626
627    // ===========================================
628
629    /// Write to an I2C slave.
630    ///
631    /// The buffer must have a length of at most 255 bytes on the nRF52832
632    /// and at most 65535 bytes on the nRF52840.
633    pub fn blocking_write(&mut self, address: u8, buffer: &[u8]) -> Result<(), Error> {
634        self.blocking_transaction(address, &mut [Operation::Write(buffer)])
635    }
636
637    /// Read from an I2C slave.
638    ///
639    /// The buffer must have a length of at most 255 bytes on the nRF52832
640    /// and at most 65535 bytes on the nRF52840.
641    pub fn blocking_read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Error> {
642        self.blocking_transaction(address, &mut [Operation::Read(buffer)])
643    }
644
645    /// Write data to an I2C slave, then read data from the slave without
646    /// triggering a stop condition between the two.
647    ///
648    /// The buffers must have a length of at most 255 bytes on the nRF52832
649    /// and at most 65535 bytes on the nRF52840.
650    pub fn blocking_write_read(&mut self, address: u8, wr_buffer: &[u8], rd_buffer: &mut [u8]) -> Result<(), Error> {
651        self.blocking_transaction(address, &mut [Operation::Write(wr_buffer), Operation::Read(rd_buffer)])
652    }
653
654    // ===========================================
655
656    /// Write to an I2C slave with timeout.
657    ///
658    /// See [Self::blocking_write].
659    #[cfg(feature = "time")]
660    pub fn blocking_write_timeout(&mut self, address: u8, buffer: &[u8], timeout: Duration) -> Result<(), Error> {
661        self.blocking_transaction_timeout(address, &mut [Operation::Write(buffer)], timeout)
662    }
663
664    /// Read from an I2C slave.
665    ///
666    /// The buffer must have a length of at most 255 bytes on the nRF52832
667    /// and at most 65535 bytes on the nRF52840.
668    #[cfg(feature = "time")]
669    pub fn blocking_read_timeout(&mut self, address: u8, buffer: &mut [u8], timeout: Duration) -> Result<(), Error> {
670        self.blocking_transaction_timeout(address, &mut [Operation::Read(buffer)], timeout)
671    }
672
673    /// Write data to an I2C slave, then read data from the slave without
674    /// triggering a stop condition between the two.
675    ///
676    /// The buffers must have a length of at most 255 bytes on the nRF52832
677    /// and at most 65535 bytes on the nRF52840.
678    #[cfg(feature = "time")]
679    pub fn blocking_write_read_timeout(
680        &mut self,
681        address: u8,
682        wr_buffer: &[u8],
683        rd_buffer: &mut [u8],
684        timeout: Duration,
685    ) -> Result<(), Error> {
686        self.blocking_transaction_timeout(
687            address,
688            &mut [Operation::Write(wr_buffer), Operation::Read(rd_buffer)],
689            timeout,
690        )
691    }
692
693    // ===========================================
694
695    /// Read from an I2C slave.
696    ///
697    /// The buffer must have a length of at most 255 bytes on the nRF52832
698    /// and at most 65535 bytes on the nRF52840.
699    pub async fn read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Error> {
700        self.transaction(address, &mut [Operation::Read(buffer)]).await
701    }
702
703    /// Write to an I2C slave.
704    ///
705    /// The buffer must have a length of at most 255 bytes on the nRF52832
706    /// and at most 65535 bytes on the nRF52840.
707    pub async fn write(&mut self, address: u8, buffer: &[u8]) -> Result<(), Error> {
708        self.transaction(address, &mut [Operation::Write(buffer)]).await
709    }
710
711    /// Write data to an I2C slave, then read data from the slave without
712    /// triggering a stop condition between the two.
713    ///
714    /// The buffers must have a length of at most 255 bytes on the nRF52832
715    /// and at most 65535 bytes on the nRF52840.
716    pub async fn write_read(&mut self, address: u8, wr_buffer: &[u8], rd_buffer: &mut [u8]) -> Result<(), Error> {
717        self.transaction(address, &mut [Operation::Write(wr_buffer), Operation::Read(rd_buffer)])
718            .await
719    }
720}
721
722impl<'a> Drop for Twim<'a> {
723    fn drop(&mut self) {
724        trace!("twim drop");
725
726        // TODO: check for abort
727
728        // disable!
729        let r = self.r;
730        r.enable().write(|w| w.set_enable(vals::Enable::DISABLED));
731
732        gpio::deconfigure_pin(r.psel().sda().read());
733        gpio::deconfigure_pin(r.psel().scl().read());
734
735        trace!("twim drop: done");
736    }
737}
738
739pub(crate) struct State {
740    end_waker: AtomicWaker,
741}
742
743impl State {
744    pub(crate) const fn new() -> Self {
745        Self {
746            end_waker: AtomicWaker::new(),
747        }
748    }
749}
750
751pub(crate) trait SealedInstance {
752    fn regs() -> pac::twim::Twim;
753    fn state() -> &'static State;
754}
755
756/// TWIM peripheral instance.
757#[allow(private_bounds)]
758pub trait Instance: SealedInstance + PeripheralType + 'static {
759    /// Interrupt for this peripheral.
760    type Interrupt: interrupt::typelevel::Interrupt;
761}
762
763macro_rules! impl_twim {
764    ($type:ident, $pac_type:ident, $irq:ident) => {
765        impl crate::twim::SealedInstance for peripherals::$type {
766            fn regs() -> pac::twim::Twim {
767                pac::$pac_type
768            }
769            fn state() -> &'static crate::twim::State {
770                static STATE: crate::twim::State = crate::twim::State::new();
771                &STATE
772            }
773        }
774        impl crate::twim::Instance for peripherals::$type {
775            type Interrupt = crate::interrupt::typelevel::$irq;
776        }
777    };
778}
779
780// ====================
781
782mod eh02 {
783    use super::*;
784
785    impl<'a> embedded_hal_02::blocking::i2c::Write for Twim<'a> {
786        type Error = Error;
787
788        fn write(&mut self, addr: u8, bytes: &[u8]) -> Result<(), Error> {
789            self.blocking_write(addr, bytes)
790        }
791    }
792
793    impl<'a> embedded_hal_02::blocking::i2c::Read for Twim<'a> {
794        type Error = Error;
795
796        fn read(&mut self, addr: u8, bytes: &mut [u8]) -> Result<(), Error> {
797            self.blocking_read(addr, bytes)
798        }
799    }
800
801    impl<'a> embedded_hal_02::blocking::i2c::WriteRead for Twim<'a> {
802        type Error = Error;
803
804        fn write_read<'w>(&mut self, addr: u8, bytes: &'w [u8], buffer: &'w mut [u8]) -> Result<(), Error> {
805            self.blocking_write_read(addr, bytes, buffer)
806        }
807    }
808}
809
810impl embedded_hal_1::i2c::Error for Error {
811    fn kind(&self) -> embedded_hal_1::i2c::ErrorKind {
812        match *self {
813            Self::TxBufferTooLong => embedded_hal_1::i2c::ErrorKind::Other,
814            Self::RxBufferTooLong => embedded_hal_1::i2c::ErrorKind::Other,
815            Self::Transmit => embedded_hal_1::i2c::ErrorKind::Other,
816            Self::Receive => embedded_hal_1::i2c::ErrorKind::Other,
817            Self::RAMBufferTooSmall => embedded_hal_1::i2c::ErrorKind::Other,
818            Self::AddressNack => {
819                embedded_hal_1::i2c::ErrorKind::NoAcknowledge(embedded_hal_1::i2c::NoAcknowledgeSource::Address)
820            }
821            Self::DataNack => {
822                embedded_hal_1::i2c::ErrorKind::NoAcknowledge(embedded_hal_1::i2c::NoAcknowledgeSource::Data)
823            }
824            Self::Overrun => embedded_hal_1::i2c::ErrorKind::Overrun,
825            Self::Timeout => embedded_hal_1::i2c::ErrorKind::Other,
826        }
827    }
828}
829
830impl<'d> embedded_hal_1::i2c::ErrorType for Twim<'d> {
831    type Error = Error;
832}
833
834impl<'d> embedded_hal_1::i2c::I2c for Twim<'d> {
835    fn transaction(&mut self, address: u8, operations: &mut [Operation<'_>]) -> Result<(), Self::Error> {
836        self.blocking_transaction(address, operations)
837    }
838}
839
840impl<'d> embedded_hal_async::i2c::I2c for Twim<'d> {
841    async fn transaction(&mut self, address: u8, operations: &mut [Operation<'_>]) -> Result<(), Self::Error> {
842        self.transaction(address, operations).await
843    }
844}
845
846impl<'d> SetConfig for Twim<'d> {
847    type Config = Config;
848    type ConfigError = ();
849    fn set_config(&mut self, config: &Self::Config) -> Result<(), Self::ConfigError> {
850        let r = self.r;
851        r.frequency().write(|w| w.set_frequency(config.frequency));
852
853        Ok(())
854    }
855}