1use crate::command::{FlushRx, FlushTx, Nop};
2use crate::device::Device;
3use crate::registers::{
4 Config, Dynpd, EnAa, EnRxaddr, Feature, RfCh, RfSetup, SetupAw, SetupRetr, Status, TxAddr,
5};
6use crate::PIPES_COUNT;
7
8#[derive(Debug, PartialEq, Copy, Clone)]
10pub enum DataRate {
11 R250Kbps,
13 R1Mbps,
15 R2Mbps,
17}
18
19impl Default for DataRate {
20 fn default() -> DataRate {
21 DataRate::R1Mbps
22 }
23}
24
25#[derive(Debug, PartialEq, Copy, Clone)]
27pub enum CrcMode {
28 Disabled,
30 OneByte,
32 TwoBytes,
34}
35
36impl CrcMode {
37 fn set_config(&self, config: &mut Config) {
38 let (en_crc, crco) = match *self {
39 CrcMode::Disabled => (false, false),
40 CrcMode::OneByte => (true, false),
41 CrcMode::TwoBytes => (true, true),
42 };
43 config.set_en_crc(en_crc);
44 config.set_crco(crco);
45 }
46}
47
48pub trait Configuration {
52 type Inner: Device;
54 fn device(&mut self) -> &mut Self::Inner;
56
57 fn flush_rx(&mut self) -> Result<(), <<Self as Configuration>::Inner as Device>::Error> {
61 self.device().send_command(&FlushRx)?;
62 Ok(())
63 }
64
65 fn flush_tx(&mut self) -> Result<(), <<Self as Configuration>::Inner as Device>::Error> {
67 self.device().send_command(&FlushTx)?;
68 Ok(())
69 }
70
71 fn get_frequency(&mut self) -> Result<u8, <<Self as Configuration>::Inner as Device>::Error> {
73 let (_, register) = self.device().read_register::<RfCh>()?;
74 let freq_offset = register.rf_ch();
75 Ok(freq_offset)
76 }
77
78 fn set_frequency(
80 &mut self,
81 freq_offset: u8,
82 ) -> Result<(), <<Self as Configuration>::Inner as Device>::Error> {
83 assert!(freq_offset < 126);
84
85 let mut register = RfCh(0);
86 register.set_rf_ch(freq_offset);
87 self.device().write_register(register)?;
88
89 Ok(())
90 }
91
92 fn set_rf(
94 &mut self,
95 rate: &DataRate,
96 power: u8,
97 ) -> Result<(), <<Self as Configuration>::Inner as Device>::Error> {
98 assert!(power < 0b100);
99 let mut register = RfSetup(0);
100 register.set_rf_pwr(power);
101
102 let (dr_low, dr_high) = match *rate {
103 DataRate::R250Kbps => (true, false),
104 DataRate::R1Mbps => (false, false),
105 DataRate::R2Mbps => (false, true),
106 };
107 register.set_rf_dr_low(dr_low);
108 register.set_rf_dr_high(dr_high);
109
110 self.device().write_register(register)?;
111 Ok(())
112 }
113
114 fn set_crc(
116 &mut self,
117 mode: CrcMode,
118 ) -> Result<(), <<Self as Configuration>::Inner as Device>::Error> {
119 self.device().update_config(|config| mode.set_config(config))
120 }
121
122 fn set_interrupt_mask(
127 &mut self,
128 data_ready_rx: bool,
129 data_sent_tx: bool,
130 max_retransmits_tx: bool
131 ) -> Result<(), <<Self as Configuration>::Inner as Device>::Error> {
132 self.device().update_config(|config| {
133 config.set_mask_rx_dr(data_ready_rx);
134 config.set_mask_tx_ds(data_sent_tx);
135 config.set_mask_max_rt(max_retransmits_tx);
136 })
137 }
138
139 fn set_pipes_rx_enable(
141 &mut self,
142 bools: &[bool; PIPES_COUNT],
143 ) -> Result<(), <<Self as Configuration>::Inner as Device>::Error> {
144 self.device().write_register(EnRxaddr::from_bools(bools))?;
145 Ok(())
146 }
147
148 fn set_rx_addr(
150 &mut self,
151 pipe_no: usize,
152 addr: &[u8],
153 ) -> Result<(), <<Self as Configuration>::Inner as Device>::Error> {
154 macro_rules! w {
155 ( $($no: expr, $name: ident);+ ) => (
156 match pipe_no {
157 $(
158 $no => {
159 use crate::registers::$name;
160 let register = $name::new(addr);
161 self.device().write_register(register)?;
162 }
163 )+
164 _ => panic!("No such pipe {}", pipe_no)
165 }
166 )
167 }
168 w!(0, RxAddrP0;
169 1, RxAddrP1;
170 2, RxAddrP2;
171 3, RxAddrP3;
172 4, RxAddrP4;
173 5, RxAddrP5);
174 Ok(())
175 }
176
177 fn set_tx_addr(
179 &mut self,
180 addr: &[u8],
181 ) -> Result<(), <<Self as Configuration>::Inner as Device>::Error> {
182 let register = TxAddr::new(addr);
183 self.device().write_register(register)?;
184 Ok(())
185 }
186
187 fn set_auto_retransmit(
191 &mut self,
192 delay: u8,
193 count: u8,
194 ) -> Result<(), <<Self as Configuration>::Inner as Device>::Error> {
195 let mut register = SetupRetr(0);
196 register.set_ard(delay);
197 register.set_arc(count);
198 self.device().write_register(register)?;
199 Ok(())
200 }
201
202 fn get_auto_ack(
204 &mut self,
205 ) -> Result<[bool; PIPES_COUNT], <<Self as Configuration>::Inner as Device>::Error> {
206 let (_, register) = self.device().read_register::<EnAa>()?;
208 Ok(register.to_bools())
209 }
210
211 fn set_auto_ack(
215 &mut self,
216 bools: &[bool; PIPES_COUNT],
217 ) -> Result<(), <<Self as Configuration>::Inner as Device>::Error> {
218 let register = EnAa::from_bools(bools);
220 self.device().write_register(register)?;
222 Ok(())
223 }
224
225 fn get_address_width(
227 &mut self,
228 ) -> Result<u8, <<Self as Configuration>::Inner as Device>::Error> {
229 let (_, register) = self.device().read_register::<SetupAw>()?;
230 Ok(2 + register.aw())
231 }
232
233 fn get_interrupts(
238 &mut self,
239 ) -> Result<(bool, bool, bool), <<Self as Configuration>::Inner as Device>::Error> {
240 let (status, ()) = self.device().send_command(&Nop)?;
241 Ok((status.rx_dr(), status.tx_ds(), status.max_rt()))
242 }
243
244 fn clear_interrupts(
246 &mut self,
247 ) -> Result<(), <<Self as Configuration>::Inner as Device>::Error> {
248 let mut clear = Status(0);
249 clear.set_rx_dr(true);
250 clear.set_tx_ds(true);
251 clear.set_max_rt(true);
252 self.device().write_register(clear)?;
253 Ok(())
254 }
255
256 fn set_pipes_rx_lengths(
260 &mut self,
261 lengths: &[Option<u8>; PIPES_COUNT],
262 ) -> Result<(), <<Self as Configuration>::Inner as Device>::Error> {
263 let mut bools = [true; PIPES_COUNT];
265 for (i, length) in lengths.iter().enumerate() {
266 bools[i] = length.is_none();
267 }
268 let dynpd = Dynpd::from_bools(&bools);
269 if dynpd.0 != 0 {
270 self.device().update_register::<Feature, _, _>(|feature| {
271 feature.set_en_dpl(true);
272 })?;
273 }
274 self.device().write_register(dynpd)?;
275
276 macro_rules! set_rx_pw {
278 ($name: ident, $index: expr) => {{
279 use crate::registers::$name;
280 let length = lengths[$index].unwrap_or(0);
281 let mut register = $name(0);
282 register.set(length);
283 self.device().write_register(register)?;
284 }};
285 }
286 set_rx_pw!(RxPwP0, 0);
287 set_rx_pw!(RxPwP1, 1);
288 set_rx_pw!(RxPwP2, 2);
289 set_rx_pw!(RxPwP3, 3);
290 set_rx_pw!(RxPwP4, 4);
291 set_rx_pw!(RxPwP5, 5);
292
293 Ok(())
294 }
295}