File Coverage

blib/lib/Device/Chip/nRF24L01P.pm
Criterion Covered Total %
statement 230 266 86.4
branch 20 42 47.6
condition 8 20 40.0
subroutine 35 40 87.5
pod 19 21 90.4
total 312 389 80.2


line stmt bran cond sub pod time code
1             # You may distribute under the terms of either the GNU General Public License
2             # or the Artistic License (the same terms as Perl itself)
3             #
4             # (C) Paul Evans, 2014-2023 -- leonerd@leonerd.org.uk
5              
6 6     6   1611000 use v5.26;
  6         77  
7 6     6   37 use warnings;
  6         12  
  6         235  
8 6     6   718 use Object::Pad 0.800;
  6         11608  
  6         373  
9              
10             package Device::Chip::nRF24L01P 0.08;
11             class Device::Chip::nRF24L01P
12 1     1   635 :isa(Device::Chip);
  1         81536  
  1         56  
13              
14 6     6   1947 use Carp;
  6         16  
  6         423  
15 6     6   3232 use Data::Bitfield qw( bitfield boolfield enumfield intfield );
  6         13967  
  6         475  
16              
17 6     6   48 use Future::AsyncAwait;
  6         14  
  6         37  
18              
19 6     6   404 use constant PROTOCOL => "SPI";
  6         12  
  6         3930  
20              
21             =head1 NAME
22              
23             C - chip driver for a F
24              
25             =head1 DESCRIPTION
26              
27             This L subclass provides specific communication to a
28             F F chip attached to a computer via an SPI
29             adapter.
30              
31             The reader is presumed to be familiar with the general operation of this chip;
32             the documentation here will not attempt to explain or define chip-specific
33             concepts or features, only the use of this module to access them.
34              
35             =cut
36              
37             =head1 MOUNT PARAMETERS
38              
39             =head2 ce
40              
41             The name of the GPIO line on the adapter that is connected to the Chip Enable
42             (CE) pin. This module defaults to using the C line on a F, or
43             C on an F; for other adapter types the parameter will have to
44             be supplied.
45              
46             =cut
47              
48             my %DEFAULT_CE = (
49             'Device::Chip::Adapter::BusPirate' => "AUX",
50             'Device::Chip::Adapter::FTDI' => "D4",
51             );
52              
53             field $_gpio_ce;
54              
55 5         11 async method mount ( $adapter, %params )
  5         13  
  5         10  
  5         8  
56 5         21 {
57 5   33     54 my $ce_pin = $params{ce} // $DEFAULT_CE{ref $adapter} // "CE";
      50        
58              
59 5         13 $_gpio_ce = $ce_pin;
60              
61 5         70 await $self->SUPER::mount( $adapter, %params );
62              
63 5         1290 await $self->protocol->write_gpios( { $ce_pin => 0 } );
64              
65 5         47971 return $self;
66 5     5 1 891 }
67              
68             method SPI_options
69 5     5 0 2168 {
70             return (
71 5         38 mode => 0,
72             max_bitrate => 1E6,
73             );
74             }
75              
76             =head1 METHODS
77              
78             The following methods documented in an C expression return L
79             instances.
80              
81             =cut
82              
83 0     0 0 0 async method power ( $on ) { await $self->protocol->power( $on ) }
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
84              
85             # Commands
86             use constant {
87 6         1674 CMD_R_REGISTER => 0x00,
88             CMD_W_REGISTER => 0x20,
89             CMD_R_RX_PAYLOAD => 0x61,
90             CMD_W_TX_PAYLOAD => 0xA0,
91             CMD_FLUSH_TX => 0xE1,
92             CMD_FLUSH_RX => 0xE2,
93             CMD_REUSE_TX_PL => 0xE3,
94             CMD_R_RX_PL_WID => 0x60,
95             CMD_W_ACK_PAYLOAD => 0xA8,
96             CMD_W_TX_PAYLOAD_NO_ACK => 0xB0,
97             CMD_NOP => 0xFF,
98 6     6   54 };
  6         16  
