Originally Posted by
samdomville
A snippet of my code looks like this:
Code:
typedef struct {
unsigned reg1 : 25;
unsigned reg2 : 5;
unsigned reg3 : 2;
} volatile RegStruct;
and the compiler is trying to read/write in byte-sizes
I'm not surprised. If we (for the moment) ignore Salem's statement, although he is correct in that statement, and assume that you still want to use a struct with bitfields, then I would recommend that you unionize that with a 32-bit value, eg:
Code:
typedef union {
struct {
unsigned reg1 : 25;
unsigned reg2 : 5;
unsigned reg3 : 2;
} bits;
uint32 word;
} volatile RegStruct;
Then write the word to the hardware register, not the bitfields themselves.
So, let's say you want to modify reg1 to a new value:
Code:
// Somewhere global:
RegStruct *hwReg = (RegStruct *)0x90000000; // Fictive actual hardware address.
...
SetNewReg1(unsigned newreg1)
{
RegStruct val;
val.word = hwReg->word;
val.bits.reg1 = newreg1;
hwReg->word = val.word
}
Salem's suggestion would probably generate exactly the same code, but you would be doing the shifting and masking to set reg1 manually:
Code:
volatile uint32 *hwReg = (volatile uint32 *)0x90000000;
#define SHIFT_REG1 7
#define MASK_REG1 ((~1) << SHIFT_REG1)
#define SHIFT_REG2 2
#define MASK_REG2 (((1 << 5) -1) << SHIFT_REG2)
#define SHIFT_REG3 0
#define MASK_REG3 (((1 << 2) -1) << SHIFT_REG3)
...
SetNewReg1(unsigned newreg1)
{
uint32 val;
val = *hwReg;
val = (newreg << SHIFT_REG1)| (val) & (mask_reg2 | mask_reg3));
*hwReg = val
}
--
Mats