Hi Paul.

Check out Data::ParseBinary. I developed it for similar tasks.

Shmuel.
On Sep 24, 2014 1:56 PM, "Paul "LeoNerd" Evans" <leon...@leonerd.org.uk>
wrote:

> [[ 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
>
> leon...@leonerd.org.uk
> http://www.leonerd.org.uk/  |  https://metacpan.org/author/PEVANS
>

Reply via email to