99              
100             # Register numbers and lengths, and bitfields
101             use constant {
102 6         43296 REG_CONFIG => [ 0x00, 1 ], # bitfield
103             REG_EN_AA => [ 0x01, 1 ], # per-pipe bitmask
104             REG_EN_RXADDR => [ 0x02, 1 ], # per-pipe bitmask
105             REG_SETUP_AW => [ 0x03, 1 ], # bitfield
106             REG_SETUP_RETR => [ 0x04, 1 ], # bitfield
107             REG_RF_CH => [ 0x05, 1 ], # int
108             REG_RF_SETUP => [ 0x06, 1 ], # bitfield
109             REG_STATUS => [ 0x07, 1 ], # bitfield
110             REG_OBSERVE_TX => [ 0x08, 1 ], # bitfield
111             REG_RPD => [ 0x09, 1 ], # bool
112             REG_RX_ADDR_P0 => [ 0x0A, 5 ], # addresses
113             REG_RX_ADDR_P1 => [ 0x0B, 5 ],
114             REG_RX_ADDR_P2 => [ 0x0C, 1 ],
115             REG_RX_ADDR_P3 => [ 0x0D, 1 ],
116             REG_RX_ADDR_P4 => [ 0x0E, 1 ],
117             REG_RX_ADDR_P5 => [ 0x0F, 1 ],
118             REG_TX_ADDR => [ 0x10, 5 ],
119             REG_RX_PW_P0 => [ 0x11, 1 ], # ints
120             REG_RX_PW_P1 => [ 0x12, 1 ],
121             REG_RX_PW_P2 => [ 0x13, 1 ],
122             REG_RX_PW_P3 => [ 0x14, 1 ],
123             REG_RX_PW_P4 => [ 0x15, 1 ],
124             REG_RX_PW_P5 => [ 0x16, 1 ],
125             REG_FIFO_STATUS => [ 0x17, 1 ], # bitfield
126             REG_DYNPD => [ 0x1C, 1 ], # per-pipe bitmask
127             REG_FEATURE => [ 0x1D, 1 ], # bitfield
128 6     6   123 };
  6         18  
129              
130             bitfield { unrecognised_ok => 1 }, CONFIG =>
131             MASK_RX_DR => boolfield(6),
132             MASK_TX_DS => boolfield(5),
133             MASK_MAX_RT => boolfield(4),
134             EN_CRC => boolfield(3),
135             CRCO => enumfield(2, 1, 2 ),
136             PWR_UP => boolfield(1),
137             PRIM_RX => boolfield(0);
138              
139             bitfield { unrecognised_ok => 1 }, SETUP_AW =>
140             AW => enumfield(0, undef, 3, 4, 5 );
141              
142             bitfield { unrecognised_ok => 1 }, SETUP_RETR =>
143             ARD => enumfield(4, map { ( $_ + 1 ) * 250 } 0 .. 15),
144             ARC => intfield(0, 4);
145              
146             bitfield { unrecognised_ok => 1 }, RF_SETUP =>
147             CONT_WAVE => boolfield(7),
148             RF_DR_LOW => boolfield(5),
149             PLL_LOCK => boolfield(4),
150             RF_DR_HIGH => boolfield(3),
151             RF_PWR => enumfield(1, -18, -12, -6, 0 );
152              
153             bitfield STATUS =>
154             RX_DR => boolfield(6),
155             TX_DS => boolfield(5),
156             MAX_RT => boolfield(4),
157             RX_P_NO => enumfield(1, 0,1,2,3,4,5 ),
158             TX_FULL => boolfield(0);
159              
160             bitfield OBSERVE_TX =>
161             PLOS_CNT => intfield(4, 4),
162             ARC_CNT => intfield(0, 4);
163              
164             bitfield FIFO_STATUS =>
165             TX_REUSE => boolfield(6),
166             TX_FULL => boolfield(5),
167             TX_EMPTY => boolfield(4),
168             RX_FULL => boolfield(1),
169             RX_EMPTY => boolfield(0);
170              
171             bitfield { unrecognised_ok => 1 }, FEATURE =>
172             EN_DPL => boolfield(2),
173             EN_ACK_PAY => boolfield(1),
174             EN_DYN_ACK => boolfield(0);
175              
176             =head2 clear_caches
177              
178             $nrf->clear_caches
179              
180             The chip object stores a cache of the register values it last read or wrote,
181             so it can optimise updates of configuration. This method clears these caches,
182             ensuring a fresh SPI transfer next time the register needs to be read.
183              
184             This should not normally be necessary, other than for debugging.
185              
186             =cut
187              
188             field @_registers;
189              
190 0         0 method clear_caches ()
  0         0  
