nrf24_rs/
status.rs

1//! Status datastructures.
2use crate::config::DataPipe;
3#[cfg(feature = "micro-fmt")]
4use ufmt::{uDebug, uWrite, Formatter};
5
6/// Wrapper for the status value returned from the device.
7/// Provides convenience methods and debug implemantions.
8#[derive(Copy, Clone, Eq, PartialEq)]
9pub struct Status(u8);
10
11/// Wrapper around the FIFO status.
12#[derive(Debug, Copy, Clone, Eq, PartialEq)]
13pub struct FIFOStatus(u8);
14
15impl Status {
16    /// Create a status obj with all the flags turned on.
17    pub fn flags() -> Self {
18        Self(0b01110000)
19    }
20    /// Returns the raw value represented by this struct.
21    pub fn value(&self) -> u8 {
22        self.0
23    }
24    /// Checks if the status is valid.
25    pub fn is_valid(&self) -> bool {
26        (self.0 >> 7) & 1 == 0
27    }
28    /// Indicates if there is data ready to be read.
29    pub fn data_ready(&self) -> bool {
30        (self.0 >> 6) & 1 != 0
31    }
32    /// Indicates whether data has been sent.
33    pub fn data_sent(&self) -> bool {
34        (self.0 >> 5) & 1 != 0
35    }
36    /// Indicates whether the max retries has been reached.
37    /// Can only be true if auto acknowledgement is enabled.
38    pub fn reached_max_retries(&self) -> bool {
39        (self.0 >> 4) & 1 != 0
40    }
41    /// Returns data pipe number for the payload availbe for reading
42    /// or None if RX FIFO is empty.
43    pub fn data_pipe_available(&self) -> Option<DataPipe> {
44        match (self.0 >> 1) & 0b111 {
45            x @ 0..=5 => Some(x.into()),
46            6 => panic!(),
47            7 => None,
48            _ => unreachable!(), // because we AND the value
49        }
50    }
51    /// Indicates whether the transmission queue is full or not.
52    pub fn tx_full(&self) -> bool {
53        (self.0 & 0b1) != 0
54    }
55}
56
57impl FIFOStatus {
58    /// Returns `true` if there are availbe locations in transmission queue
59    pub fn tx_full(&self) -> bool {
60        (self.0 >> 5) & 1 != 0
61    }
62
63    /// Returns `true` if the transmission queue is empty
64    pub fn tx_empty(&self) -> bool {
65        (self.0 >> 4) & 1 != 0
66    }
67
68    /// Returns `true` if there are availbe locations in receive queue
69    pub fn rx_full(&self) -> bool {
70        (self.0 >> 1) & 1 != 0
71    }
72
73    /// Returns `true` if the receive queue is empty
74    pub fn rx_empty(&self) -> bool {
75        self.0 & 1 != 0
76    }
77}
78
79impl From<u8> for Status {
80    fn from(t: u8) -> Self {
81        Status(t)
82    }
83}
84
85impl From<u8> for FIFOStatus {
86    fn from(t: u8) -> Self {
87        FIFOStatus(t)
88    }
89}
90
91impl core::fmt::Debug for Status {
92    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
93        if !&self.is_valid() {
94            f.write_str("Invalid status. Something went wrong during communication with nrf24l01")
95        } else {
96            let mut s = f.debug_struct("Status");
97            let s = s.field("Data ready", &self.data_ready());
98            let s = s.field("Data sent", &self.data_sent());
99            let s = s.field("Reached max retries", &self.reached_max_retries());
100            let s = match &self.data_pipe_available() {
101                None => s.field("No data ready to be read in FIFO", &true),
102                Some(pipe) => s.field("Data ready to be read on pipe", &pipe.pipe()),
103            };
104            let s = s.field("Transmission FIFO full", &self.tx_full());
105            s.finish()
106        }
107    }
108}
109
110#[cfg(feature = "micro-fmt")]
111impl uDebug for Status {
112    fn fmt<W: ?Sized>(&self, f: &mut Formatter<'_, W>) -> core::result::Result<(), W::Error>
113    where
114        W: uWrite,
115    {
116        if !&self.is_valid() {
117            f.write_str("Invalid status. Something went wrong during communication with nrf24l01")
118        } else {
119            let mut s = f.debug_struct("Status")?;
120            let s = s.field("Data ready", &self.data_ready())?;
121            let s = s.field("Data sent", &self.data_sent())?;
122            let s = s.field("Reached max retries", &self.reached_max_retries())?;
123            let s = match &self.data_pipe_available() {
124                None => s.field("No data ready to be read in FIFO", &true)?,
125                Some(pipe) => s.field("Data ready to be read on pipe", &pipe.pipe())?,
126            };
127            let s = s.field("Transmission FIFO full", &self.tx_full())?;
128            s.finish()
129        }
130    }
131}