1use embedded_hal::{delay::DelayNs, digital::OutputPin, spi::SpiDevice};
2
3use crate::radio::{prelude::EsbPower, Nrf24Error, RF24};
4
5use super::registers;
6
7impl<SPI, DO, DELAY> EsbPower for RF24<SPI, DO, DELAY>
8where
9 SPI: SpiDevice,
10 DO: OutputPin,
11 DELAY: DelayNs,
12{
13 type PowerErrorType = Nrf24Error<SPI::Error, DO::Error>;
14
15 fn power_down(&mut self) -> Result<(), Self::PowerErrorType> {
25 self.ce_pin.set_low().map_err(Nrf24Error::Gpo)?; self._config_reg = self._config_reg.with_power(false);
27 self.spi_write_byte(registers::CONFIG, self._config_reg.into_bits())?;
28 Ok(())
29 }
30
31 fn power_up(&mut self, delay: Option<u32>) -> Result<(), Self::PowerErrorType> {
32 if self._config_reg.power() {
34 return Ok(());
35 }
36 self._config_reg = self._config_reg.with_power(true);
37 self.spi_write_byte(registers::CONFIG, self._config_reg.into_bits())?;
38
39 if delay.is_some_and(|val| val > 0) || delay.is_none() {
43 self._delay_impl.delay_ns(delay.unwrap_or(5000000));
44 }
45 Ok(())
46 }
47
48 fn is_powered(&self) -> bool {
50 self._config_reg.power()
51 }
52}
53
54#[cfg(test)]
57mod test {
58 extern crate std;
59 use crate::radio::prelude::EsbPower;
60 use crate::radio::rf24::commands;
61 use crate::spi_test_expects;
62
63 use super::{registers, RF24};
64 use embedded_hal_mock::eh1::delay::NoopDelay;
65 use embedded_hal_mock::eh1::digital::Mock as PinMock;
66 use embedded_hal_mock::eh1::spi::{Mock as SpiMock, Transaction as SpiTransaction};
67 use std::vec;
68
69 #[test]
70 pub fn power_up() {
71 let pin_expectations = [];
73 let mut pin_mock = PinMock::new(&pin_expectations);
74
75 let delay_mock = NoopDelay::new();
77
78 let spi_expectations = spi_test_expects![
79 (
81 vec![registers::CONFIG | commands::W_REGISTER, 0xEu8],
82 vec![0xEu8, 0u8],
83 ),
84 ];
85 let mut spi_mock = SpiMock::new(&spi_expectations);
86 let mut radio = RF24::new(pin_mock.clone(), spi_mock.clone(), delay_mock);
87 radio.power_up(None).unwrap();
88 radio.power_up(None).unwrap();
89 spi_mock.done();
91 pin_mock.done();
92 }
93
94 #[test]
95 pub fn power_up_no_blocking() {
96 let pin_expectations = [];
98 let mut pin_mock = PinMock::new(&pin_expectations);
99
100 let delay_mock = NoopDelay::new();
102
103 let spi_expectations = spi_test_expects![
104 (
106 vec![registers::CONFIG | commands::W_REGISTER, 0xEu8],
107 vec![0xEu8, 0u8],
108 ),
109 ];
110 let mut spi_mock = SpiMock::new(&spi_expectations);
111 let mut radio = RF24::new(pin_mock.clone(), spi_mock.clone(), delay_mock);
112 radio.power_up(Some(0)).unwrap();
113 assert!(radio.is_powered());
114 spi_mock.done();
115 pin_mock.done();
116 }
117
118 #[test]
119 pub fn power_getter() {
120 let pin_expectations = [];
122 let mut pin_mock = PinMock::new(&pin_expectations);
123
124 let delay_mock = NoopDelay::new();
126
127 let spi_expectations = vec![];
128 let mut spi_mock = SpiMock::new(&spi_expectations);
129 let radio = RF24::new(pin_mock.clone(), spi_mock.clone(), delay_mock);
130 assert!(!radio.is_powered());
132 spi_mock.done();
133 pin_mock.done();
134 }
135}