191 0     0 1 0 {
192 0         0 undef @_registers;
193             }
194              
195             =head2 latest_status
196              
197             $status = $nrf->latest_status
198              
199             Returns the latest cached copy of the status register from the most recent SPI
200             interaction. As this method does not perform any IO, it returns its result
201             immediately rather than via a Future.
202              
203             Returns a HASH reference containing the following boolean fields
204              
205             RX_DR TX_DS MAX_RT TX_FULL
206              
207             Also returned is a field called C, which is either a pipe number (0
208             to 5) or undef.
209              
210             =cut
211              
212             field $_latest_status;
213              
214 1         3 method latest_status ()
  1         2  
215 1     1 1 10833 {
216 1         8 return { unpack_STATUS( $_latest_status ) };
217             }
218              
219             =head2 reset_interrupt
220              
221             await $nrf->reset_interrupt;
222              
223             Clears the interrupt flags in the C register.
224              
225             =cut
226              
227 0         0 async method reset_interrupt ()
  0         0  
228 0         0 {
229 0         0 await $self->_write_register_volatile( REG_STATUS, chr pack_STATUS(
230             RX_DR => 1,
231             TX_DS => 1,
232             MAX_RT => 1
233             ) );
234 0     0 1 0 }
235              
236 23         37 async method _do_command ( $cmd, $data = "" )
  23         31  
  23         45  
  23         32  
237 23         53 {
238 23         74 my $buf = await $self->protocol->readwrite( chr( $cmd ) . $data );
239              
240 23         18901 $_latest_status = ord substr $buf, 0, 1, "";
241              
242 23         93 return $buf;
243 23     23   78 }
244              
245             =head2 read_status
246              
247             $status = await $nrf->read_status;
248              
249             Reads and returns the current content of the status register as a HASH
250             reference as per C.
251              
252             =cut
253              
254 0         0 async method read_status ()
  0         0  
255 0         0 {
256 0         0 await $self->_do_command( CMD_NOP );
257              
258 0         0 return $self->latest_status;
259 0     0 1 0 }
260              
261             # Always performs an SPI operation
262 15         22 async method _read_register_volatile ( $reg )
  15         24  
  15         20  
263 15         34 {
264 15         33 my ( $regnum, $len ) = @$reg;
265              
266 15         65 my $val = await $self->_do_command( CMD_R_REGISTER | $regnum, ( "\0" x $len ) );
267              
268 15         1101 $_registers[$regnum] = $val;
269 15         55 return $val;
270 15     15   25 }
271              
272             # Returns the cached value if present
273 24         31 async method _read_register ( $reg )
  24         33  
  24         34  
274 24         64 {
275 24         48 my ( $regnum ) = @$reg;
276              
277 24 100       133 defined $_registers[$regnum] ?
278             return $_registers[$regnum] :
279             return await $self->_read_register_volatile( $reg );
280 24     24   44 }
281              
282             # Always performs an SPI operation
283 2         3 async method _write_register_volatile ( $reg, $data )
  2         3  
  2         6  
  2         2  
284 2         6 {
285 2         6 my ( $regnum, $len ) = @$reg;
286 2 50       7 $len == length $data or croak "Attempted to write the wrong length";
287              
288 2         6 await $self->_do_command( CMD_W_REGISTER | $regnum, $data );
289              
290 2         148 $_registers[$regnum] = $data;
291 2         8 return;
292 2     2   7 }
293              
294             # Doesn't bother if no change
295 12         55 async method _write_register ( $reg, $data )
  12         22  
  12         19  
  12         34  
