I am writing code to access some chips on my PCB board, for example, there is a chip with two registers defined as below:
Each register has different address and content value, and address and value are both a 16-bits word. I have defined structs for each registers for example:
typedef struct _CHIP01_REG01
{
union
{
struct
{
unsigned short software_reset : 1; //bit[0]
unsigned short reg_read_en : 1; //bit[1]
unsigned short add_offset : 1; //bit[2]
unsigned short reserved : 13; //bit[15:3]
} value_bit;
unsigned short value_all;
} value;
unsigned short const address = 0x00;
} CHIP01_REG01;
typedef struct _CHIP01_REG02
{
union
{
struct
{
unsigned short global_pdn : 1; //bit[0]
unsigned short reserved1 : 4; //bit[4:1]
unsigned short dis_lvds : 1; //bit[5]
unsigned short reserved2 : 8; //bit[13:6]
unsigned short lvds_rate_2x : 1; //bit[14]
unsigned short reserved3 : 1; //bit[15]
} value_bit;
unsigned short value_all;
} value;
unsigned short const address = 0x01;
} CHIP01_REG02;
then define a struct to hold all the registers of a chip,
typedef struct
{
CHIP01_REG01 chip01_reg01;
CHIP01_REG02 chip01_reg02;
} CHIP01_REGS;
then I would like to write functions to read/write the registers, for now, my function is as below,
bool RegisterWrite_1
(
unsigned short regAddress,
unsigned short regVal
)
{
// write "regVal" into address "regAddress"
return true;
}
so setting register content and write a register is like this,
chip01_regs.chip01_reg01.value.value_bit.software_reset = 0;
chip01_regs.chip01_reg01.value.value_bit.add_offset = 1;
RegisterWrite_1( chip01_regs.chip01_reg01.address, chip01_regs.chip01_reg01.value.value_all );
the above code is lengthy and error-prone, especially when many registers are required to be set to make the chip function normally.
I would like to know if there is a way to define a function "RegisterWrite_2()", where function input is a pointer to a register and register address/value is extracted inside the function
bool RegisterWrite_2
(
REG_PTR *reg_ptr
)
{
unsigned short regAddress = *reg_ptr.address;
unsigned short regVal = *reg_ptr.value;
// write "regVal" into address "regAddress"
return true;
}
If the above is possible, code to write a register could be done in a much clear way like the third line as below,
chip01_regs.chip01_reg01.value.value_bit.software_reset = 0;
chip01_regs.chip01_reg01.value.value_bit.add_offset = 1;
RegisterWrite_2( &chip01_regs.chip01_reg01 );
the problem is, input type "REG_PTR" in RegisterWrite_2() is not a fixed type, each register belongs to different types (CHIP01_REG01, CHIP01_REG02), so I do not know how to assign "REG_PTR". However, each register occupies the same size of memory (16 bits value and 16 bits address), so I believe there is some way to deal with this condition.
hope I had described my question clearly enough, and since I am a newbie to C++ hope this is not a stupid question, looking forward to your reply, thanks in advance !
This sounds like a straightforward template:
template <class REG>
bool RegisterWrite_2(const REG ®) {
unsigned short regAddress = reg.address;
unsigned short regVal = reg.value;
// write "regVal" into address "regAddress"
return true;
}
Not what you were asking, but you did ask for help on making your code easier to write. So I suggest anonymous unions and structs . Like this:
typedef struct _CHIP01_REG01
{
union
{
struct
{
unsigned short software_reset : 1; //bit[0]
unsigned short reg_read_en : 1; //bit[1]
unsigned short add_offset : 1; //bit[2]
unsigned short reserved : 13; //bit[15:3]
};
unsigned short value_all;
};
unsigned short const address = 0x00;
} CHIP01_REG01;
Now, instead of this:
chip01_regs.chip01_reg01.value.value_bit.add_offset = 1;
you can write this:
chip01_regs.chip01_reg01.add_offset = 1;
This feature has been available in C
since the C11 standard, and in C++
since the C++14 standard.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.