1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
#![warn(missing_docs, unused)]
#![no_std]
extern crate embedded_hal;
#[macro_use]
extern crate bitfield;
use core::fmt;
use core::fmt::Debug;
use embedded_hal::digital::OutputPin;
use embedded_hal::blocking::spi::Transfer as SpiTransfer;
mod config;
pub use config::{Configuration, CrcMode, DataRate};
pub mod setup;
mod registers;
use registers::{Register, Config, Status, SetupAw};
mod command;
use command::{Command, ReadRegister, WriteRegister};
mod payload;
pub use payload::Payload;
mod device;
pub use device::Device;
mod standby;
pub use standby::StandbyMode;
mod rx;
pub use rx::RxMode;
mod tx;
pub use tx::TxMode;
pub const PIPES_COUNT: usize = 6;
pub const MIN_ADDR_BYTES: usize = 3;
pub const MAX_ADDR_BYTES: usize = 5;
pub struct NRF24L01<CE: OutputPin, CSN: OutputPin, SPI: SpiTransfer<u8>> {
ce: CE,
csn: CSN,
spi: SPI,
config: Config,
}
impl<CE: OutputPin, CSN: OutputPin, SPI: SpiTransfer<u8, Error=SPIE>, SPIE: Debug> fmt::Debug for NRF24L01<CE, CSN, SPI> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "NRF24L01")
}
}
impl<CE: OutputPin, CSN: OutputPin, SPI: SpiTransfer<u8, Error=SPIE>, SPIE: Debug> NRF24L01<CE, CSN, SPI> {
pub fn new(mut ce: CE, mut csn: CSN, spi: SPI) -> Result<StandbyMode<Self>, SPIE> {
ce.set_low();
csn.set_high();
let mut config = Config(0b0000_1000);
config.set_mask_rx_dr(true);
config.set_mask_tx_ds(true);
config.set_mask_max_rt(true);
let mut device = NRF24L01 {
ce, csn, spi,
config,
};
assert!(device.is_connected().unwrap());
StandbyMode::power_up(device)
.map_err(|(_, e)| e)
}
pub fn is_connected(&mut self) -> Result<bool, SPIE> {
let (_, setup_aw) =
self.read_register::<SetupAw>()?;
let valid =
setup_aw.aw() >= 3 &&
setup_aw.aw() <= 5;
Ok(valid)
}
}
impl<CE: OutputPin, CSN: OutputPin, SPI: SpiTransfer<u8, Error=SPIE>, SPIE: Debug> Device for NRF24L01<CE, CSN, SPI> {
type Error = SPIE;
fn ce_enable(&mut self) {
self.ce.set_high();
}
fn ce_disable(&mut self) {
self.ce.set_low();
}
fn send_command<C: Command>(&mut self, command: &C) -> Result<(Status, C::Response), Self::Error> {
let mut buf_storage = [0; 33];
let len = command.len();
let buf = &mut buf_storage[0..len];
command.encode(buf);
self.csn.set_low();
let transfer_result = self.spi.transfer(buf)
.map(|_| {});
self.csn.set_high();
transfer_result?;
let status = Status(buf[0]);
let response = C::decode_response(buf);
Ok((status, response))
}
fn write_register<R: Register>(&mut self, register: R) -> Result<Status, Self::Error> {
let (status, ()) = self.send_command(&WriteRegister::new(register))?;
Ok(status)
}
fn read_register<R: Register>(&mut self) -> Result<(Status, R), Self::Error> {
self.send_command(&ReadRegister::new())
}
fn update_config<F, R>(&mut self, f: F) -> Result<R, Self::Error>
where F: FnOnce(&mut Config) -> R
{
let old_config = self.config.clone();
let result = f(&mut self.config);
if self.config != old_config {
let config = self.config.clone();
self.write_register(config)?;
}
Ok(result)
}
}