296 12         29 {
297 12         23 my ( $regnum ) = @$reg;
298              
299             return if
300 12 100 66     107 defined $_registers[$regnum] and $_registers[$regnum] eq $data;
301              
302 2         12 await $self->_write_register_volatile( $reg, $data );
303 12     12   1376 }
304              
305             =head2 read_config
306              
307             $config = await $nrf->read_config;
308              
309             =head2 change_config
310              
311             await $nrf->change_config( %config );
312              
313             Reads or writes the chip-wide configuration. This is an amalgamation of all
314             the non-pipe-specific configuration registers; C, C,
315             C, C, C, C and C.
316              
317             When reading, the fields are returned in a HASH reference whose names are the
318             original bitfield names found in the F data sheet. When
319             writing, these fields are accepted as named parameters to the C
320             method directly.
321              
322             Some of the fields have special processing for convenience. They are:
323              
324             =over 4
325              
326             =item * CRCO
327              
328             Gives the CRC length in bytes, as either 1 or 2.
329              
330             =item * AW
331              
332             Gives the full address width in bytes, between 3 and 5.
333              
334             =item * ARD
335              
336             Gives the auto retransmit delay in microseconds directly; a multiple of 250
337             between 250 and 4000.
338              
339             =item * RF_DR
340              
341             Gives the RF data rate in bytes/sec; omits the C and C
342             fields; as 250000, 1000000 or 2000000
343              
344             =item * RF_PWR
345              
346             Gives the RF output power in dBm directly, as -18, -12, -6 or 0.
347              
348             =item * TX_ADDR
349              
350             Gives the PTX address as a string of 5 capital hexadecimal encoded octets,
351             separated by colons.
352              
353             =back
354              
355             Whenever the config is read it is cached within the C<$chip> instance.
356             Whenever it is written, any missing fields in the passed configuration are
357             pre-filled by the cached config, and only those registers that need writing
358             will be written.
359              
360             =cut
361              
362             sub _unpack_addr ( $addr )
363 3     3   432 {
  3         6  
  3         7  
364 3         14 return join ":", map { sprintf "%02X", ord } split //, $addr;
  15         60  
365             }
366              
367             sub _pack_addr ( $addr )
368 1     1   525 {
  1         3  
  1         2  
369 1         5 return join "", map { chr hex } split m/:/, $addr;
  5         22  
370             }
371              
372             sub _unpack_config ( %regs )
373 2     2   3 {
  2         8  
  2         3  
374             my %config = (
375             unpack_CONFIG ( $regs{config} ),
376             unpack_SETUP_AW ( $regs{setup_aw} ),
377             unpack_SETUP_RETR( $regs{setup_retr} ),
378             RF_CH => $regs{rf_ch},
379             unpack_RF_SETUP ( $regs{rf_setup} ),
380             TX_ADDR => _unpack_addr( $regs{tx_addr} ),
381 2         10 unpack_FEATURE ( $regs{feature} ),
382             );
383              
384             # RF_DR is split across two discontiguous bits - currently Data::Bitmask
385             # can't support this
386 2         107 $config{RF_DR} = ( 1E6, 2E6, 250E6, undef )[ delete($config{RF_DR_HIGH}) + 2 * delete($config{RF_DR_LOW}) ];
387              
388 2         43 return %config;
389             }
390              
391             sub _pack_config ( %config )
392 1     1   3 {
  1         7  
  1         2  
393             # RF_DR is split across two discontiguous bits - currently Data::Bitmask
394             # can't support this
395 1         5 for( delete $config{RF_DR} ) {
396 1 50       5 $config{RF_DR_LOW} = 1, $config{RF_DR_HIGH} = 0, last if $_ == 250E3;
397 1 50       5 $config{RF_DR_LOW} = 0, $config{RF_DR_HIGH} = 0, last if $_ == 1E6;
398 1 50       6 $config{RF_DR_LOW} = 0, $config{RF_DR_HIGH} = 1, last if $_ == 2E6;
399 0         0 croak "Unsupported 'RF_DR'";
400             }
401              
402             return
403             config => pack_CONFIG ( %config ),
404             setup_aw => pack_SETUP_AW ( %config ),
405             setup_retr => pack_SETUP_RETR( %config ),
406             rf_ch => $config{RF_CH},
407             rf_setup => pack_RF_SETUP ( %config ),
408 1         8 tx_addr => _pack_addr( $config{TX_ADDR} ),
409             feature => pack_FEATURE ( %config ),
410             }
411              
412 2         4 async method read_config ()
  2         3  
