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