embassy_nrf/
twis.rs

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