背景描述:
芯片的一个寄存器数据宽度通常是32bit,经常会遇到一个寄存器包含多个控制能容,例如:
这是一个32bit的寄存器,对应2个内容:
- [12:0] 设置stride
- [31:16]设置stride2
那么如何实现一个接口,将一个stride值设置到指定的位置呢?
代码实现:
#include <stdlib.h>
#include <stdio.h>
#define BITS_PER_W 32
#define BITS_FULL_1 (~0U)
#define MOVE_OUT_INVALID_BITS(high, low) (BITS_FULL_1 >> ((BITS_PER_W - (high - low + 1))))
#define ALIGN_TO_DST_BITS(high, low) (MOVE_OUT_INVALID_BITS(high, low) << (low))
#define SET_BITS(high, low) (ALIGN_TO_DST_BITS(high, low))
#define SET_DATA_TO_BITS(high, low, data) (SET_BITS(high, low) & (data << low))
#define CLEAR_BITS_OF_DATA(data, high, low) (data & ~SET_BITS(high, low))
#define WRITE_DATA_TO_BITS(curr, data, high, low) (CLEAR_BITS_OF_DATA(curr, high, low) | SET_DATA_TO_BITS(high, low, data))
int main()
{
unsigned int curr_data = 0x43020;
unsigned int data = 2;
unsigned int high = 15, low = 14;
unsigned int updated_data = WRITE_DATA_TO_BITS(curr_data, data, high, low);
printf("curr_data: 0x%x, updata to [%d:%d] - 0x%x, updated_data: 0x%x\n",
curr_data, high, low, data, updated_data);
return 0;
}
代码逻辑:
- 准备一个空的32bits,对应代码中的BITS_FULL_1
- 将要写入的值放到32bits中指定位置。这里通过&操作,将值data放到这个空的32bit对应的比特范围
- 将寄存器当前值对应比特范围的值清掉
- 最后把步骤二和步骤三的32bits通过|合到一起