413 2         6 {
414             my @vals = await Future->needs_all(
415 2         7 map { $self->_read_register( $_ ) }
416             REG_CONFIG, REG_SETUP_AW, REG_SETUP_RETR, REG_RF_CH, REG_RF_SETUP, REG_TX_ADDR, REG_FEATURE,
417             );
418              
419 2         440 $_ = ord $_ for @vals[0,1,2,3,4,6]; # [5] is TX_ADDR
420 2         5 my %regs;
421 2         12 @regs{qw( config setup_aw setup_retr rf_ch rf_setup tx_addr feature )} = @vals;
422              
423 2         12 return { _unpack_config %regs };
424 2     2 1 474 }
425              
426 1         2 async method change_config ( %changes )
  1         3  
  1         2  
427 1         5 {
428 1         4 my $config = await $self->read_config;
429              
430 1         48 my %new_registers = _pack_config %$config, %changes;
431              
432 1         124 my @f;
433 1         3 foreach (qw( config setup_aw setup_retr rf_ch rf_setup feature )) {
434 6         1576 push @f, $self->_write_register( $self->${\"REG_\U$_"}, chr $new_registers{$_} );
  6         45  
435             }
436 1         21 push @f, $self->_write_register( REG_TX_ADDR, $new_registers{tx_addr} );
437              
438 1         27 await Future->needs_all( @f );
439 1         207 return;
440 1     1 1 1373 }
441              
442             =head2 read_rx_config
443              
444             $config = await $nrf->read_rx_config( $pipeno );
445              
446             =head2 change_rx_config
447              
448             await $nrf->change_rx_config( $pipeno, %config );
449              
450             Reads or writes the per-pipe RX configuration. This is composed of the
451             per-pipe bits of the C and C registers and its
452             C register.
453              
454             Addresses are given as a string of 5 octets in capitalised hexadecimal
455             notation, separated by colons.
456              
457             When reading an address from pipes 2 to 5, the address of pipe 1 is used to
458             build a complete address string to return. When writing and address to these
459             pipes, all but the final byte is ignored.
460              
461             =cut
462              
463 1         2 async method read_rx_config ( $pipeno )
  1         5  
  1         2  
464 1         4 {
465 1 50 33     8 $pipeno >= 0 and $pipeno < 6 or croak "Invalid pipe number $pipeno";
466 1         3 my $mask = 1 << $pipeno;
467              
468             my ( $en_aa, $en_rxaddr, $dynpd, $width, $addr, $p1addr ) =
469             await Future->needs_all(
470             map { $self->_read_register( $_ ) }
471             REG_EN_AA, REG_EN_RXADDR, REG_DYNPD, # bitwise
472 1         3 $self->${\"REG_RX_PW_P$pipeno"}, $self->${\"REG_RX_ADDR_P$pipeno"},
473             # Pipes 2 to 5 share the first 4 octects of PIPE1's address
474             ( $pipeno >= 2 ? REG_RX_ADDR_P1 : () ),
475             );
476              
477 1         199 $_ = ord $_ for $en_aa, $en_rxaddr, $dynpd, $width;
478              
479 1 50       4 $addr = substr( $p1addr, 0, 4 ) . $addr if $pipeno >= 2;
480              
481             return {
482 1         5 EN_AA => !!( $en_aa & $mask ),
483             EN_RXADDR => !!( $en_rxaddr & $mask ),
484             DYNPD => !!( $dynpd & $mask ),
485             RX_PW => $width,
486             RX_ADDR => _unpack_addr $addr,
487             };
488 1     1 1 3470 }
489              
490 1         2 async method change_rx_config ( $pipeno, %changes )
  1         2  
  1         3  
  1         2  
