1use crate::register_acces::Register;
18use crate::MAX_PAYLOAD_SIZE;
19#[cfg(feature = "micro-fmt")]
20use ufmt::{uDebug, uWrite, uwrite, Formatter};
21
22const MAX_CHANNEL: u8 = 125;
23
24#[derive(Copy, Debug, Clone)]
57pub struct NrfConfig {
58 pub(crate) payload_size: PayloadSize,
59 pub(crate) channel: u8,
60 pub(crate) addr_width: AddressWidth,
61 pub(crate) data_rate: DataRate,
62 pub(crate) pa_level: PALevel,
63 pub(crate) crc_encoding_scheme: Option<EncodingScheme>,
64 pub(crate) ack_payloads_enabled: bool,
65 pub(crate) auto_retry: AutoRetransmission,
66}
67
68impl NrfConfig {
69 pub fn payload_size<T: Into<PayloadSize>>(mut self, payload_size: T) -> Self {
73 self.payload_size = payload_size.into();
74 self
75 }
76 pub fn channel(mut self, channel: u8) -> Self {
79 self.channel = core::cmp::min(channel, MAX_CHANNEL);
80 self
81 }
82 pub fn addr_width<T: Into<AddressWidth>>(mut self, addr_width: T) -> Self {
85 self.addr_width = addr_width.into();
86 self
87 }
88 pub fn data_rate(mut self, data_rate: DataRate) -> Self {
90 self.data_rate = data_rate;
91 self
92 }
93 pub fn pa_level(mut self, pa_level: PALevel) -> Self {
95 self.pa_level = pa_level;
96 self
97 }
98 pub fn crc_encoding_scheme(mut self, crc_encoding_scheme: Option<EncodingScheme>) -> Self {
101 self.crc_encoding_scheme = crc_encoding_scheme;
102 self
103 }
104 pub fn ack_payloads_enabled(mut self, ack_payloads_enabled: bool) -> Self {
106 self.ack_payloads_enabled = ack_payloads_enabled;
107 self
108 }
109 pub fn auto_retry<T: Into<AutoRetransmission>>(mut self, auto_retry: T) -> Self {
111 self.auto_retry = auto_retry.into();
112 self
113 }
114}
115
116impl Default for NrfConfig {
117 fn default() -> Self {
118 Self {
119 channel: 76,
120 payload_size: PayloadSize::default(),
121 addr_width: AddressWidth::default(),
122 crc_encoding_scheme: Some(EncodingScheme::R2Bytes),
123 pa_level: PALevel::default(),
124 data_rate: DataRate::default(),
125 ack_payloads_enabled: false,
126 auto_retry: AutoRetransmission::default(),
127 }
128 }
129}
130
131#[cfg(feature = "micro-fmt")]
132impl uDebug for NrfConfig {
133 fn fmt<W: ?Sized>(&self, f: &mut Formatter<'_, W>) -> core::result::Result<(), W::Error>
134 where
135 W: uWrite,
136 {
137 f.debug_struct("nRF configuration")?
138 .field("channel", &self.channel)?
139 .field("payload size", &self.payload_size)?
140 .field("power amplification level", &self.pa_level)?
141 .field("data rate", &self.data_rate)?
142 .field("auto retransmission", &self.auto_retry)?
143 .field(
144 "acknowledgement payloads enabled",
145 &self.ack_payloads_enabled,
146 )?
147 .field("address width", &self.addr_width)?
148 .field("crc encoding scheme", &self.crc_encoding_scheme)?
149 .finish()
150 }
151}
152
153#[derive(Debug, PartialEq, Eq, Copy, Clone)]
158pub enum PALevel {
159 Min = 0b0000_0000,
161 Low = 0b0000_0010,
163 High = 0b0000_0100,
165 Max = 0b0000_0110,
167}
168
169impl PALevel {
170 pub(crate) fn bitmask() -> u8 {
171 0b0000_0110
172 }
173 pub(crate) fn level(&self) -> u8 {
174 *self as u8
175 }
176}
177
178impl Default for PALevel {
179 fn default() -> Self {
180 PALevel::Min
181 }
182}
183
184impl From<u8> for PALevel {
185 fn from(t: u8) -> Self {
186 match t & Self::bitmask() {
187 0b0000_0000 => Self::Min,
188 0b0000_0010 => Self::Low,
189 0b0000_0100 => Self::High,
190 0b0000_0110 => Self::Max,
191 _ => unreachable!(),
192 }
193 }
194}
195
196#[cfg(feature = "micro-fmt")]
197impl uDebug for PALevel {
198 fn fmt<W: ?Sized>(&self, f: &mut Formatter<'_, W>) -> core::result::Result<(), W::Error>
199 where
200 W: uWrite,
201 {
202 match *self {
203 PALevel::Min => f.write_str("min (-18 dBm)"),
204 PALevel::Low => f.write_str("low (-12 dBm)"),
205 PALevel::High => f.write_str("high (-6 dBm)"),
206 PALevel::Max => f.write_str("max (0 dBm)"),
207 }
208 }
209}
210
211#[derive(Debug, Copy, Clone, PartialEq, Eq)]
213pub enum PayloadSize {
214 Dynamic,
216 Static(u8),
218}
219
220impl PayloadSize {
221 pub(crate) fn truncate(self) -> Self {
223 match self {
224 Self::Dynamic => Self::Dynamic,
225 Self::Static(n) => Self::Static(core::cmp::min(n, MAX_PAYLOAD_SIZE)),
226 }
227 }
228}
229
230impl Default for PayloadSize {
231 fn default() -> Self {
232 Self::Static(MAX_PAYLOAD_SIZE)
233 }
234}
235
236impl From<u8> for PayloadSize {
237 fn from(size: u8) -> Self {
238 match size {
239 0 => Self::Dynamic,
240 n => Self::Static(core::cmp::min(n, MAX_PAYLOAD_SIZE)),
241 }
242 }
243}
244
245#[cfg(feature = "micro-fmt")]
246impl uDebug for PayloadSize {
247 fn fmt<W: ?Sized>(&self, f: &mut Formatter<'_, W>) -> core::result::Result<(), W::Error>
248 where
249 W: uWrite,
250 {
251 match *self {
252 Self::Dynamic => f.write_str("dynamic payloads"),
253 Self::Static(n) => uwrite!(f, "{:?} byte static payloads", n),
254 }
255 }
256}
257
258#[derive(Debug, PartialEq, Eq, Copy, Clone)]
262pub enum DataRate {
263 R1Mbps = 0b0000_0000,
265 R2Mbps = 0b0000_0001,
267}
268
269impl DataRate {
270 pub(crate) fn bitmask() -> u8 {
271 0b1111_1110
272 }
273 pub(crate) fn rate(&self) -> u8 {
274 *self as u8
275 }
276}
277
278impl Default for DataRate {
279 fn default() -> Self {
280 DataRate::R1Mbps
281 }
282}
283
284impl From<u8> for DataRate {
285 fn from(t: u8) -> Self {
286 match t & Self::bitmask() {
287 0 => Self::R1Mbps,
288 1 => Self::R2Mbps,
289 _ => unreachable!(),
290 }
291 }
292}
293
294#[cfg(feature = "micro-fmt")]
295impl uDebug for DataRate {
296 fn fmt<W: ?Sized>(&self, f: &mut Formatter<'_, W>) -> core::result::Result<(), W::Error>
297 where
298 W: uWrite,
299 {
300 match *self {
301 DataRate::R1Mbps => f.write_str("1 Mbps"),
302 DataRate::R2Mbps => f.write_str("2 Mbps"),
303 }
304 }
305}
306
307#[derive(Debug, PartialEq, Eq, Copy, Clone)]
309pub enum EncodingScheme {
310 R1Byte = 0,
312 R2Bytes = 1,
314}
315
316impl EncodingScheme {
317 pub(crate) fn scheme(&self) -> u8 {
318 *self as u8
319 }
320}
321
322#[cfg(feature = "micro-fmt")]
323impl uDebug for EncodingScheme {
324 fn fmt<W: ?Sized>(&self, f: &mut Formatter<'_, W>) -> core::result::Result<(), W::Error>
325 where
326 W: uWrite,
327 {
328 match *self {
329 Self::R1Byte => f.write_str("1 byte"),
330 Self::R2Bytes => f.write_str("2 bytes"),
331 }
332 }
333}
334
335#[derive(Debug, PartialEq, Eq, Copy, Clone)]
337pub enum AddressWidth {
338 R3Bytes = 1,
340 R4Bytes = 2,
342 R5Bytes = 3,
344}
345
346impl AddressWidth {
347 pub(crate) fn value(&self) -> u8 {
348 *self as u8
349 }
350}
351impl Default for AddressWidth {
352 fn default() -> Self {
353 Self::R5Bytes
354 }
355}
356
357impl From<u8> for AddressWidth {
358 fn from(t: u8) -> Self {
359 match t {
360 0..=3 => Self::R3Bytes,
361 4 => Self::R4Bytes,
362 5..=u8::MAX => Self::R5Bytes,
363 }
364 }
365}
366
367#[cfg(feature = "micro-fmt")]
368impl uDebug for AddressWidth {
369 fn fmt<W: ?Sized>(&self, f: &mut Formatter<'_, W>) -> core::result::Result<(), W::Error>
370 where
371 W: uWrite,
372 {
373 match *self {
374 Self::R3Bytes => f.write_str("3 bytes"),
375 Self::R4Bytes => f.write_str("4 bytes"),
376 Self::R5Bytes => f.write_str("5 bytes"),
377 }
378 }
379}
380
381#[derive(Debug, PartialEq, Eq, Copy, Clone)]
392pub struct AutoRetransmission {
393 delay: u8,
394 count: u8,
395}
396
397impl Default for AutoRetransmission {
398 fn default() -> Self {
399 Self {
400 delay: 5,
401 count: 15,
402 }
403 }
404}
405
406impl AutoRetransmission {
407 pub(crate) fn from_register(reg: u8) -> Self {
408 Self {
409 delay: reg >> 4,
410 count: reg & 0b0000_1111,
411 }
412 }
413 pub fn raw_delay(&self) -> u8 {
418 self.delay
419 }
420
421 pub fn delay(&self) -> u32 {
423 ((self.delay as u32 + 1) * 250) + 86
424 }
425 pub fn count(&self) -> u8 {
428 self.count
429 }
430}
431
432impl From<(u8, u8)> for AutoRetransmission {
433 fn from((d, c): (u8, u8)) -> Self {
434 Self {
435 delay: core::cmp::min(d, 15),
436 count: core::cmp::min(c, 15),
437 }
438 }
439}
440
441#[cfg(feature = "micro-fmt")]
442impl uDebug for AutoRetransmission {
443 fn fmt<W: ?Sized>(&self, f: &mut Formatter<'_, W>) -> core::result::Result<(), W::Error>
444 where
445 W: uWrite,
446 {
447 f.debug_struct("AutoRetransmission")?
448 .field("delay", &self.delay)?
449 .field("count", &self.count)?
450 .finish()
451 }
452}
453#[derive(Debug, PartialEq, Eq, Copy, Clone)]
472#[repr(u8)]
473pub enum DataPipe {
474 DP0 = 0,
479 DP1 = 1,
481 DP2 = 2,
483 DP3 = 3,
485 DP4 = 4,
487 DP5 = 5,
489}
490
491impl DataPipe {
492 pub(crate) fn pipe(&self) -> u8 {
493 *self as u8
494 }
495}
496
497impl Default for DataPipe {
498 fn default() -> Self {
499 DataPipe::DP0
500 }
501}
502
503impl From<u8> for DataPipe {
504 fn from(t: u8) -> Self {
505 match t {
506 0 => DataPipe::DP0,
507 1 => DataPipe::DP1,
508 2 => DataPipe::DP2,
509 3 => DataPipe::DP3,
510 4 => DataPipe::DP4,
511 5 => DataPipe::DP5,
512 _ => DataPipe::DP0,
513 }
514 }
515}
516
517impl Into<Register> for DataPipe {
518 fn into(self) -> Register {
519 match self {
520 DataPipe::DP0 => Register::RX_ADDR_P0,
521 DataPipe::DP1 => Register::RX_ADDR_P1,
522 DataPipe::DP2 => Register::RX_ADDR_P2,
523 DataPipe::DP3 => Register::RX_ADDR_P3,
524 DataPipe::DP4 => Register::RX_ADDR_P4,
525 DataPipe::DP5 => Register::RX_ADDR_P5,
526 }
527 }
528}
529
530#[cfg(feature = "micro-fmt")]
531impl uDebug for DataPipe {
532 fn fmt<W: ?Sized>(&self, f: &mut Formatter<'_, W>) -> core::result::Result<(), W::Error>
533 where
534 W: uWrite,
535 {
536 match *self {
537 DataPipe::DP0 => f.write_str("data pipe 0"),
538 DataPipe::DP1 => f.write_str("data pipe 1"),
539 DataPipe::DP2 => f.write_str("data pipe 2"),
540 DataPipe::DP3 => f.write_str("data pipe 3"),
541 DataPipe::DP4 => f.write_str("data pipe 4"),
542 DataPipe::DP5 => f.write_str("data pipe 5"),
543 }
544 }
545}