1use core::{
5 fmt::{Display, Formatter, Result},
6 write,
7};
8
9use bitfield_struct::bitfield;
10
11#[derive(Clone, Copy, Debug, PartialEq)]
14pub enum PaLevel {
15 Min,
19 Low,
23 High,
27 Max,
31}
32
33#[cfg(feature = "defmt")]
34#[cfg(target_os = "none")]
35impl defmt::Format for PaLevel {
36 fn format(&self, fmt: defmt::Formatter) {
37 match self {
38 PaLevel::Min => defmt::write!(fmt, "Min"),
39 PaLevel::Low => defmt::write!(fmt, "Low"),
40 PaLevel::High => defmt::write!(fmt, "High"),
41 PaLevel::Max => defmt::write!(fmt, "Max"),
42 }
43 }
44}
45
46impl PaLevel {
47 pub(crate) const fn into_bits(self) -> u8 {
48 match self {
49 PaLevel::Min => 0,
50 PaLevel::Low => 2,
51 PaLevel::High => 4,
52 PaLevel::Max => 6,
53 }
54 }
55 pub(crate) const fn from_bits(value: u8) -> Self {
56 match value {
57 0 => PaLevel::Min,
58 2 => PaLevel::Low,
59 4 => PaLevel::High,
60 _ => PaLevel::Max,
61 }
62 }
63}
64
65impl Display for PaLevel {
66 fn fmt(&self, f: &mut Formatter) -> Result {
67 match self {
68 PaLevel::Min => write!(f, "Min"),
69 PaLevel::Low => write!(f, "Low"),
70 PaLevel::High => write!(f, "High"),
71 PaLevel::Max => write!(f, "Max"),
72 }
73 }
74}
75
76#[derive(Clone, Copy, Debug, PartialEq)]
78pub enum DataRate {
79 Mbps1,
81 Mbps2,
83 Kbps250,
85}
86
87impl DataRate {
88 pub(crate) const fn into_bits(self) -> u8 {
89 match self {
90 DataRate::Mbps1 => 0,
91 DataRate::Mbps2 => 0x8,
92 DataRate::Kbps250 => 0x20,
93 }
94 }
95 pub(crate) const fn from_bits(value: u8) -> Self {
96 match value {
97 0x8 => DataRate::Mbps2,
98 0x20 => DataRate::Kbps250,
99 _ => DataRate::Mbps1,
100 }
101 }
102}
103
104#[cfg(feature = "defmt")]
105#[cfg(target_os = "none")]
106impl defmt::Format for DataRate {
107 fn format(&self, fmt: defmt::Formatter) {
108 match self {
109 DataRate::Mbps1 => defmt::write!(fmt, "1 Mbps"),
110 DataRate::Mbps2 => defmt::write!(fmt, "2 Mbps"),
111 DataRate::Kbps250 => defmt::write!(fmt, "250 Kbps"),
112 }
113 }
114}
115
116impl Display for DataRate {
117 fn fmt(&self, f: &mut Formatter) -> Result {
118 match self {
119 DataRate::Mbps1 => write!(f, "1 Mbps"),
120 DataRate::Mbps2 => write!(f, "2 Mbps"),
121 DataRate::Kbps250 => write!(f, "250 Kbps"),
122 }
123 }
124}
125
126#[derive(Clone, Copy, Debug, PartialEq)]
130pub enum CrcLength {
131 Disabled,
133 Bit8,
135 Bit16,
137}
138
139impl CrcLength {
140 pub(crate) const fn into_bits(self) -> u8 {
141 match self {
142 CrcLength::Disabled => 0,
143 CrcLength::Bit8 => 8,
144 CrcLength::Bit16 => 12,
145 }
146 }
147 pub(crate) const fn from_bits(value: u8) -> Self {
148 match value {
149 0 => CrcLength::Disabled,
150 8 => CrcLength::Bit8,
151 _ => CrcLength::Bit16,
152 }
153 }
154}
155
156#[cfg(feature = "defmt")]
157#[cfg(target_os = "none")]
158impl defmt::Format for CrcLength {
159 fn format(&self, fmt: defmt::Formatter) {
160 match self {
161 CrcLength::Disabled => defmt::write!(fmt, "disabled"),
162 CrcLength::Bit8 => defmt::write!(fmt, "8 bit"),
163 CrcLength::Bit16 => defmt::write!(fmt, "16 bit"),
164 }
165 }
166}
167
168impl Display for CrcLength {
169 fn fmt(&self, f: &mut Formatter<'_>) -> Result {
170 match self {
171 CrcLength::Disabled => write!(f, "disabled"),
172 CrcLength::Bit8 => write!(f, "8 bit"),
173 CrcLength::Bit16 => write!(f, "16 bit"),
174 }
175 }
176}
177
178#[derive(Clone, Copy, Debug, PartialEq)]
180pub enum FifoState {
181 Full,
183 Empty,
185 Occupied,
187}
188
189#[cfg(feature = "defmt")]
190#[cfg(target_os = "none")]
191impl defmt::Format for FifoState {
192 #[cfg(feature = "defmt")]
193 fn format(&self, fmt: defmt::Formatter) {
194 match self {
195 FifoState::Empty => defmt::write!(fmt, "Empty"),
196 FifoState::Full => defmt::write!(fmt, "Full"),
197 FifoState::Occupied => defmt::write!(fmt, "Occupied"),
198 }
199 }
200}
201
202impl Display for FifoState {
203 fn fmt(&self, f: &mut Formatter<'_>) -> Result {
204 match self {
205 FifoState::Empty => write!(f, "Empty"),
206 FifoState::Full => write!(f, "Full"),
207 FifoState::Occupied => write!(f, "Occupied"),
208 }
209 }
210}
211
212#[bitfield(u8, new = false, order = Msb)]
222pub struct StatusFlags {
223 #[bits(1)]
224 _padding: u8,
225
226 #[bits(1, access = RO)]
228 pub rx_dr: bool,
229
230 #[bits(1, access = RO)]
232 pub tx_ds: bool,
233
234 #[bits(1, access = RO)]
236 pub tx_df: bool,
237
238 #[bits(3, access = RO)]
239 pub(crate) rx_pipe: u8,
240
241 #[bits(1, access = RO)]
242 pub(crate) tx_full: bool,
243}
244
245#[cfg(feature = "defmt")]
246impl defmt::Format for StatusFlags {
247 fn format(&self, fmt: defmt::Formatter) {
248 defmt::write!(
249 fmt,
250 "StatusFlags rx_dr: {}, tx_ds: {}, tx_df: {}",
251 self.rx_dr,
252 self.tx_ds,
253 self.tx_df
254 )
255 }
256}
257
258impl StatusFlags {
259 pub(crate) const IRQ_MASK: u8 = 0x70;
261
262 pub fn new() -> Self {
265 Self::from_bits(0x70)
266 }
267
268 pub fn with_rx_dr(self, flag: bool) -> Self {
270 let new_val = self.into_bits() & !(1 << Self::RX_DR_OFFSET);
271 if flag {
272 Self::from_bits(new_val | (1 << Self::RX_DR_OFFSET))
273 } else {
274 Self::from_bits(new_val)
275 }
276 }
277
278 pub fn with_tx_ds(self, flag: bool) -> Self {
280 let new_val = self.into_bits() & !(1 << Self::TX_DS_OFFSET);
281 if flag {
282 Self::from_bits(new_val | (1 << Self::TX_DS_OFFSET))
283 } else {
284 Self::from_bits(new_val)
285 }
286 }
287
288 pub fn with_tx_df(self, flag: bool) -> Self {
290 let new_val = self.into_bits() & !(1 << Self::TX_DF_OFFSET);
291 if flag {
292 Self::from_bits(new_val | (1 << Self::TX_DF_OFFSET))
293 } else {
294 Self::from_bits(new_val)
295 }
296 }
297}
298
299impl Display for StatusFlags {
300 fn fmt(&self, f: &mut Formatter<'_>) -> Result {
301 write!(
302 f,
303 "StatusFlags rx_dr: {}, tx_ds: {}, tx_df: {}",
304 self.rx_dr(),
305 self.tx_ds(),
306 self.tx_df()
307 )
308 }
309}
310
311#[cfg(test)]
312mod test {
313 use crate::StatusFlags;
314
315 use super::{CrcLength, DataRate, FifoState, PaLevel};
316 extern crate std;
317 use std::{format, string::String};
318
319 fn display_crc(param: CrcLength, expected: String) -> bool {
320 format!("{param}") == expected
321 }
322
323 #[test]
324 fn crc_8bit() {
325 assert!(display_crc(CrcLength::Bit8, String::from("8 bit")));
326 }
327
328 #[test]
329 fn crc_16bit() {
330 assert!(display_crc(CrcLength::Bit16, String::from("16 bit")));
331 }
332
333 #[test]
334 fn crc_disable() {
335 assert!(display_crc(CrcLength::Disabled, String::from("disabled")));
336 }
337
338 fn display_fifo_state(param: FifoState, expected: String) -> bool {
339 format!("{param}") == expected
340 }
341
342 #[test]
343 fn fifo_state_empty() {
344 assert!(display_fifo_state(FifoState::Empty, String::from("Empty")));
345 }
346
347 #[test]
348 fn fifo_state_full() {
349 assert!(display_fifo_state(FifoState::Full, String::from("Full")));
350 }
351
352 #[test]
353 fn fifo_state_occupied() {
354 assert!(display_fifo_state(
355 FifoState::Occupied,
356 String::from("Occupied")
357 ));
358 }
359
360 fn display_data_rate(param: DataRate, expected: String) -> bool {
361 format!("{param}") == expected
362 }
363
364 #[test]
365 fn data_rate_1mbps() {
366 assert!(display_data_rate(DataRate::Mbps1, String::from("1 Mbps")));
367 }
368
369 #[test]
370 fn data_rate_2mbps() {
371 assert!(display_data_rate(DataRate::Mbps2, String::from("2 Mbps")));
372 }
373
374 #[test]
375 fn data_rate_250kbps() {
376 assert!(display_data_rate(
377 DataRate::Kbps250,
378 String::from("250 Kbps")
379 ));
380 }
381
382 fn display_pa_level(param: PaLevel, expected: String) -> bool {
383 format!("{param}") == expected
384 }
385
386 #[test]
387 fn pa_level_min() {
388 assert!(display_pa_level(PaLevel::Min, String::from("Min")));
389 }
390
391 #[test]
392 fn pa_level_low() {
393 assert!(display_pa_level(PaLevel::Low, String::from("Low")));
394 }
395
396 #[test]
397 fn pa_level_high() {
398 assert!(display_pa_level(PaLevel::High, String::from("High")));
399 }
400
401 #[test]
402 fn pa_level_max() {
403 assert!(display_pa_level(PaLevel::Max, String::from("Max")));
404 }
405
406 #[test]
407 fn display_flags() {
408 assert_eq!(
409 format!("{}", StatusFlags::default()),
410 String::from("StatusFlags rx_dr: false, tx_ds: false, tx_df: false")
411 );
412 }
413
414 fn set_flags(rx_dr: bool, tx_ds: bool, tx_df: bool) {
415 let flags = StatusFlags::default()
416 .with_rx_dr(rx_dr)
417 .with_tx_ds(tx_ds)
418 .with_tx_df(tx_df);
419 assert_eq!(flags.rx_dr(), rx_dr);
420 assert_eq!(flags.tx_ds(), tx_ds);
421 assert_eq!(flags.tx_df(), tx_df);
422 }
423
424 #[test]
425 fn flags_0x50() {
426 set_flags(true, false, true);
427 }
428
429 #[test]
430 fn flags_0x20() {
431 set_flags(false, true, false);
432 }
433}