491 1         4 {
492 1 50 33     8 $pipeno >= 0 and $pipeno < 6 or croak "Invalid pipe number $pipeno";
493 1         3 my $mask = 1 << $pipeno;
494              
495 1         2 my $REG_RX_PW_Pn = $self->${\"REG_RX_PW_P$pipeno"};
  1         7  
496 1         3 my $REG_RX_ADDR_Pn = $self->${\"REG_RX_ADDR_P$pipeno"};
  1         5  
497              
498             my ( $en_aa, $en_rxaddr, $dynpd, $width, $addr ) =
499             await Future->needs_all(
500 1         3 map { $self->_read_register( $_ ) }
501             REG_EN_AA, REG_EN_RXADDR, REG_DYNPD, $REG_RX_PW_Pn, $REG_RX_ADDR_Pn
502             );
503              
504 1         172 $_ = ord $_ for $en_aa, $en_rxaddr, $dynpd, $width;
505              
506 1 50       5 if( exists $changes{EN_AA} ) {
507 0         0 $en_aa &= ~$mask;
508 0 0       0 $en_aa |= $mask if $changes{EN_AA};
509             }
510 1 50       4 if( exists $changes{EN_RXADDR} ) {
511 0         0 $en_rxaddr &= ~$mask;
512 0 0       0 $en_rxaddr |= $mask if $changes{EN_RXADDR};
513             }
514 1 50       4 if( exists $changes{DYNPD} ) {
515 0         0 $dynpd &= ~$mask;
516 0 0       0 $dynpd |= $mask if $changes{DYNPD};
517             }
518 1 50       4 if( exists $changes{RX_PW} ) {
519 1         2 $width = $changes{RX_PW};
520             }
521 1 50       5 if( exists $changes{RX_ADDR} ) {
522 0         0 $addr = _pack_addr $changes{RX_ADDR};
523 0 0       0 $addr = substr( $addr, -1 ) if $pipeno >= 2;
524             }
525              
526             await Future->needs_all(
527             $self->_write_register( REG_EN_AA, chr $en_aa ),
528             $self->_write_register( REG_EN_RXADDR, chr $en_rxaddr ),
529             $self->_write_register( REG_DYNPD, chr $dynpd ),
530             $self->_write_register( $REG_RX_PW_Pn, chr $width ),
531             $self->_write_register( $REG_RX_ADDR_Pn, $addr ),
532 1         5 );
533              
534 1         204 return;
535 1     1 1 6254 }
536              
537             =head2 observe_tx_counts
538              
539             $counts = await $nrf->observe_tx_counts;
540              
541             Reads the C register and returns the two counts from it.
542              
543             =cut
544              
545 1         3 async method observe_tx_counts ()
  1         2  
546 1         4 {
547 1         5 my $buf = await $self->_read_register_volatile( REG_OBSERVE_TX );
548              
549 1         84 return { unpack_OBSERVE_TX( ord $buf ) };
550 1     1 1 129 }
551              
552             =head2 rpd
553              
554             $rpd = await $nrf->rpd;
555              
556             Reads the C register
557              
558             =cut
559              
560 1         3 async method rpd ()
  1         2  
561 1         4 {
562 1         5 my $buf = await $self->_read_register_volatile( REG_RPD );
563              
564 1         71 return ( ord $buf ) & 1;
565 1     1 1 5748 }
566              
567             =head2 fifo_status
568              
569             $status = await $nrf->fifo_status;
570              
571             Reads the C register and returns the five bit fields from it.
572              
573             =cut
574              
575 1         3 async method fifo_status ()
  1         2  
