Hey Paul,

My first thought was, "Why not use Convert::Binary::C
<https://metacpan.org/pod/Convert::Binary::C>?" You could write your
bitfields using regular C bitfields in a struct declaration. I figured a
good answer would be "Because he needs it to be pure Perl," but I figured I
would at least throw the idea out there.

Otherwise, I like the idea.

David

On Wed, Sep 24, 2014 at 6:56 AM, 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
>



-- 
 "Debugging is twice as hard as writing the code in the first place.
  Therefore, if you write the code as cleverly as possible, you are,
  by definition, not smart enough to debug it." -- Brian Kernighan

Reply via email to