embassy_nrf/
twis.rs

1//! I2C-compatible Two Wire Interface in slave 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_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            w.set_drive(match config.sda_high_drive {
165                true => gpiovals::Drive::H0D1,
166                false => gpiovals::Drive::S0D1,
167            });
168            if config.sda_pullup {
169                w.set_pull(gpiovals::Pull::PULLUP);
170            }
171        });
172        scl.conf().write(|w| {
173            w.set_dir(gpiovals::Dir::INPUT);
174            w.set_input(gpiovals::Input::CONNECT);
175            w.set_drive(match config.scl_high_drive {
176                true => gpiovals::Drive::H0D1,
177                false => gpiovals::Drive::S0D1,
178            });
179            if config.sda_pullup {
180                w.set_pull(gpiovals::Pull::PULLUP);
181            }
182        });
183
184        // Select pins.
185        r.psel().sda().write_value(sda.psel_bits());
186        r.psel().scl().write_value(scl.psel_bits());
187
188        // Enable TWIS instance.
189        r.enable().write(|w| w.set_enable(vals::Enable::ENABLED));
190
191        // Disable all events interrupts
192        r.intenclr().write(|w| w.0 = 0xFFFF_FFFF);
193
194        // Set address
195        r.address(0).write(|w| w.set_address(config.address0));
196        r.config().write(|w| w.set_address0(true));
197        if let Some(address1) = config.address1 {
198            r.address(1).write(|w| w.set_address(address1));
199            r.config().modify(|w| w.set_address1(true));
200        }
201
202        // Set over-read character
203        r.orc().write(|w| w.set_orc(config.orc));
204
205        // Generate suspend on read event
206        r.shorts().write(|w| w.set_read_suspend(true));
207
208        T::Interrupt::unpend();
209        unsafe { T::Interrupt::enable() };
210
211        Self {
212            r: T::regs(),
213            state: T::state(),
214            _p: PhantomData,
215        }
216    }
217
218    /// Set TX buffer, checking that it is in RAM and has suitable length.
219    unsafe fn set_tx_buffer(&mut self, buffer: &[u8]) -> Result<(), Error> {
220        slice_in_ram_or(buffer, Error::BufferNotInRAM)?;
221
222        if buffer.len() > EASY_DMA_SIZE {
223            return Err(Error::TxBufferTooLong);
224        }
225
226        let r = self.r;
227
228        // We're giving the register a pointer to the stack. Since we're
229        // waiting for the I2C transaction to end before this stack pointer
230        // becomes invalid, there's nothing wrong here.
231        r.txd().ptr().write_value(buffer.as_ptr() as u32);
232        r.txd().maxcnt().write(|w|
233            // We're giving it the length of the buffer, so no danger of
234            // accessing invalid memory. We have verified that the length of the
235            // buffer fits in an `u8`, so the cast to `u8` is also fine.
236            //
237            // The MAXCNT field is 8 bits wide and accepts the full range of
238            // values.
239            w.set_maxcnt(buffer.len() as _));
240
241        Ok(())
242    }
243
244    /// Set RX buffer, checking that it has suitable length.
245    unsafe fn set_rx_buffer(&mut self, buffer: &mut [u8]) -> Result<(), Error> {
246        // NOTE: RAM slice check is not necessary, as a mutable
247        // slice can only be built from data located in RAM.
248
249        if buffer.len() > EASY_DMA_SIZE {
250            return Err(Error::RxBufferTooLong);
251        }
252
253        let r = self.r;
254
255        // We're giving the register a pointer to the stack. Since we're
256        // waiting for the I2C transaction to end before this stack pointer
257        // becomes invalid, there's nothing wrong here.
258        r.rxd().ptr().write_value(buffer.as_mut_ptr() as u32);
259        r.rxd().maxcnt().write(|w|
260            // We're giving it the length of the buffer, so no danger of
261            // accessing invalid memory. We have verified that the length of the
262            // buffer fits in an `u8`, so the cast to the type of maxcnt
263            // is also fine.
264            //
265            // Note that that nrf52840 maxcnt is a wider
266            // type than a u8, so we use a `_` cast rather than a `u8` cast.
267            // The MAXCNT field is thus at least 8 bits wide and accepts the
268            // full range of values that fit in a `u8`.
269            w.set_maxcnt(buffer.len() as _));
270
271        Ok(())
272    }
273
274    fn clear_errorsrc(&mut self) {
275        let r = self.r;
276        r.errorsrc().write(|w| {
277            w.set_overflow(true);
278            w.set_overread(true);
279            w.set_dnack(true);
280        });
281    }
282
283    /// Returns matched address for latest command.
284    pub fn address_match(&self) -> u8 {
285        let r = self.r;
286        r.address(r.match_().read().0 as usize).read().address()
287    }
288
289    /// Returns the index of the address matched in the latest command.
290    pub fn address_match_index(&self) -> usize {
291        self.r.match_().read().0 as _
292    }
293
294    /// Wait for read, write, stop or error
295    fn blocking_listen_wait(&mut self) -> Result<Status, Error> {
296        let r = self.r;
297        loop {
298            if r.events_error().read() != 0 {
299                r.events_error().write_value(0);
300                r.tasks_stop().write_value(1);
301                while r.events_stopped().read() == 0 {}
302                return Err(Error::Overflow);
303            }
304            if r.events_stopped().read() != 0 {
305                r.events_stopped().write_value(0);
306                return Err(Error::Bus);
307            }
308            if r.events_read().read() != 0 {
309                r.events_read().write_value(0);
310                return Ok(Status::Read);
311            }
312            if r.events_write().read() != 0 {
313                r.events_write().write_value(0);
314                return Ok(Status::Write);
315            }
316        }
317    }
318
319    /// Wait for stop, repeated start or error
320    fn blocking_listen_wait_end(&mut self, status: Status) -> Result<Command, Error> {
321        let r = self.r;
322        loop {
323            // stop if an error occurred
324            if r.events_error().read() != 0 {
325                r.events_error().write_value(0);
326                r.tasks_stop().write_value(1);
327                return Err(Error::Overflow);
328            } else if r.events_stopped().read() != 0 {
329                r.events_stopped().write_value(0);
330                return match status {
331                    Status::Read => Ok(Command::Read),
332                    Status::Write => {
333                        let n = r.rxd().amount().read().0 as usize;
334                        Ok(Command::Write(n))
335                    }
336                };
337            } else if r.events_read().read() != 0 {
338                r.events_read().write_value(0);
339                let n = r.rxd().amount().read().0 as usize;
340                return Ok(Command::WriteRead(n));
341            }
342        }
343    }
344
345    /// Wait for stop or error
346    fn blocking_wait(&mut self) -> Result<usize, Error> {
347        let r = self.r;
348        loop {
349            // stop if an error occurred
350            if r.events_error().read() != 0 {
351                r.events_error().write_value(0);
352                r.tasks_stop().write_value(1);
353                let errorsrc = r.errorsrc().read();
354                if errorsrc.overread() {
355                    return Err(Error::OverRead);
356                } else if errorsrc.dnack() {
357                    return Err(Error::DataNack);
358                } else {
359                    return Err(Error::Bus);
360                }
361            } else if r.events_stopped().read() != 0 {
362                r.events_stopped().write_value(0);
363                let n = r.txd().amount().read().0 as usize;
364                return Ok(n);
365            }
366        }
367    }
368
369    /// Wait for stop or error with timeout
370    #[cfg(feature = "time")]
371    fn blocking_wait_timeout(&mut self, timeout: Duration) -> Result<usize, Error> {
372        let r = self.r;
373        let deadline = Instant::now() + timeout;
374        loop {
375            // stop if an error occurred
376            if r.events_error().read() != 0 {
377                r.events_error().write_value(0);
378                r.tasks_stop().write_value(1);
379                let errorsrc = r.errorsrc().read();
380                if errorsrc.overread() {
381                    return Err(Error::OverRead);
382                } else if errorsrc.dnack() {
383                    return Err(Error::DataNack);
384                } else {
385                    return Err(Error::Bus);
386                }
387            } else if r.events_stopped().read() != 0 {
388                r.events_stopped().write_value(0);
389                let n = r.txd().amount().read().0 as usize;
390                return Ok(n);
391            } else if Instant::now() > deadline {
392                r.tasks_stop().write_value(1);
393                return Err(Error::Timeout);
394            }
395        }
396    }
397
398    /// Wait for read, write, stop or error with timeout
399    #[cfg(feature = "time")]
400    fn blocking_listen_wait_timeout(&mut self, timeout: Duration) -> Result<Status, Error> {
401        let r = self.r;
402        let deadline = Instant::now() + timeout;
403        loop {
404            if r.events_error().read() != 0 {
405                r.events_error().write_value(0);
406                r.tasks_stop().write_value(1);
407                while r.events_stopped().read() == 0 {}
408                return Err(Error::Overflow);
409            }
410            if r.events_stopped().read() != 0 {
411                r.events_stopped().write_value(0);
412                return Err(Error::Bus);
413            }
414            if r.events_read().read() != 0 {
415                r.events_read().write_value(0);
416                return Ok(Status::Read);
417            }
418            if r.events_write().read() != 0 {
419                r.events_write().write_value(0);
420                return Ok(Status::Write);
421            }
422            if Instant::now() > deadline {
423                r.tasks_stop().write_value(1);
424                return Err(Error::Timeout);
425            }
426        }
427    }
428
429    /// Wait for stop, repeated start or error with timeout
430    #[cfg(feature = "time")]
431    fn blocking_listen_wait_end_timeout(&mut self, status: Status, timeout: Duration) -> Result<Command, Error> {
432        let r = self.r;
433        let deadline = Instant::now() + timeout;
434        loop {
435            // stop if an error occurred
436            if r.events_error().read() != 0 {
437                r.events_error().write_value(0);
438                r.tasks_stop().write_value(1);
439                return Err(Error::Overflow);
440            } else if r.events_stopped().read() != 0 {
441                r.events_stopped().write_value(0);
442                return match status {
443                    Status::Read => Ok(Command::Read),
444                    Status::Write => {
445                        let n = r.rxd().amount().read().0 as usize;
446                        Ok(Command::Write(n))
447                    }
448                };
449            } else if r.events_read().read() != 0 {
450                r.events_read().write_value(0);
451                let n = r.rxd().amount().read().0 as usize;
452                return Ok(Command::WriteRead(n));
453            } else if Instant::now() > deadline {
454                r.tasks_stop().write_value(1);
455                return Err(Error::Timeout);
456            }
457        }
458    }
459
460    /// Wait for stop or error
461    fn async_wait(&mut self) -> impl Future<Output = Result<usize, Error>> {
462        let r = self.r;
463        let s = self.state;
464        poll_fn(move |cx| {
465            s.waker.register(cx.waker());
466
467            // stop if an error occurred
468            if r.events_error().read() != 0 {
469                r.events_error().write_value(0);
470                r.tasks_stop().write_value(1);
471                let errorsrc = r.errorsrc().read();
472                if errorsrc.overread() {
473                    return Poll::Ready(Err(Error::OverRead));
474                } else if errorsrc.dnack() {
475                    return Poll::Ready(Err(Error::DataNack));
476                } else {
477                    return Poll::Ready(Err(Error::Bus));
478                }
479            } else if r.events_stopped().read() != 0 {
480                r.events_stopped().write_value(0);
481                let n = r.txd().amount().read().0 as usize;
482                return Poll::Ready(Ok(n));
483            }
484
485            Poll::Pending
486        })
487    }
488
489    /// Wait for read or write
490    fn async_listen_wait(&mut self) -> impl Future<Output = Result<Status, Error>> {
491        let r = self.r;
492        let s = self.state;
493        poll_fn(move |cx| {
494            s.waker.register(cx.waker());
495
496            // stop if an error occurred
497            if r.events_error().read() != 0 {
498                r.events_error().write_value(0);
499                r.tasks_stop().write_value(1);
500                return Poll::Ready(Err(Error::Overflow));
501            } else if r.events_read().read() != 0 {
502                r.events_read().write_value(0);
503                return Poll::Ready(Ok(Status::Read));
504            } else if r.events_write().read() != 0 {
505                r.events_write().write_value(0);
506                return Poll::Ready(Ok(Status::Write));
507            } else if r.events_stopped().read() != 0 {
508                r.events_stopped().write_value(0);
509                return Poll::Ready(Err(Error::Bus));
510            }
511            Poll::Pending
512        })
513    }
514
515    /// Wait for stop, repeated start or error
516    fn async_listen_wait_end(&mut self, status: Status) -> impl Future<Output = Result<Command, Error>> {
517        let r = self.r;
518        let s = self.state;
519        poll_fn(move |cx| {
520            s.waker.register(cx.waker());
521
522            // stop if an error occurred
523            if r.events_error().read() != 0 {
524                r.events_error().write_value(0);
525                r.tasks_stop().write_value(1);
526                return Poll::Ready(Err(Error::Overflow));
527            } else if r.events_stopped().read() != 0 {
528                r.events_stopped().write_value(0);
529                return match status {
530                    Status::Read => Poll::Ready(Ok(Command::Read)),
531                    Status::Write => {
532                        let n = r.rxd().amount().read().0 as usize;
533                        Poll::Ready(Ok(Command::Write(n)))
534                    }
535                };
536            } else if r.events_read().read() != 0 {
537                r.events_read().write_value(0);
538                let n = r.rxd().amount().read().0 as usize;
539                return Poll::Ready(Ok(Command::WriteRead(n)));
540            }
541            Poll::Pending
542        })
543    }
544
545    fn setup_respond_from_ram(&mut self, buffer: &[u8], inten: bool) -> Result<(), Error> {
546        let r = self.r;
547
548        compiler_fence(SeqCst);
549
550        // Set up the DMA write.
551        unsafe { self.set_tx_buffer(buffer)? };
552
553        // Clear events
554        r.events_stopped().write_value(0);
555        r.events_error().write_value(0);
556        self.clear_errorsrc();
557
558        if inten {
559            r.intenset().write(|w| {
560                w.set_stopped(true);
561                w.set_error(true);
562            });
563        } else {
564            r.intenclr().write(|w| {
565                w.set_stopped(true);
566                w.set_error(true);
567            });
568        }
569
570        // Start write operation.
571        r.tasks_preparetx().write_value(1);
572        r.tasks_resume().write_value(1);
573        Ok(())
574    }
575
576    fn setup_respond(&mut self, wr_buffer: &[u8], inten: bool) -> Result<(), Error> {
577        match self.setup_respond_from_ram(wr_buffer, inten) {
578            Ok(_) => Ok(()),
579            Err(Error::BufferNotInRAM) => {
580                trace!("Copying TWIS tx buffer into RAM for DMA");
581                let tx_ram_buf = &mut [0; FORCE_COPY_BUFFER_SIZE][..wr_buffer.len()];
582                tx_ram_buf.copy_from_slice(wr_buffer);
583                self.setup_respond_from_ram(tx_ram_buf, inten)
584            }
585            Err(error) => Err(error),
586        }
587    }
588
589    fn setup_listen(&mut self, buffer: &mut [u8], inten: bool) -> Result<(), Error> {
590        let r = self.r;
591        compiler_fence(SeqCst);
592
593        // Set up the DMA read.
594        unsafe { self.set_rx_buffer(buffer)? };
595
596        // Clear events
597        r.events_read().write_value(0);
598        r.events_write().write_value(0);
599        r.events_stopped().write_value(0);
600        r.events_error().write_value(0);
601        self.clear_errorsrc();
602
603        if inten {
604            r.intenset().write(|w| {
605                w.set_stopped(true);
606                w.set_error(true);
607                w.set_read(true);
608                w.set_write(true);
609            });
610        } else {
611            r.intenclr().write(|w| {
612                w.set_stopped(true);
613                w.set_error(true);
614                w.set_read(true);
615                w.set_write(true);
616            });
617        }
618
619        // Start read operation.
620        r.tasks_preparerx().write_value(1);
621
622        Ok(())
623    }
624
625    fn setup_listen_end(&mut self, inten: bool) -> Result<(), Error> {
626        let r = self.r;
627        compiler_fence(SeqCst);
628
629        // Clear events
630        r.events_read().write_value(0);
631        r.events_write().write_value(0);
632        r.events_stopped().write_value(0);
633        r.events_error().write_value(0);
634        self.clear_errorsrc();
635
636        if inten {
637            r.intenset().write(|w| {
638                w.set_stopped(true);
639                w.set_error(true);
640                w.set_read(true);
641            });
642        } else {
643            r.intenclr().write(|w| {
644                w.set_stopped(true);
645                w.set_error(true);
646                w.set_read(true);
647            });
648        }
649
650        Ok(())
651    }
652
653    /// Wait for commands from an I2C master.
654    /// `buffer` is provided in case master does a 'write' and is unused for 'read'.
655    /// The buffer must have a length of at most 255 bytes on the nRF52832
656    /// and at most 65535 bytes on the nRF52840.
657    /// To know which one of the addresses were matched, call `address_match` or `address_match_index`
658    pub fn blocking_listen(&mut self, buffer: &mut [u8]) -> Result<Command, Error> {
659        self.setup_listen(buffer, false)?;
660        let status = self.blocking_listen_wait()?;
661        if status == Status::Write {
662            self.setup_listen_end(false)?;
663            let command = self.blocking_listen_wait_end(status)?;
664            return Ok(command);
665        }
666        Ok(Command::Read)
667    }
668
669    /// Respond to an I2C master READ command.
670    /// Returns the number of bytes written.
671    /// The buffer must have a length of at most 255 bytes on the nRF52832
672    /// and at most 65535 bytes on the nRF52840.
673    pub fn blocking_respond_to_read(&mut self, buffer: &[u8]) -> Result<usize, Error> {
674        self.setup_respond(buffer, false)?;
675        self.blocking_wait()
676    }
677
678    /// Same as [`blocking_respond_to_read`](Twis::blocking_respond_to_read) but will fail instead of copying data into RAM.
679    /// Consult the module level documentation to learn more.
680    pub fn blocking_respond_to_read_from_ram(&mut self, buffer: &[u8]) -> Result<usize, Error> {
681        self.setup_respond_from_ram(buffer, false)?;
682        self.blocking_wait()
683    }
684
685    // ===========================================
686
687    /// Wait for commands from an I2C master, with timeout.
688    /// `buffer` is provided in case master does a 'write' and is unused for 'read'.
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    /// To know which one of the addresses were matched, call `address_match` or `address_match_index`
692    #[cfg(feature = "time")]
693    pub fn blocking_listen_timeout(&mut self, buffer: &mut [u8], timeout: Duration) -> Result<Command, Error> {
694        self.setup_listen(buffer, false)?;
695        let status = self.blocking_listen_wait_timeout(timeout)?;
696        if status == Status::Write {
697            self.setup_listen_end(false)?;
698            let command = self.blocking_listen_wait_end_timeout(status, timeout)?;
699            return Ok(command);
700        }
701        Ok(Command::Read)
702    }
703
704    /// Respond to an I2C master READ command with timeout.
705    /// Returns the number of bytes written.
706    /// See [Self::blocking_respond_to_read].
707    #[cfg(feature = "time")]
708    pub fn blocking_respond_to_read_timeout(&mut self, buffer: &[u8], timeout: Duration) -> Result<usize, Error> {
709        self.setup_respond(buffer, false)?;
710        self.blocking_wait_timeout(timeout)
711    }
712
713    /// Same as [`blocking_respond_to_read_timeout`](Twis::blocking_respond_to_read_timeout) but will fail instead of copying data into RAM.
714    /// Consult the module level documentation to learn more.
715    #[cfg(feature = "time")]
716    pub fn blocking_respond_to_read_from_ram_timeout(
717        &mut self,
718        buffer: &[u8],
719        timeout: Duration,
720    ) -> Result<usize, Error> {
721        self.setup_respond_from_ram(buffer, false)?;
722        self.blocking_wait_timeout(timeout)
723    }
724
725    // ===========================================
726
727    /// Wait asynchronously for commands from an I2C master.
728    /// `buffer` is provided in case master does a 'write' and is unused for 'read'.
729    /// The buffer must have a length of at most 255 bytes on the nRF52832
730    /// and at most 65535 bytes on the nRF52840.
731    /// To know which one of the addresses were matched, call `address_match` or `address_match_index`
732    pub async fn listen(&mut self, buffer: &mut [u8]) -> Result<Command, Error> {
733        self.setup_listen(buffer, true)?;
734        let status = self.async_listen_wait().await?;
735        if status == Status::Write {
736            self.setup_listen_end(true)?;
737            let command = self.async_listen_wait_end(status).await?;
738            return Ok(command);
739        }
740        Ok(Command::Read)
741    }
742
743    /// Respond to an I2C master READ command, asynchronously.
744    /// Returns the number of bytes written.
745    /// The buffer must have a length of at most 255 bytes on the nRF52832
746    /// and at most 65535 bytes on the nRF52840.
747    pub async fn respond_to_read(&mut self, buffer: &[u8]) -> Result<usize, Error> {
748        self.setup_respond(buffer, true)?;
749        self.async_wait().await
750    }
751
752    /// 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.
753    pub async fn respond_to_read_from_ram(&mut self, buffer: &[u8]) -> Result<usize, Error> {
754        self.setup_respond_from_ram(buffer, true)?;
755        self.async_wait().await
756    }
757}
758
759impl<'a> Drop for Twis<'a> {
760    fn drop(&mut self) {
761        trace!("twis drop");
762
763        // TODO: check for abort
764
765        // disable!
766        let r = self.r;
767        r.enable().write(|w| w.set_enable(vals::Enable::DISABLED));
768
769        gpio::deconfigure_pin(r.psel().sda().read());
770        gpio::deconfigure_pin(r.psel().scl().read());
771
772        trace!("twis drop: done");
773    }
774}
775
776pub(crate) struct State {
777    waker: AtomicWaker,
778}
779
780impl State {
781    pub(crate) const fn new() -> Self {
782        Self {
783            waker: AtomicWaker::new(),
784        }
785    }
786}
787
788pub(crate) trait SealedInstance {
789    fn regs() -> pac::twis::Twis;
790    fn state() -> &'static State;
791}
792
793/// TWIS peripheral instance.
794#[allow(private_bounds)]
795pub trait Instance: SealedInstance + PeripheralType + 'static {
796    /// Interrupt for this peripheral.
797    type Interrupt: interrupt::typelevel::Interrupt;
798}
799
800macro_rules! impl_twis {
801    ($type:ident, $pac_type:ident, $irq:ident) => {
802        impl crate::twis::SealedInstance for peripherals::$type {
803            fn regs() -> pac::twis::Twis {
804                pac::$pac_type
805            }
806            fn state() -> &'static crate::twis::State {
807                static STATE: crate::twis::State = crate::twis::State::new();
808                &STATE
809            }
810        }
811        impl crate::twis::Instance for peripherals::$type {
812            type Interrupt = crate::interrupt::typelevel::$irq;
813        }
814    };
815}