rf24/radio/rf24/
data_rate.rs

1use embedded_hal::{delay::DelayNs, digital::OutputPin, spi::SpiDevice};
2
3use super::registers;
4use crate::radio::{prelude::EsbDataRate, Nrf24Error, RF24};
5use crate::DataRate;
6
7/// A function to set the [`RF24::tx_delay`] in accordance with the desired [`DataRate`].
8///
9/// This function is only public to the crate::radio::rf24 module.
10pub(super) fn set_tx_delay(data_rate: DataRate) -> u32 {
11    match data_rate {
12        DataRate::Mbps1 => 280,
13        DataRate::Mbps2 => 240,
14        DataRate::Kbps250 => 505,
15    }
16}
17
18impl<SPI, DO, DELAY> EsbDataRate for RF24<SPI, DO, DELAY>
19where
20    SPI: SpiDevice,
21    DO: OutputPin,
22    DELAY: DelayNs,
23{
24    type DataRateErrorType = Nrf24Error<SPI::Error, DO::Error>;
25
26    fn get_data_rate(&mut self) -> Result<DataRate, Self::DataRateErrorType> {
27        self.spi_read(1, registers::RF_SETUP)?;
28        let da_bin = self._buf[1] & (0x28);
29        if da_bin == 0x28 {
30            return Err(Nrf24Error::BinaryCorruption);
31        }
32        Ok(DataRate::from_bits(da_bin))
33    }
34
35    fn set_data_rate(&mut self, data_rate: DataRate) -> Result<(), Self::DataRateErrorType> {
36        self.tx_delay = set_tx_delay(data_rate);
37        let da_bin = data_rate.into_bits();
38        self.spi_read(1, registers::RF_SETUP)?;
39        let out = self._buf[1] & !0x28 | da_bin;
40        self.spi_write_byte(registers::RF_SETUP, out)
41    }
42}
43
44/////////////////////////////////////////////////////////////////////////////////
45/// unit tests
46#[cfg(test)]
47mod test {
48    extern crate std;
49    use crate::radio::prelude::EsbDataRate;
50    use crate::radio::rf24::commands;
51    use crate::{spi_test_expects, DataRate};
52
53    use super::{registers, RF24};
54    use embedded_hal_mock::eh1::delay::NoopDelay;
55    use embedded_hal_mock::eh1::digital::Mock as PinMock;
56    use embedded_hal_mock::eh1::spi::{Mock as SpiMock, Transaction as SpiTransaction};
57    use std::vec;
58
59    #[test]
60    pub fn get_data_rate() {
61        // Create pin
62        let pin_expectations = [];
63        let mut pin_mock = PinMock::new(&pin_expectations);
64
65        // create delay fn
66        let delay_mock = NoopDelay::new();
67
68        let spi_expectations = spi_test_expects![
69            // get the RF_SETUP register value for each possible result
70            (vec![registers::RF_SETUP, 0u8], vec![0xEu8, 0u8]),
71            (vec![registers::RF_SETUP, 0u8], vec![0xEu8, 8u8]),
72            (vec![registers::RF_SETUP, 8u8], vec![0xEu8, 0x20u8]),
73            (vec![registers::RF_SETUP, 0x20u8], vec![0xEu8, 0x28u8]),
74        ];
75        let mut spi_mock = SpiMock::new(&spi_expectations);
76        let mut radio = RF24::new(pin_mock.clone(), spi_mock.clone(), delay_mock);
77        assert_eq!(radio.get_data_rate(), Ok(DataRate::Mbps1));
78        assert_eq!(radio.get_data_rate(), Ok(DataRate::Mbps2));
79        assert_eq!(radio.get_data_rate(), Ok(DataRate::Kbps250));
80        assert_eq!(
81            radio.get_data_rate(),
82            Err(crate::radio::Nrf24Error::BinaryCorruption)
83        );
84        spi_mock.done();
85        pin_mock.done();
86    }
87
88    #[test]
89    pub fn set_data_rate() {
90        // Create pin
91        let pin_expectations = [];
92        let mut pin_mock = PinMock::new(&pin_expectations);
93
94        // create delay fn
95        let delay_mock = NoopDelay::new();
96
97        let spi_expectations = spi_test_expects![
98            // set the RF_SETUP register value for each possible enumeration of CrcLength
99            (vec![registers::RF_SETUP, 0u8], vec![0xEu8, 0x28u8]),
100            (
101                vec![registers::RF_SETUP | commands::W_REGISTER, 0u8],
102                vec![0xEu8, 0u8],
103            ),
104            (vec![registers::RF_SETUP, 0u8], vec![0xEu8, 0x28u8]),
105            (
106                vec![registers::RF_SETUP | commands::W_REGISTER, 0x8u8],
107                vec![0xEu8, 0u8],
108            ),
109            (vec![registers::RF_SETUP, 0u8], vec![0xEu8, 0x28u8]),
110            (
111                vec![registers::RF_SETUP | commands::W_REGISTER, 0x20u8],
112                vec![0xEu8, 0u8],
113            ),
114        ];
115        let mut spi_mock = SpiMock::new(&spi_expectations);
116        let mut radio = RF24::new(pin_mock.clone(), spi_mock.clone(), delay_mock);
117        radio.set_data_rate(DataRate::Mbps1).unwrap();
118        radio.set_data_rate(DataRate::Mbps2).unwrap();
119        radio.set_data_rate(DataRate::Kbps250).unwrap();
120        spi_mock.done();
121        pin_mock.done();
122    }
123}