576 1         3 {
577 1         4 my $buf = await $self->_read_register_volatile( REG_FIFO_STATUS );
578              
579 1         78 return { unpack_FIFO_STATUS( ord $buf ) };
580 1     1 1 3672 }
581              
582             =head2 pwr_up
583              
584             await $nrf->pwr_up( $pwr );
585              
586             A convenient shortcut to setting the C configuration bit.
587              
588             =cut
589              
590 0         0 async method pwr_up ( $pwr )
  0         0  
  0         0  
591 0         0 {
592 0         0 await $self->change_config( PWR_UP => $pwr );
593 0     0 1 0 }
594              
595             =head2 chip_enable
596              
597             await $nrf->chip_enable( $ce );
598              
599             Controls the Chip Enable (CE) pin of the chip.
600              
601             =cut
602              
603 1         3 async method chip_enable ( $ce )
  1         2  
  1         2  
604 1         3 {
605 1         4 await $self->protocol->write_gpios( { $_gpio_ce => $ce } );
606 1     1 1 118 }
607              
608             =head2 read_rx_payload_width
609              
610             $len = await $nrf->read_rx_payload_width;
611              
612             Returns the width of the most recently received payload, when in C mode.
613             Remember that C needs to be enabled (using C) on both the
614             transmitter and receiver before this will work.
615              
616             =cut
617              
618 1         3 async method read_rx_payload_width ()
  1         2  
619 1         3 {
620 1         8 return ord await $self->_do_command( CMD_R_RX_PL_WID, "\0" );
621 1     1 1 134 }
622              
623             =head2 read_rx_payload
624              
625             $data = await $nrf->read_rx_payload( $len );
626              
627             Reads the most recently received RX FIFO payload buffer.
628              
629             =cut
630              
631 1         3 async method read_rx_payload ( $len )
  1         2  
  1         3  
632 1         3 {
633 1 50 33     13 $len > 0 and $len <= 32 or croak "Invalid RX payload length $len";
634              
635 1         6 return await $self->_do_command( CMD_R_RX_PAYLOAD, "\0" x $len )
636 1     1 1 6554 }
637              
638             =head2 write_tx_payload
639              
640             await $nrf->write_tx_payload( $data, %opts );
641              
642             Writes the next TX FIFO payload buffer. Takes the following options:
643              
644             =over 4
645              
646             =item no_ack => BOOL
647              
648             If true, uses the C command, requesting that this payload
649             does not requre auto-ACK.
650              
651             =back
652              
653             =cut
654              
655 2         7 async method write_tx_payload ( $data, %opts )
  2         7  
  2         11  
  2         3  
656 2         9 {
657 2         5 my $len = length $data;
658 2 50 33     14 $len > 0 and $len <= 32 or croak "Invalid TX payload length $len";
659              
660 2 100       6 my $cmd = $opts{no_ack} ? CMD_W_TX_PAYLOAD_NO_ACK : CMD_W_TX_PAYLOAD;
661              
662 2         7 await $self->_do_command( $cmd, $data );
663 2         148 return;
664 2     2 1 4677 }
665              
666             =head2 flush_rx_fifo
667              
668             await $nrf->flush_rx_fifo;
669              
670             =head2 flush_tx_fifo
671              
672             await $nrf->flush_tx_fifo;
673              
674             Flush the RX or TX FIFOs, discarding all their contents.
675              
676             =cut
677              
678 1         2 async method flush_rx_fifo ()
  1         2  
679 1         4 {
680 1         7 await $self->_do_command( CMD_FLUSH_RX );
681 1         77 return;
682 1     1 1 5852 }
683              
684 1         2 async method flush_tx_fifo ()
  1         2  
685 1         5 {
686 1         4 await $self->_do_command( CMD_FLUSH_TX );
687 1         73 return;
688 1     1 1 3256 }
689              
690             =head1 AUTHOR
691              
692             Paul Evans
693              
694             =cut
695              
696             0x55AA;