[[ background ]] I've been doing a lot of hardware IO work lately, which involves lots of talking to hardware devices, where there are byte-wide registers that store little bitfields, sometimes of individual and unrelated bits packed together. To make this easier I tend to write myself lots of pairs of functions to pack/unpack the fields in one of these bytes; for instance:
use constant {
MASK_RX_RD => 1<<6,
MASK_TX_DS => 1<<5,
MASK_MAX_RT => 1<<4,
EN_CRC => 1<<3,
CRCO => 1<<2,
PWR_UP => 1<<1,
PRIM_RX => 1<<0,
};
sub unpack_CONFIG
{
my ( $config ) = @_;
return
MASK_RX_RD => !!( $config & MASK_RX_RD ),
MASK_TX_DS => !!( $config & MASK_TX_DS ),
MASK_MAX_RT => !!( $config & MASK_MAX_RT ),
EN_CRC => !!( $config & EN_CRC ),
CRCO => $CRCOs[!!( $config & CRCO )],
PWR_UP => !!( $config & PWR_UP ),
PRIM_RX => !!( $config & PRIM_RX );
}
sub pack_CONFIG
{
my %config = @_;
return
( $config{MASK_RX_RD} ? MASK_RX_RD : 0 ) |
( $config{MASK_TX_DS} ? MASK_TX_DS : 0 ) |
( $config{MASK_MAX_RT} ? MASK_MAX_RT : 0 ) |
( $config{EN_CRC} ? EN_CRC : 0 ) |
( ( _idx_of $config{CRCO}, @CRCOs )
// croak "Unsupported 'CRCO'" ) * CRCO |
( $config{PWR_UP} ? PWR_UP : 0 ) |
( $config{PRIM_RX} ? PRIM_RX : 0 ) );
}
This convenient pair of functions bidirectionally converts bytes into
key/value lists. As well as containing 6 simple boolean values, there's
also an enumerated field, represented by the values in the array
@CRCOs. These functions convert those too.
I'm getting tired of writing these pairs of functions. Hey, this is
Perl write? :) I should get Perl to write them for me.
[[ TL;DR - I propose the following ]]
I'd like instead to write something like:
use bitfield;
bitfield CONFIG =>
MASK_RX_DS => boolfield(6),
MASK_TX_DS => boolfield(5),
MASK_MAX_RT => boolfield(4),
EN_CRC => boolfield(3),
CRCO => enumfield(2, qw( values here )),
PWR_UP => boolfield(1),
PRIM_RX => boolfield(0);
The operation here is that 'bitfield' is automatically exporting a
function called 'bitfield', along with the various *field() functions
that create field definitions. boolfield() declares a single true/false
boolean bit position, enumfield() declares a range of bits that give
an enumeration. I guess also would be required intfield() to use a
range of bits as an integer, and finally most likely customfield()
taking a pair of conversion CODE refs or somesuch.
What does anyone think to that?
--
Paul "LeoNerd" Evans
[email protected]
http://www.leonerd.org.uk/ | https://metacpan.org/author/PEVANS
signature.asc
Description: PGP signature
