如何使用预定义掩码生成值
How to generate a value using pre defined mask
我正在开发一个有点棘手的硬件...例如它的 32 位寄存器看起来像这样(高 16 位全为零)
#define MASK_DBG_CTRL_FIFO_SPLIT 0b0000000000000001
#define MASK_DBG_CTRL_FIFO_ENABLE 0b0000000000000010
#define MASK_DBG_CTRL_ADC_SPLIT 0b0000000000000100
#define MASK_DBG_CTRL_ADC_ENABLE 0b0000000000001000
#define MASK_DBG_CTRL_MAX_COUNTER 0b1111111111110000
#define NO_SPLIT 0
#define WITH_SPLIT 1
#define DISABLE 0
#define ENABLE 1
我的问题是,如何生成需要写入该寄存器的数字。例如。我将有一个函数从用户那里获取数字和 returns 准备写入寄存器的值。
这似乎是一个非常痛苦的过程...我有十几个具有不同位宽和内容的类似寄存器...我怎样才能使这更容易?
首先,我如何在 MASK_DBG_CTRL_MAX_COUNTER
位写入所需的值?
uint32_t generateDebugRegister(uint8_t fifoSplit, uint8_t fifoEnable,
uint8_t adcSplit, uint8_t adcEnable,
uint16_t counter) {
uint32_t output = 0;
switch(fifoSplit) {
case NO_SPLIT:
//do nothing;
break;
case WITH_SPLIT:
output = 1UL >> 1; //set bit 0 to 1
break;
}
switch(fifoEnable) {
case DISABLE:
//do nothing;
break;
case ENABLE:
output = 1UL >> 2; //set bit 2 to 1
break;
}
switch(adcSplit) {
case NO_SPLIT:
//do nothing;
break;
case WITH_SPLIT:
output = 1UL >> 3; //set bit 3 to 1
break;
}
switch(adcEnable) {
case DISABLE:
//do nothing;
break;
case ENABLE:
output = 1UL >> 4; //set bit 4 to 1
break;
}
//how to evenset the counter value???
return output;
}
调用函数示例:
void setDebugRegister(uint32_t value) { /*write to reg*/ };
uint32_t toWrite = generateDebugRegister(NO_SPLIT, DISABLE, WITH_SPLIT, ENABLE, 4256);
setDebugRegister( toWrite);
这是另一组寄存器掩码...这里我需要将低10位拼接成两个5位:
#define MASK_DAD_NUM_ADDR 0b0000000000011111
#define MASK_DAD_NUM_DECI 0b0000001111100000
此处高8位低8位:
#define MASK_DBG_REG_ID 0b1111111100000000;
#define MASK_DBG_REG_CNTR 0b0000000011111111;
How to generate a value using pre defined mask (?)
解决 OP 的第一部分:
考虑重写函数签名。下面的其他建议更改作为注释代码。
// uint32_t generateDebugRegister(uint8_t fifoSplit, uint8_t fifoEnable,
// uint8_t adcSplit, uint8_t adcEnable, uint16_t counter) { ...
// use bool for simple T/F values
uint32_t generateDebugRegister(bool fifoSplit, bool fifoEnable, bool adcSplit,
bool adcEnable, uint16_t counter) {
uint32_t output = 0;
if (fifoSplit == WITH_SPLIT) { // use an `if()`
output |= MASK_DBG_CTRL_FIFO_SPLIT; // use an 'or' of the mask
}
if (fifoEnable == ENABLE) {
output |= MASK_DBG_CTRL_FIFO_ENABLE;
}
.... // like-wise with adcSplit, adcEnable
// add an `offset` to simplify shifting needs
#define MASK_DBG_CTRL_MAX_BIT_OFFSET 4
#define MASK_DBG_CTRL_MAX_MAX (MASK_DBG_CTRL_MAX_COUNTER >> MASK_DBG_CTRL_MAX_BIT_OFFSET)
// test, since 16 bits do not fit in 12
if (counter > MASK_DBG_CTRL_MAX_MAX) {
Handle_error_with_TBD_Code();
}
else {
output |= (uint32_t)counter << MASK_DBG_CTRL_MAX_BIT_OFFSET;
}
return out;
}
I have a dozen of similar registers that have different bit-width and stuff...How can I make this easier?
需要查看其中一些以获得良好的一般性答案。
我正在开发一个有点棘手的硬件...例如它的 32 位寄存器看起来像这样(高 16 位全为零)
#define MASK_DBG_CTRL_FIFO_SPLIT 0b0000000000000001
#define MASK_DBG_CTRL_FIFO_ENABLE 0b0000000000000010
#define MASK_DBG_CTRL_ADC_SPLIT 0b0000000000000100
#define MASK_DBG_CTRL_ADC_ENABLE 0b0000000000001000
#define MASK_DBG_CTRL_MAX_COUNTER 0b1111111111110000
#define NO_SPLIT 0
#define WITH_SPLIT 1
#define DISABLE 0
#define ENABLE 1
我的问题是,如何生成需要写入该寄存器的数字。例如。我将有一个函数从用户那里获取数字和 returns 准备写入寄存器的值。
这似乎是一个非常痛苦的过程...我有十几个具有不同位宽和内容的类似寄存器...我怎样才能使这更容易?
首先,我如何在 MASK_DBG_CTRL_MAX_COUNTER
位写入所需的值?
uint32_t generateDebugRegister(uint8_t fifoSplit, uint8_t fifoEnable,
uint8_t adcSplit, uint8_t adcEnable,
uint16_t counter) {
uint32_t output = 0;
switch(fifoSplit) {
case NO_SPLIT:
//do nothing;
break;
case WITH_SPLIT:
output = 1UL >> 1; //set bit 0 to 1
break;
}
switch(fifoEnable) {
case DISABLE:
//do nothing;
break;
case ENABLE:
output = 1UL >> 2; //set bit 2 to 1
break;
}
switch(adcSplit) {
case NO_SPLIT:
//do nothing;
break;
case WITH_SPLIT:
output = 1UL >> 3; //set bit 3 to 1
break;
}
switch(adcEnable) {
case DISABLE:
//do nothing;
break;
case ENABLE:
output = 1UL >> 4; //set bit 4 to 1
break;
}
//how to evenset the counter value???
return output;
}
调用函数示例:
void setDebugRegister(uint32_t value) { /*write to reg*/ };
uint32_t toWrite = generateDebugRegister(NO_SPLIT, DISABLE, WITH_SPLIT, ENABLE, 4256);
setDebugRegister( toWrite);
这是另一组寄存器掩码...这里我需要将低10位拼接成两个5位:
#define MASK_DAD_NUM_ADDR 0b0000000000011111
#define MASK_DAD_NUM_DECI 0b0000001111100000
此处高8位低8位:
#define MASK_DBG_REG_ID 0b1111111100000000;
#define MASK_DBG_REG_CNTR 0b0000000011111111;
How to generate a value using pre defined mask (?)
解决 OP 的第一部分:
考虑重写函数签名。下面的其他建议更改作为注释代码。
// uint32_t generateDebugRegister(uint8_t fifoSplit, uint8_t fifoEnable,
// uint8_t adcSplit, uint8_t adcEnable, uint16_t counter) { ...
// use bool for simple T/F values
uint32_t generateDebugRegister(bool fifoSplit, bool fifoEnable, bool adcSplit,
bool adcEnable, uint16_t counter) {
uint32_t output = 0;
if (fifoSplit == WITH_SPLIT) { // use an `if()`
output |= MASK_DBG_CTRL_FIFO_SPLIT; // use an 'or' of the mask
}
if (fifoEnable == ENABLE) {
output |= MASK_DBG_CTRL_FIFO_ENABLE;
}
.... // like-wise with adcSplit, adcEnable
// add an `offset` to simplify shifting needs
#define MASK_DBG_CTRL_MAX_BIT_OFFSET 4
#define MASK_DBG_CTRL_MAX_MAX (MASK_DBG_CTRL_MAX_COUNTER >> MASK_DBG_CTRL_MAX_BIT_OFFSET)
// test, since 16 bits do not fit in 12
if (counter > MASK_DBG_CTRL_MAX_MAX) {
Handle_error_with_TBD_Code();
}
else {
output |= (uint32_t)counter << MASK_DBG_CTRL_MAX_BIT_OFFSET;
}
return out;
}
I have a dozen of similar registers that have different bit-width and stuff...How can I make this easier?
需要查看其中一些以获得良好的一般性答案。