Device-Chip-nRF24L01P
view release on metacpan or search on metacpan
lib/Device/Chip/nRF24L01P.pm view on Meta::CPAN
=head2 change_config
await $nrf->change_config( %config );
Reads or writes the chip-wide configuration. This is an amalgamation of all
the non-pipe-specific configuration registers; C<CONFIG>, C<SETUP_AW>,
C<SETUP_RETR>, C<RF_CH>, C<RF_SETUP>, C<TX_ADDR> and C<FEATURE>.
When reading, the fields are returned in a HASH reference whose names are the
original bitfield names found in the F<Nordic Semiconductor> data sheet. When
writing, these fields are accepted as named parameters to the C<change_config>
method directly.
Some of the fields have special processing for convenience. They are:
=over 4
=item * CRCO
Gives the CRC length in bytes, as either 1 or 2.
=item * AW
Gives the full address width in bytes, between 3 and 5.
=item * ARD
Gives the auto retransmit delay in microseconds directly; a multiple of 250
between 250 and 4000.
=item * RF_DR
Gives the RF data rate in bytes/sec; omits the C<RF_DR_LOW> and C<RF_DR_HIGH>
fields; as 250000, 1000000 or 2000000
=item * RF_PWR
Gives the RF output power in dBm directly, as -18, -12, -6 or 0.
=item * TX_ADDR
Gives the PTX address as a string of 5 capital hexadecimal encoded octets,
separated by colons.
=back
Whenever the config is read it is cached within the C<$chip> instance.
Whenever it is written, any missing fields in the passed configuration are
pre-filled by the cached config, and only those registers that need writing
will be written.
=cut
sub _unpack_addr ( $addr )
{
return join ":", map { sprintf "%02X", ord } split //, $addr;
}
sub _pack_addr ( $addr )
{
return join "", map { chr hex } split m/:/, $addr;
}
sub _unpack_config ( %regs )
{
my %config = (
unpack_CONFIG ( $regs{config} ),
unpack_SETUP_AW ( $regs{setup_aw} ),
unpack_SETUP_RETR( $regs{setup_retr} ),
RF_CH => $regs{rf_ch},
unpack_RF_SETUP ( $regs{rf_setup} ),
TX_ADDR => _unpack_addr( $regs{tx_addr} ),
unpack_FEATURE ( $regs{feature} ),
);
# RF_DR is split across two discontiguous bits - currently Data::Bitmask
# can't support this
$config{RF_DR} = ( 1E6, 2E6, 250E6, undef )[ delete($config{RF_DR_HIGH}) + 2 * delete($config{RF_DR_LOW}) ];
return %config;
}
sub _pack_config ( %config )
{
# RF_DR is split across two discontiguous bits - currently Data::Bitmask
# can't support this
for( delete $config{RF_DR} ) {
$config{RF_DR_LOW} = 1, $config{RF_DR_HIGH} = 0, last if $_ == 250E3;
$config{RF_DR_LOW} = 0, $config{RF_DR_HIGH} = 0, last if $_ == 1E6;
$config{RF_DR_LOW} = 0, $config{RF_DR_HIGH} = 1, last if $_ == 2E6;
croak "Unsupported 'RF_DR'";
}
return
config => pack_CONFIG ( %config ),
setup_aw => pack_SETUP_AW ( %config ),
setup_retr => pack_SETUP_RETR( %config ),
rf_ch => $config{RF_CH},
rf_setup => pack_RF_SETUP ( %config ),
tx_addr => _pack_addr( $config{TX_ADDR} ),
feature => pack_FEATURE ( %config ),
}
async method read_config ()
{
my @vals = await Future->needs_all(
map { $self->_read_register( $_ ) }
REG_CONFIG, REG_SETUP_AW, REG_SETUP_RETR, REG_RF_CH, REG_RF_SETUP, REG_TX_ADDR, REG_FEATURE,
);
$_ = ord $_ for @vals[0,1,2,3,4,6]; # [5] is TX_ADDR
my %regs;
@regs{qw( config setup_aw setup_retr rf_ch rf_setup tx_addr feature )} = @vals;
return { _unpack_config %regs };
}
async method change_config ( %changes )
{
my $config = await $self->read_config;
( run in 0.500 second using v1.01-cache-2.11-cpan-71847e10f99 )