Electronic – Register map using C for a MAX30001 analog front end

cregister

I am trying to follow the best practices in register mapping. I have a MAX30001 analog front end for ECG applications (Datasheet) and in page 38, there is a table that contains user command and register map: 32 words, each with 24 bits of information. Should I use structures or macros ?

Using structures with bit fields:

typedef struct {

    volatile uint8_t Bit0 : 1;
    volatile uint8_t Bit1 : 1;
    volatile uint8_t Bit2 : 1;
    volatile uint8_t Bit3 : 1;
    // ... 
    // and so on
    // ... 
    volatile uint8_t Bit23 : 1;
} foo;

Using macros:

#define STATUS (*(volatile uint32_t*)0x01))

Best Answer

In the general case, where you have memory mapped registers, you should always avoid bitfield structs. This is because those are very poorly specified by the C standard. Fundamental things that you may assume are specified, are not. This includes bit order, byte order, padding & alignment.

In addition, uint8_t among other types, is not even an allowed type in bitfields! You can only use int types, though if int counts as signed or unsigned is not specified either...

To sum it up, bitfields are horribly unreliable and you are left at the mercy of the compiler implementation (if any) when you use them.

What you should do instead, is to always use address and bit mask macros, together with the bit-wise operators. Those are 100% well-defined and portable.