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