nrf24_rs/
nrf24.rs

1//! nRF24 implementations.
2
3use crate::config::{
4    AddressWidth, AutoRetransmission, DataPipe, DataRate, EncodingScheme, NrfConfig, PALevel,
5    PayloadSize,
6};
7use crate::error::TransceiverError;
8use crate::register_acces::{Instruction, Register};
9use crate::status::{Interrupts, Status};
10use crate::MAX_PAYLOAD_SIZE;
11use embedded_hal::{
12    delay::DelayNs,
13    digital::{ErrorType as PinErrorType, OutputPin},
14    spi::{ErrorType as SpiErrorType, Operation, SpiDevice},
15};
16
17/// The nRF24L01 driver type. This struct encapsulates all functionality.
18///
19/// For the different configuration options see: [`NrfConfig`].
20///
21/// # Examples
22/// ```
23/// use nrf24::Nrf24l01;
24/// use nrf24::config::NrfConfig;
25///
26/// // Initialize the chip with deafault configuration.
27/// let nrf24 = Nrf24l01::new(spi, ce, &mut delay, NrfConfig::default()).unwrap();
28///
29/// ```
30pub struct Nrf24l01<SPI, CE> {
31    spi: SPI,
32    // Chip Enable Pin
33    ce: CE,
34    // Config Register
35    config_reg: u8,
36    // Payload size
37    payload_size: PayloadSize,
38}
39
40// Associated type alias to simplify our result types.
41type NrfResult<T, SPI, CE> =
42    Result<T, TransceiverError<<SPI as SpiErrorType>::Error, <CE as PinErrorType>::Error>>;
43
44impl<SPI, CE> Nrf24l01<SPI, CE>
45where
46    SPI: SpiDevice,
47    CE: OutputPin,
48{
49    const MAX_ADDR_WIDTH: usize = 5;
50    const STATUS_RESET: u8 = 0b01110000;
51
52    /// Creates a new nRF24L01 driver with the given configuration.
53    ///
54    /// This function initializes the device, configures it according to the provided settings,
55    /// and performs validation to ensure proper communication with the chip. After initialization,
56    /// the device is powered up and ready to use.
57    ///
58    /// # Arguments
59    ///
60    /// * `spi` - SPI interface for communicating with the nRF24L01 chip, this type should implement
61    ///           the `SpiDevice` trait from `embedded_hal`
62    /// * `ce` - Chip Enable pin for controlling the chip's operating states
63    /// * `delay` - Delay provider for timing requirements during initialization
64    /// * `config` - Configuration settings for the chip (see [`NrfConfig`] for options)
65    ///
66    /// # Errors
67    ///
68    /// This function may return errors in the following situations:
69    /// * SPI communication errors
70    /// * Chip enable pin errors
71    /// * Communication errors with the module (e.g., incorrect configuration register values)
72    ///
73    /// # Examples
74    ///
75    /// ```
76    /// use nrf24::{Nrf24l01, SPI_MODE};
77    /// use nrf24::config::{NrfConfig, PALevel, DataRate};
78    ///
79    /// // Initialize hardware interfaces (platform-specific)
80    /// let spi = setup_spi(SPI_MODE);
81    /// let ce = setup_pin();
82    /// let mut delay = setup_delay();
83    ///
84    /// // Create custom configuration
85    /// let config = NrfConfig::default()
86    ///     .channel(76)
87    ///     .data_rate(DataRate::R2Mbps)
88    ///     .pa_level(PALevel::Low);
89    ///
90    /// // Initialize the nRF24L01 driver
91    /// match Nrf24l01::new(spi, ce, &mut delay, config) {
92    ///     Ok(nrf) => {
93    ///         // Successfully initialized
94    ///         // Continue with nrf.open_reading_pipe(), nrf.start_listening(), etc.
95    ///     },
96    ///     Err(e) => {
97    ///         // Handle initialization error
98    ///         panic!("Failed to initialize nRF24L01: {:?}", e);
99    ///     }
100    /// }
101    /// ```
102    ///
103    /// # Note
104    ///
105    /// The chip requires some settling time after power-up. This function
106    /// includes appropriate delays to ensure reliable initialization.
107    pub fn new<D: DelayNs>(
108        spi: SPI,
109        ce: CE,
110        delay: &mut D,
111        config: NrfConfig,
112    ) -> NrfResult<Self, SPI, CE> {
113        let mut chip = Nrf24l01 {
114            spi,
115            ce,
116            config_reg: 0,
117            payload_size: PayloadSize::Static(0),
118        };
119
120        // Set the output pin to the correct levels
121        chip.set_ce_low()?;
122
123        // Must allow the radio time to settle else configuration bits will not necessarily stick.
124        // This is actually only required following power up but some settling time also appears to
125        // be required after resets too. For full coverage, we'll always assume the worst.
126        // Enabling 16b CRC is by far the most obvious case if the wrong timing is used - or skipped.
127        // Technically we require 4.5ms + 14us as a worst case. We'll just call it 5ms for good measure.
128        delay.delay_ms(5);
129
130        // Set retries
131        chip.set_retries(config.auto_retry)?;
132        // Set rf
133        chip.setup_rf(config.data_rate, config.pa_level)?;
134        // Set payload size
135        chip.set_payload_size(config.payload_size)?;
136        // Set address length
137        chip.set_address_width(config.addr_width)?;
138        // Reset status
139        chip.reset_status()?;
140        // This channel should be universally safe and not bleed over into adjacent spectrum.
141        chip.set_channel(config.channel)?;
142        // flush buffers
143        chip.flush_rx()?;
144        chip.flush_tx()?;
145
146        // The value the config register should be: power up bit + crc encoding
147        let config_val = (1 << 1) | config.crc_encoding_scheme.scheme();
148
149        // clear CONFIG register, Enable PTX, Power Up & set CRC
150        chip.write_register(Register::CONFIG, config_val)?;
151
152        // wait for startup
153        delay.delay_ms(5);
154
155        chip.config_reg = chip.read_register(Register::CONFIG)?;
156
157        if chip.config_reg != config_val {
158            Err(TransceiverError::Comm(chip.config_reg))
159        } else {
160            Ok(chip)
161        }
162    }
163
164    /// Checks if the chip is connected to the SPI bus.
165    /// # Examples
166    /// ```rust
167    /// if !chip.is_connected()? {
168    ///     // Handle disconnection
169    /// }
170    /// ```
171    pub fn is_connected(&mut self) -> NrfResult<bool, SPI, CE> {
172        self.read_register(Register::SETUP_AW)
173            .map(|aw| aw == 0b1 || aw == 0b10 || aw == 0b11)
174    }
175
176    /// Opens a reading pipe for reading data on an address.
177    ///
178    /// # Examples
179    /// ```rust
180    /// chip.open_reading_pipe(DataPipe::DP0, b"Node1")?;
181    /// ```
182    ///
183    /// `pipe` can either be an instance of the type [`DataPipe`] or an integer.
184    /// Note that if an integer is provided, numbers higher than 5 will default to reading pipe 0.
185    ///
186    /// # Warnings
187    /// You have to call this before calling [`start_listening()`](#method.start_listening).
188    pub fn open_reading_pipe<T: Into<DataPipe>>(
189        &mut self,
190        pipe: T,
191        mut addr: &[u8],
192    ) -> NrfResult<(), SPI, CE> {
193        let pipe = pipe.into();
194        if addr.len() > Self::MAX_ADDR_WIDTH {
195            addr = &addr[0..Self::MAX_ADDR_WIDTH];
196        }
197
198        // Get the memory map address corresponding to the data pipe.
199        let rx_address_reg: Register = pipe.into();
200        match pipe {
201            DataPipe::DP0 | DataPipe::DP1 => self.write_register(rx_address_reg, addr)?,
202            _ => self.write_register(rx_address_reg, addr[0])?,
203        }
204
205        // Enable corresponding RX Addr
206        let old_reg = self.read_register(Register::EN_RXADDR)?; // Read old value
207        self.write_register(Register::EN_RXADDR, old_reg | (1 << pipe.pipe()))?; // Update
208
209        Ok(())
210    }
211
212    /// Opens a writing pipe for writing data to an address.
213    /// # Examples
214    /// ```rust
215    /// // Open writing pipe for address "Node1"
216    /// chip.open_writing_pipe(b"Node1")?;
217    /// ```
218    /// # Warnings
219    /// Must be called before writing data.
220    pub fn open_writing_pipe(&mut self, mut addr: &[u8]) -> NrfResult<(), SPI, CE> {
221        if addr.len() > Self::MAX_ADDR_WIDTH {
222            addr = &addr[0..Self::MAX_ADDR_WIDTH];
223        }
224        // We need to open Reading Pipe 0 with the same address name
225        // because ACK messages will be recieved on this channel
226        self.write_register(Register::RX_ADDR_P0, addr)?;
227        // Open writing pipe
228        self.write_register(Register::TX_ADDR, addr)?;
229
230        Ok(())
231    }
232
233    /// Starts listening on the pipes that are opened for reading.
234    /// Used in Receiver Mode.
235    ///
236    /// # Examples
237    /// ```rust
238    /// // First open data pipe 0 with address "Node1"
239    /// chip.open_reading_pipe(DataPipe::DP0, b"Node1")?;
240    /// // Configure the chip to listening modes (non blocking)
241    /// chip.start_listening()
242    /// // Now we can check for available messages and read them
243    /// ```
244    /// # Warnings
245    /// Make sure at least one pipe is opened for reading using the [`open_reading_pipe()`](#method.open_reading_pipe) method.
246    ///
247    // TODO: Use the type system to make start and stop listening by RAII and Drop
248    pub fn start_listening(&mut self) -> NrfResult<(), SPI, CE> {
249        // Enable RX listening flag
250        self.config_reg |= 0b1;
251        self.write_register(Register::CONFIG, self.config_reg)?;
252        // Flush interrupts
253        self.reset_status()?;
254
255        self.set_ce_high()?;
256
257        Ok(())
258    }
259
260    /// Stops listening.
261    ///
262    /// # Examples
263    /// ```rust
264    /// // Configure chip and start listening
265    /// chip.open_reading_pipe(DataPipe::DP0, b"Node1")?;
266    /// chip.start_listening()?;
267    /// // ... read data
268    /// // Reading is done, now we can stop listening
269    /// chip.stop_listening()?;
270    /// ```
271    ///
272    // TODO: Use the type system to make start and stop listening by RAII and Drop
273    pub fn stop_listening(&mut self) -> NrfResult<(), SPI, CE> {
274        self.set_ce_low()?;
275
276        self.config_reg &= !0b1;
277        self.write_register(Register::CONFIG, self.config_reg)?;
278
279        Ok(())
280    }
281
282    /// Checks if there are any bytes available to be read.
283    ///
284    /// # Examples
285    /// ```rust
286    /// // Chip has to be set in listening mode first
287    /// chip.open_reading_pipe(DataPipe::DP0, b"Node1")?;
288    /// chip.start_listening()?;
289    /// // Check if there is any data to read
290    /// while chip.data_available()? {
291    ///     // ... read the payload
292    ///     delay.delay_ms(50); // small delay between calls of data_available
293    /// }
294    /// ```
295    ///
296    /// # Notes
297    /// If data_available is called in too rapid succession, the chip can glitch out.
298    /// If this is the case, just add a small delay between calling successive `data_available`.
299    pub fn data_available(&mut self) -> NrfResult<bool, SPI, CE> {
300        Ok(self.data_available_on_pipe()?.is_some())
301    }
302
303    /// Returns the data pipe where the data is available and `None` if no data available.
304    ///
305    /// # Examples
306    /// ```rust
307    /// // Chip has to be set in listening mode first
308    /// chip.open_reading_pipe(DataPipe::DP0, b"Node1")?;
309    /// chip.start_listening()?;
310    /// // Check if there is any data to read on pipe 1
311    /// while let Some(pipe) = chip.data_available_on_pipe()? {
312    ///     if pipe == DataPipe::DP1 {
313    ///         // ... read the payload
314    ///         delay.delay_ms(50); // small delay between calls of data_available
315    ///     }
316    /// }
317    /// ```
318    pub fn data_available_on_pipe(&mut self) -> NrfResult<Option<DataPipe>, SPI, CE> {
319        Ok(self.status()?.data_pipe_available())
320    }
321
322    /// Reads the available payload. To check if there are any payloads available, call
323    /// [`data_available()`](#method.data_available).
324    ///
325    /// Make sure the chip is configured in listening mode and at
326    /// least one data pipe is opened for reading, see:
327    /// * [`open_reading_pipe()`](#method.open_reading_pipe)
328    /// * [`start_listening()`](#method.start_listening)
329    ///
330    /// Returns the number of bytes read into the buffer.
331    ///
332    /// # Examples
333    /// ```rust
334    /// // We will be receiving float values
335    /// // Set the payload size to 4 bytes, the size of an f32
336    /// let config = NrfConfig::default().payload_size(PayloadSize::Static(4));
337    /// let chip = Nrf24l01::new(spi, ce, &mut delay, config).unwrap();
338    /// // Put the chip in listening mode
339    /// chip.open_reading_pipe(DataPipe::DP0, b"Node1");
340    /// chip.start_listening();
341    ///
342    /// // The buffer where we will read the data into
343    /// let mut buffer = [0u8; 4];
344    /// loop {
345    ///     // Keep reading data if any is available
346    ///     while let Ok(true) = chip.data_available() {
347    ///         match chip.read(&mut buffer) {
348    ///             Err(e) => eprintln!("Error while reading data from buffer: {:?}", e),
349    ///             Ok(n) => {
350    ///                 println!("Successfully read {} bytes of data!", n);
351    ///                 assert_eq!(n, 4);
352    ///                 // reinterpret memory as a float
353    ///                 let f = f32::from_le_bytes(buffer);
354    ///                 println!("Received value: {}", f);
355    ///             },
356    ///         }
357    ///     }
358    ///     // Wait some time before trying again
359    ///     delay.delay_us(50);
360    /// }
361    /// ```
362    pub fn read(&mut self, buf: &mut [u8]) -> NrfResult<usize, SPI, CE> {
363        let len = match self.payload_size {
364            PayloadSize::Static(n) => {
365                // Ensure buffer is large enough
366                if buf.len() < n as usize {
367                    return Err(TransceiverError::BufferTooSmall {
368                        required: n,
369                        actual: buf.len() as u8,
370                    });
371                }
372                n as usize
373            }
374            PayloadSize::Dynamic => core::cmp::min(buf.len(), MAX_PAYLOAD_SIZE as usize),
375        };
376
377        // Write to spi
378        self.spi
379            .transaction(&mut [
380                Operation::Write(&[Instruction::RRX.opcode()]),
381                Operation::Read(&mut buf[..len]),
382            ])
383            .map_err(TransceiverError::Spi)?;
384
385        Ok(len)
386    }
387
388    /// Writes data to the opened channel.
389    ///
390    /// # Examples
391    /// ```rust
392    /// // We will be sending float values
393    /// // Set the payload size to 4 bytes, the size of an f32
394    /// let config = NrfConfig::default().payload_size(PayloadSize::Static(4));
395    /// let chip = Nrf24l01::new(spi, ce, &mut delay, config).unwrap();
396    /// // Put the chip in transmission mode
397    /// chip.open_writing_pipe(b"Node1");
398    /// chip.stop_listening();
399    ///
400    /// // The buffer where we will write data into before sending
401    /// let mut buffer = [0u8; 4];
402    /// loop {
403    ///     let f = get_reading(); // data from some sensor
404    ///     // reinterpret float to bytes and put into buffer
405    ///     buffer.copy_from_slice(&f.to_le_bytes());
406    ///
407    ///     match chip.write(&mut delay, &buffer) {
408    ///         Err(e) => eprintln!("Error while sending data {:?}", e),
409    ///         Ok(_) => {
410    ///             println!("Successfully wrote the data!");
411    ///         },
412    ///     }
413    ///     // Wait some time before trying again
414    ///     delay.delay_us(50);
415    /// }
416    /// ```
417    ///
418    /// Will clear all interrupt flags after write.
419    /// Returns an error when max retries have been reached.
420    pub fn write<D: DelayNs>(&mut self, delay: &mut D, buf: &[u8]) -> NrfResult<(), SPI, CE> {
421        let send_count = match self.payload_size {
422            PayloadSize::Static(n) => {
423                // we have to send `n` bytes
424                if buf.len() < n as usize {
425                    return Err(TransceiverError::BufferTooSmall {
426                        required: n,
427                        actual: buf.len() as u8,
428                    });
429                }
430                n as usize
431            }
432            PayloadSize::Dynamic => {
433                // In dynamic payload mode, max payload_size is the limit
434                core::cmp::min(buf.len(), MAX_PAYLOAD_SIZE as usize)
435            }
436        };
437
438        let status = self.send_command_bytes(Instruction::WTX, &buf[..send_count])?;
439
440        // Start transmission:
441        // pulse CE pin to signal transmission start
442        self.set_ce_high()?;
443        delay.delay_us(10);
444        self.set_ce_low()?;
445
446        // Clear interrupt flags
447        self.write_register(Register::STATUS, Interrupts::all().raw())?;
448
449        // Max retries exceeded
450        if status.reached_max_retries() {
451            self.flush_tx()?;
452            return Err(TransceiverError::MaxRetries);
453        }
454
455        Ok(())
456    }
457
458    /// Setup of automatic retransmission.
459    ///
460    /// # Arguments
461    /// * `delay` is the auto retransmit delay.
462    /// Values can be between 0 and 15.
463    /// The delay before a retransmit is initiated, is calculated according to the following formula:
464    /// > ((**delay** + 1) * 250) + 86 µs
465    ///
466    /// * `count` is number of times there will be an auto retransmission.
467    /// Must be a value between 0 and 15.
468    ///
469    /// # Examples
470    /// ```rust
471    /// // Set the auto transmit delay to (5 + 1) * 250) + 86 = 1586µs
472    /// // and the retransmit count to 15.
473    /// nrf24l01.set_retries((5, 15))?;
474    /// ```
475    pub fn set_retries<T: Into<AutoRetransmission>>(
476        &mut self,
477        auto_retry: T,
478    ) -> NrfResult<(), SPI, CE> {
479        let auto_retry = auto_retry.into();
480        self.write_register(
481            Register::SETUP_RETR,
482            (auto_retry.raw_delay() << 4) | (auto_retry.count()),
483        )
484    }
485
486    /// Returns the auto retransmission config.
487    ///
488    /// # Examples
489    /// ```rust
490    /// // Initialize the chip
491    /// let mut chip = Nrf24l01::new(spi_struct, ce_pin, delay, NrfConfig::default())?;
492    ///
493    /// let retries_config = chip.retries()?;
494    /// // Default values for the chip
495    /// assert_eq!(retries_config.delay(), 1586);
496    /// assert_eq!(retries_config.count(), 15);
497    /// ```
498    pub fn retries(&mut self) -> NrfResult<AutoRetransmission, SPI, CE> {
499        self.read_register(Register::SETUP_RETR)
500            .map(AutoRetransmission::from_register)
501    }
502
503    /// Set the frequency channel nRF24L01 operates on.
504    ///
505    /// # Arguments
506    ///
507    /// * `channel` number between 0 and 127.
508    ///
509    /// # Examples
510    /// ```rust
511    /// nrf24l01.set_channel(74)?;
512    /// ```
513    pub fn set_channel(&mut self, channel: u8) -> NrfResult<(), SPI, CE> {
514        self.write_register(Register::RF_CH, (u8::MAX >> 1) & channel)
515    }
516
517    /// Return the frequency channel nRF24L01 operates on.
518    /// Note that the actual frequency will we the channel +2400 MHz.
519    ///
520    /// # Examples
521    /// ```rust
522    /// // Initialize the chip
523    /// let mut chip = Nrf24l01::new(spi_struct, ce_pin, delay, NrfConfig::default())?;
524    /// // Default is channel 76
525    /// assert_eq!(chip.channel()?, 76);
526    /// ```
527    pub fn channel(&mut self) -> NrfResult<u8, SPI, CE> {
528        self.read_register(Register::RF_CH)
529    }
530
531    /// Set the address width, saturating values above or below allowed range.
532    ///
533    /// # Arguments
534    ///
535    /// * `width` number between 3 and 5.
536    ///
537    /// # Examples
538    /// ```rust
539    /// nrf24l01.set_address_width(5)?;
540    /// ```
541    pub fn set_address_width<T>(&mut self, width: T) -> NrfResult<(), SPI, CE>
542    where
543        T: Into<AddressWidth>,
544    {
545        let width = width.into();
546        self.write_register(Register::SETUP_AW, width.value())
547    }
548
549    /// Returns the current data rate as a [`DataRate`] enum.
550    ///
551    /// # Examples
552    /// ```rust
553    /// // Initialize the chip
554    /// let mut chip = Nrf24l01::new(spi_struct, ce_pin, delay, NrfConfig::default())?;
555    /// // Default is 2 Mb/s
556    /// assert_eq!(chip.data_rate()?, DataRate::R2Mbps);
557    /// ```
558    pub fn data_rate(&mut self) -> NrfResult<DataRate, SPI, CE> {
559        self.read_register(Register::RF_SETUP).map(DataRate::from)
560    }
561
562    /// Returns the current power amplifier level as a [`PALevel`] enum.
563    ///
564    /// # Examples
565    /// ```rust
566    /// // Initialize the chip
567    /// let mut chip = Nrf24l01::new(spi_struct, ce_pin, delay, NrfConfig::default())?;
568    /// // Default is Min PALevel
569    /// assert_eq!(chip.power_amp_level()?, PALevel::Min);
570    /// ```
571    pub fn power_amp_level(&mut self) -> NrfResult<PALevel, SPI, CE> {
572        self.read_register(Register::RF_SETUP).map(PALevel::from)
573    }
574
575    /// Flush transmission FIFO, used in TX mode.
576    ///
577    /// # Examples
578    /// ```rust
579    /// chip.flush_tx()?;
580    /// ```
581    pub fn flush_tx(&mut self) -> NrfResult<(), SPI, CE> {
582        self.send_command(Instruction::FTX).map(|_| ())
583    }
584
585    /// Flush reciever FIFO, used in RX mode.
586    ///
587    /// # Examples
588    /// ```rust
589    /// nrf24l01.flush_rx()?;
590    /// ```
591    pub fn flush_rx(&mut self) -> NrfResult<(), SPI, CE> {
592        self.send_command(Instruction::FRX).map(|_| ())
593    }
594
595    /// Enable CRC encoding scheme.
596    ///
597    /// # Examples
598    /// ```rust
599    /// chip.enable_crc(EncodingScheme::R2Bytes)?;
600    /// ```
601    pub fn enable_crc(&mut self, scheme: EncodingScheme) -> NrfResult<(), SPI, CE> {
602        // Set the crc encoding bits to 0 first
603        self.config_reg &= !EncodingScheme::bitmask();
604        // Now set the right bits
605        self.config_reg |= scheme.scheme();
606        self.write_register(Register::CONFIG, self.config_reg)
607    }
608
609    /// Get the CRC encoding scheme
610    ///
611    /// # Examples
612    /// ```rust
613    /// match chip.crc_encoding_scheme()? {
614    ///     EncodingScheme::NoRedundancyCheck => println("No crc check"),
615    ///     EncodingScheme::R1Byte => println("8 bit check"),
616    ///     EncodingScheme::R2Bytes => println("16 bit check"),
617    /// };
618    /// ```
619    pub fn crc_encoding_scheme(&mut self) -> NrfResult<EncodingScheme, SPI, CE> {
620        self.read_register(Register::CONFIG).map(From::from)
621    }
622
623    /// Sets the payload size in bytes.
624    /// This can either be static with a set size, or dynamic.
625    ///
626    /// `payload_size` can either be an instance of the [`PayloadSize`] enum, or an integer.
627    ///
628    /// # Notes
629    /// * A value of 0 means the dynamic payloads will be enabled.
630    /// * Values bigger than [`MAX_PAYLOAD_SIZE`](constant.MAX_PAYLOAD_SIZE.html) will be set to the maximum.
631    ///
632    /// # Examples
633    /// ```rust
634    /// // Two equal methods to set the chip to dynamic payload mode.
635    /// chip.set_payload_size(PayloadSize::Dynamic)?;
636    /// chip.set_payload_size(0)?;
637    /// // Following methods set a static payload size.
638    /// chip.set_payload_size(12)?; // Messages will be 12 bytes
639    /// chip.set_payload_size(PayloadSize::Static(12))?; // Same as previous
640    /// chip.set_payload_size(49)?; // Messages will be `MAX_PAYLOAD_SIZE`
641    /// ```
642    pub fn set_payload_size<T: Into<PayloadSize>>(
643        &mut self,
644        payload_size: T,
645    ) -> NrfResult<(), SPI, CE> {
646        let payload_size = payload_size.into().truncate();
647        match payload_size {
648            PayloadSize::Static(payload_size) => {
649                if self.payload_size == PayloadSize::Dynamic {
650                    // currently dynamic payload enabled
651                    // Disable dynamic payloads
652                    let feature = self.read_register(Register::FEATURE)?;
653                    self.write_register(Register::FEATURE, feature & !(1 << 2))?;
654                }
655
656                self.write_register(Register::RX_PW_P0, payload_size)?;
657                self.write_register(Register::RX_PW_P1, payload_size)?;
658                self.write_register(Register::RX_PW_P2, payload_size)?;
659                self.write_register(Register::RX_PW_P3, payload_size)?;
660                self.write_register(Register::RX_PW_P4, payload_size)?;
661                self.write_register(Register::RX_PW_P5, payload_size)?;
662            }
663            PayloadSize::Dynamic => {
664                let feature = self.read_register(Register::FEATURE)?;
665                self.write_register(Register::FEATURE, feature | (1 << 2))?;
666                self.write_register(Register::DYNPD, 0b0001_1111)?; // enable on all pipes
667            }
668        }
669        self.payload_size = payload_size;
670        Ok(())
671    }
672
673    /// Returns the payload size as a [`PayloadSize`] enum.
674    ///
675    /// # Examples
676    /// ```rust
677    /// // Initialize chip
678    /// let mut chip = Nrf24l01::new(spi_struct, ce_pin, delay, NrfConfig::default())?;
679    /// // Default payload size is MAX_PAYLOAD_SIZE
680    /// assert_eq!(chip.payload_size()?, PayloadSize::Static(MAX_PAYLOAD_SIZE));
681    /// ```
682    pub fn payload_size(&self) -> PayloadSize {
683        self.payload_size
684    }
685
686    /// Powers the chip up. Note that a new initialized device will already be in power up mode, so
687    /// calling [`power_up()`](#method.power_up) is not necessary.
688    ///
689    /// Should be called after [`power_down()`](#method.power_down) to put the chip back into power up mode.
690    ///
691    /// # Examples
692    /// ```rust
693    /// // Go to sleep
694    /// chip.power_down(&mut delay)?;
695    /// // Zzz
696    /// // ...
697    /// chip.power_up(&mut delay)?; // power back up
698    /// ```
699    pub fn power_up<D: DelayNs>(&mut self, delay: &mut D) -> NrfResult<(), SPI, CE> {
700        // if not powered up, power up and wait for the radio to initialize
701        if !self.is_powered_up() {
702            // update the stored config register
703            self.config_reg |= 1 << 1;
704            self.write_register(Register::CONFIG, self.config_reg)?;
705
706            delay.delay_ms(5);
707        }
708        Ok(())
709    }
710
711    /// Powers the chip down. This is the low power mode.
712    /// The chip will consume approximatly 900nA.
713    ///
714    /// To power the chip back up, call [`power_up()`](#method.power_up).
715    ///
716    /// # Examples
717    /// ```rust
718    /// // Go to sleep
719    /// chip.power_down(&mut delay)?;
720    /// // Zzz
721    /// // ...
722    /// chip.power_up(&mut delay)?; // power back up
723    /// ```
724    pub fn power_down(&mut self) -> NrfResult<(), SPI, CE> {
725        self.set_ce_low()?;
726        self.config_reg &= !(1 << 1);
727        self.write_register(Register::CONFIG, self.config_reg)?;
728        Ok(())
729    }
730
731    /// Reads the status register from device. See [`Status`].
732    pub fn status(&mut self) -> NrfResult<Status, SPI, CE> {
733        self.send_command(Instruction::NOP)
734    }
735
736    /// Resets the following flags in the status register:
737    /// - data ready RX fifo interrupt
738    /// - data sent TX fifo interrupt
739    /// - maximum number of retries interrupt
740    pub fn reset_status(&mut self) -> NrfResult<(), SPI, CE> {
741        self.write_register(Register::STATUS, Self::STATUS_RESET)
742    }
743
744    /// Masks the selected interrupt flags.
745    ///
746    /// By default, the IRQ pin will pull low when one of the following events occur:
747    /// - Maximum number of retries is reached
748    /// - Transmission data is sent
749    /// - Receiver data is avaiable to be read
750    ///
751    /// This function allows you to disable these interrupts.
752    ///
753    /// # Note
754    /// Masking an interrupt doesn't prevent the event from occurring or prevent the status flag from being set.
755    /// It only prevents the external IRQ pin from triggering.
756    /// You can still read the status register to see if the event occurred, even if the interrupt is masked.
757    ///
758    /// # Examples
759    /// ```rust
760    /// let interrupts = Interrupts::new().max_retries().rx_data_ready();
761    /// chip.mask_interrupts(interrupts)?;
762    /// ```
763    /// Disable all interrupts.
764    /// ```rust
765    /// let interrupts = Interrupts::all();
766    /// chip.mask_interrupt(interrupts);
767    /// ```
768    pub fn mask_interrupts(&mut self, irq: Interrupts) -> NrfResult<(), SPI, CE> {
769        // Clear interrupt flags
770        self.config_reg &= !Interrupts::all().raw();
771        // Set configured interrupt mask
772        self.config_reg |= irq.raw();
773        self.write_register(Register::STATUS, self.config_reg)?;
774        Ok(())
775    }
776
777    /// Query which interrupts were triggered.
778    ///
779    /// Clears the interrupt request flags, so new ones can come in.
780    pub fn interrupt_src(&mut self) -> NrfResult<Interrupts, SPI, CE> {
781        let status = self.status()?;
782        // Clear flags
783        self.write_register(Register::STATUS, Interrupts::all().raw())?;
784        Ok(Interrupts::from(status.raw()))
785    }
786
787    /// Reads the config from the device and returns it in a `NrfConfig` struct.
788    /// Can be used to log the configuration when using `defmt` feature.
789    pub fn read_config(&mut self) -> NrfResult<NrfConfig, SPI, CE> {
790        let addr_width = AddressWidth::from_register(self.read_register(Register::SETUP_AW)?);
791        let config = NrfConfig::default()
792            .payload_size(self.payload_size)
793            .channel(self.channel()?)
794            .addr_width(addr_width)
795            .data_rate(self.data_rate()?)
796            .pa_level(self.power_amp_level()?)
797            .crc_encoding_scheme(self.crc_encoding_scheme()?)
798            .auto_retry(self.retries()?);
799        Ok(config)
800    }
801
802    /// Sends an instruction over the SPI bus without extra data.
803    ///
804    /// Returns the status recieved from the device.
805    /// Normally used for the other instructions than read and write.  
806    fn send_command(&mut self, instruction: Instruction) -> NrfResult<Status, SPI, CE> {
807        self.send_command_bytes(instruction, &[])
808    }
809
810    fn send_command_bytes(
811        &mut self,
812        instruction: Instruction,
813        buf: &[u8],
814    ) -> NrfResult<Status, SPI, CE> {
815        let mut status_buf = [instruction.opcode()];
816        self.spi
817            .transaction(&mut [
818                Operation::TransferInPlace(&mut status_buf),
819                Operation::Write(buf),
820            ])
821            .map_err(TransceiverError::Spi)?;
822        Ok(Status::from(status_buf[0]))
823    }
824
825    /// Writes values to a given register.
826    ///
827    /// This can be anything that can be turned into a buffer of u8's.
828    /// `IntoBuf` is currently implemented for T and for &[T].
829    /// This means that this function can be polymorphically called for single value writes as well
830    /// as for arrays.
831    fn write_register<T: IntoBuf<u8>>(
832        &mut self,
833        register: Register,
834        buf: T,
835    ) -> NrfResult<(), SPI, CE> {
836        self.spi
837            .transaction(&mut [
838                Operation::Write(&[Instruction::WR.opcode() | register.addr()]),
839                Operation::Write(buf.into_buf()),
840            ])
841            .map_err(TransceiverError::Spi)
842    }
843
844    fn read_register(&mut self, register: Register) -> NrfResult<u8, SPI, CE> {
845        let mut buf = [0_u8];
846        self.spi
847            .transaction(&mut [
848                Operation::Write(&[Instruction::RR.opcode() | register.addr()]),
849                Operation::Read(&mut buf),
850            ])
851            .map_err(TransceiverError::Spi)?;
852        Ok(buf[0])
853    }
854
855    fn setup_rf(&mut self, data_rate: DataRate, level: PALevel) -> NrfResult<(), SPI, CE> {
856        self.write_register(Register::RF_SETUP, data_rate.rate() | level.level())
857    }
858
859    fn is_powered_up(&self) -> bool {
860        self.config_reg & (1 << 1) != 0
861    }
862}
863
864/// Helper functions for setting Chip Enable pin.
865/// Returns the error enum defined in this crate, so the rest of the code can use the
866/// `?` operator.
867impl<SPI, CE> Nrf24l01<SPI, CE>
868where
869    SPI: SpiDevice,
870    CE: OutputPin,
871{
872    fn set_ce_high(&mut self) -> NrfResult<(), SPI, CE> {
873        self.ce.set_high().map_err(TransceiverError::Ce)
874    }
875    fn set_ce_low(&mut self) -> NrfResult<(), SPI, CE> {
876        self.ce.set_low().map_err(TransceiverError::Ce)
877    }
878}
879
880/// A trait representing a type that can be turned into a buffer.
881///
882/// Is used for representing single values as well as slices as buffers.
883trait IntoBuf<T> {
884    fn into_buf(&self) -> &[T];
885}
886
887impl<T> IntoBuf<T> for T {
888    fn into_buf(&self) -> &[T] {
889        core::slice::from_ref(self)
890    }
891}
892impl<T> IntoBuf<T> for &[T] {
893    fn into_buf(&self) -> &[T] {
894        self
895    }
896}