embedded_nrf24l01/
tx.rs

1use crate::command::{FlushTx, WriteTxPayload};
2use crate::config::Configuration;
3use crate::device::Device;
4use crate::registers::{FifoStatus, ObserveTx, Status};
5use crate::standby::StandbyMode;
6use core::fmt;
7
8/// Represents **TX Mode** and the associated **TX Settling** and
9/// **Standby-II** states
10///
11/// # Timing
12///
13/// The datasheet states the follwing:
14///
15/// > It is important to never keep the nRF24L01 in TX mode for more than 4ms at a time.
16///
17/// No effects have been observed when exceeding this limit. The
18/// warranty could get void.
19pub struct TxMode<D: Device> {
20    device: D,
21}
22
23impl<D: Device> fmt::Debug for TxMode<D> {
24    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
25        write!(f, "TxMode")
26    }
27}
28
29impl<D: Device> TxMode<D> {
30    /// Relies on everything being set up by `StandbyMode::tx()`, from
31    /// which it is called
32    pub(crate) fn new(device: D) -> Self {
33        TxMode { device }
34    }
35
36    /// Disable `CE` so that you can switch into RX mode.
37    pub fn standby(mut self) -> Result<StandbyMode<D>, D::Error> {
38        self.wait_empty()?;
39
40        Ok(StandbyMode::from_rx_tx(self.device))
41    }
42
43    /// Is TX FIFO empty?
44    pub fn is_empty(&mut self) -> Result<bool, D::Error> {
45        let (_, fifo_status) = self.device.read_register::<FifoStatus>()?;
46        Ok(fifo_status.tx_empty())
47    }
48
49    /// Is TX FIFO full?
50    pub fn is_full(&mut self) -> Result<bool, D::Error> {
51        let (_, fifo_status) = self.device.read_register::<FifoStatus>()?;
52        Ok(fifo_status.tx_full())
53    }
54
55    /// Does the TX FIFO have space?
56    pub fn can_send(&mut self) -> Result<bool, D::Error> {
57        let full = self.is_full()?;
58        Ok(!full)
59    }
60
61    /// Send asynchronously
62    pub fn send(&mut self, packet: &[u8]) -> Result<(), D::Error> {
63        self.device.send_command(&WriteTxPayload::new(packet))?;
64        self.device.ce_enable();
65        Ok(())
66    }
67
68    /// Poll completion of one or multiple send operations and check whether transmission was
69    /// successful.
70    ///
71    /// This function behaves like `wait_empty()`, except that it returns whether sending was
72    /// successful and that it provides an asynchronous interface.
73    pub fn poll_send(&mut self) -> nb::Result<bool, D::Error> {
74        let (status, fifo_status) = self.device.read_register::<FifoStatus>()?;
75        // We need to clear all the TX interrupts whenever we return Ok here so that the next call
76        // to poll_send correctly recognizes max_rt and send completion.
77        if status.max_rt() {
78            // If MAX_RT is set, the packet is not removed from the FIFO, so if we do not flush
79            // the FIFO, we end up in an infinite loop
80            self.device.send_command(&FlushTx)?;
81            self.clear_interrupts_and_ce()?;
82            Ok(false)
83        } else if fifo_status.tx_empty() {
84            self.clear_interrupts_and_ce()?;
85            Ok(true)
86        } else {
87            self.device.ce_enable();
88            Err(nb::Error::WouldBlock)
89        }
90    }
91
92    fn clear_interrupts_and_ce(&mut self) -> nb::Result<(), D::Error> {
93        let mut clear = Status(0);
94        clear.set_tx_ds(true);
95        clear.set_max_rt(true);
96        self.device.write_register(clear)?;
97
98        // Can save power now
99        self.device.ce_disable();
100
101        Ok(())
102    }
103
104    /// Wait until TX FIFO is empty
105    ///
106    /// If any packet cannot be delivered and the maximum amount of retries is
107    /// reached, the TX FIFO is flushed and all other packets in the FIFO are
108    /// lost.
109    pub fn wait_empty(&mut self) -> Result<(), D::Error> {
110        let mut empty = false;
111        while !empty {
112            let (status, fifo_status) = self.device.read_register::<FifoStatus>()?;
113            empty = fifo_status.tx_empty();
114            if !empty {
115                self.device.ce_enable();
116            }
117
118            // TX won't continue while MAX_RT is set
119            if status.max_rt() {
120                let mut clear = Status(0);
121                // If MAX_RT is set, the packet is not removed from the FIFO, so if we do not flush
122                // the FIFO, we end up in an infinite loop
123                self.device.send_command(&FlushTx)?;
124                // Clear TX interrupts
125                clear.set_tx_ds(true);
126                clear.set_max_rt(true);
127                self.device.write_register(clear)?;
128            }
129        }
130        // Can save power now
131        self.device.ce_disable();
132
133        Ok(())
134    }
135
136    /// Read the `OBSERVE_TX` register
137    pub fn observe(&mut self) -> Result<ObserveTx, D::Error> {
138        let (_, observe_tx) = self.device.read_register()?;
139        Ok(observe_tx)
140    }
141}
142
143impl<D: Device> Configuration for TxMode<D> {
144    type Inner = D;
145    fn device(&mut self) -> &mut Self::Inner {
146        &mut self.device
147    }
148}