embedded_nrf24l01_async/
lib.rs1#![warn(missing_docs, unused)]
10#![allow(async_fn_in_trait)]
11
12#![no_std]
13#[macro_use]
14extern crate bitfield;
15
16use core::fmt;
17use core::fmt::Debug;
18use embedded_hal_async::spi::SpiDevice;
19use embedded_hal::digital::OutputPin;
20
21mod config;
22pub use crate::config::{Configuration, CrcMode, DataRate};
23pub mod setup;
24
25mod registers;
26use crate::registers::{Config, Register, SetupAw, Status, Feature};
27mod command;
28use crate::command::{Command, ReadRegister, WriteRegister};
29mod payload;
30pub use crate::payload::Payload;
31mod error;
32pub use crate::error::Error;
33
34mod device;
35pub use crate::device::Device;
36mod standby;
37pub use crate::standby::StandbyMode;
38mod rx;
39pub use crate::rx::RxMode;
40mod tx;
41pub use crate::tx::TxMode;
42
43pub const PIPES_COUNT: usize = 6;
45pub const MIN_ADDR_BYTES: usize = 2;
47pub const MAX_ADDR_BYTES: usize = 5;
49
50pub struct NRF24L01<E: Debug, CE: OutputPin<Error = E>, SPI: SpiDevice<u8>> {
60 ce: CE,
61 pub spi: SPI,
63 config: Config,
64}
65
66impl<E: Debug, CE: OutputPin<Error = E>, SPI: SpiDevice<u8, Error = SPIE>, SPIE: Debug> fmt::Debug
67 for NRF24L01<E, CE, SPI>
68{
69 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
70 write!(f, "NRF24L01")
71 }
72}
73
74impl<E: Debug, CE: OutputPin<Error = E>, SPI: SpiDevice<u8, Error = SPIE>, SPIE: Debug>
75 NRF24L01<E, CE, SPI>
76{
77 pub async fn new(mut ce: CE, spi: SPI) -> Result<StandbyMode<Self>, Error<SPIE>> {
79 ce.set_low().unwrap();
80
81 let mut config = Config(0b0000_1000);
83 config.set_mask_rx_dr(false);
84 config.set_mask_tx_ds(false);
85 config.set_mask_max_rt(false);
86 let mut device = NRF24L01 {
87 ce,
88 spi,
89 config,
90 };
91
92 match device.is_connected().await {
93 Err(e) => return Err(e),
94 Ok(false) => return Err(Error::NotConnected),
95 _ => {}
96 }
97
98 let mut features = Feature(0);
100 features.set_en_dyn_ack(true);
101 features.set_en_dpl(true);
102 device.write_register(features).await?;
103
104 StandbyMode::power_up(device).await.map_err(|(_, e)| e)
105 }
106
107 pub async fn is_connected(&mut self) -> Result<bool, Error<SPIE>> {
109 let (_, setup_aw) = self.read_register::<SetupAw>().await?;
110 let valid = setup_aw.aw() <= 3;
111 Ok(valid)
112 }
113}
114
115impl<E: Debug, CE: OutputPin<Error = E>, SPI: SpiDevice<u8, Error = SPIE>, SPIE: Debug> Device
116 for NRF24L01<E, CE, SPI>
117{
118 type Error = Error<SPIE>;
119
120 fn ce_enable(&mut self) {
121 self.ce.set_high().unwrap();
122 }
123
124 fn ce_disable(&mut self) {
125 self.ce.set_low().unwrap();
126 }
127
128 async fn send_command<C: Command>(
129 &mut self,
130 command: &C,
131 ) -> Result<(Status, C::Response), Self::Error> {
132 let mut buf_storage = [0; 256];
134 let len = command.len();
135 let buf = &mut buf_storage[0..len];
136 command.encode(buf);
138
139 self.spi.transfer_in_place(buf).await.expect("TODO: panic message");
141
142 let status = Status(buf[0]);
144 let response = C::decode_response(buf);
145 Ok((status, response))
147 }
148
149 async fn write_register<R: Register>(&mut self, register: R) -> Result<Status, Self::Error> {
150 let (status, ()) = self.send_command(&WriteRegister::new(register)).await?;
151 Ok(status)
152 }
153
154 async fn read_register<R: Register>(&mut self) -> Result<(Status, R), Self::Error> {
155 self.send_command(&ReadRegister::new()).await
156 }
157
158 async fn update_config<F, R>(&mut self, f: F) -> Result<R, Self::Error>
159 where
160 F: FnOnce(&mut Config) -> R,
161 {
162 let old_config = self.config.clone();
164 let result = f(&mut self.config);
165
166 if self.config != old_config {
167 let config = self.config.clone();
168 self.write_register(config).await?;
169 }
170 Ok(result)
171 }
172}