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}