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