当自定义寄存器比较多时,需要有简化代码的方式。
1.STM32方式
直接定义偏移量和掩码
#define gtwDEV_POLE_SHIFT (0)
#define gtwDEV_POLE_MASK (0x03)
#define gtwDEV_POLE1 (0)
#define gtwDEV_POLE2 (1)
#define gtwDEV_POLE3 (2)
#define gtwDEV_POLE4 (3)
#define gtwDEV_POLE_GET(addr) gtwDEV_GET8(addr,gtwDEV_POLE_SHIFT,gtwDEV_POLE_MASK)
#define gtwDEV_POLE_SET(addr,val) gtwDEV_SET8(addr,gtwDEV_POLE_SHIFT,gtwDEV_POLE_MASK,val)
2.表访问方式
#define指令不能一次定义多个常量,找不到很好的方法来一次性#define生成上述代码,因此采用表访问方式
表寄存器配置框架
#define sysREG8 0
#define sysREG16 1
#define sysREG32 2
/*定义结构体*/
typedef struct
{
u8 type;
u8 shift;
u16 mask;
} sys_reg_t;
/*定义寄存器访问函数*/
inline u16 sys_reg_get( sys_reg_t *reg, void *addr);
inline void sys_reg_set( sys_reg_t *reg, void *addr, u16 val );
/*直接表索引*/
static const sys_reg_t gtw_reg_data[]={
{sysREG8 , 0, 0x03},
{sysREG8 , 2, 0x03},
};
/*两级表索引,可以避免寄存器索引混乱*/
static const void* gtw_reg_data1[]={
>w_reg_type,
>w_reg_st,
};
1)表访问方式增加了指令数量
2)为了实现32位对齐,当前数据结构不支持16位以上的单值(仍然支持32位寄存器);
3)可以将mask定义为1的位计数来支持32位值,这样mask用u8就可以了,但是这些也会增加指令数量。或者直接定义mask为u32来支持32位值,仅会增加flash存储
3.define分离式访问方式
写表访问方式的时候发现表基本没起到多大的作用,该写的代码基本还是要写,因此有第三种,采用define的连接符避免每一个REG访问都要写宏定义
#define gtwDEV_GETGET(addr, type, shift, mask) (((*(type *)(addr)) >> (shift)) & (mask))
#define gtwDEV_GET_TYPE(base) gtwDEV_##base##_TYPE
#define gtwDEV_GET_SHIFT(base,index) gtwDEV_##base##_##index##_SHIFT
#define gtwDEV_GET_MASK(base,index) gtwDEV_##base##_##index##_MASK
#define gtwDEV_GET_VAL(base,index,val) gtwDEV_##base##_##index##_##val
#define gtwDEV_GET(addr, base, index) gtwDEV_GETGET(addr, \
gtwDEV_GET_TYPE(base), \
gtwDEV_GET_SHIFT(base,index), \
gtwDEV_GET_MASK(base,index))
#define gtwDEV_SETSET(type, addr, shift, mask, val) (*(type *)(addr)) |= ((((type)(val)) & (mask)) << (shift))
#define gtwDEV_SET(addr, base, index, val) gtwDEV_SETSET(gtwDEV_GET_TYPE(base), \
addr, \
gtwDEV_GET_SHIFT(base,index), \
gtwDEV_GET_MASK(base,index), \
gtwDEV_GET_VAL(base,index,val))
#define gtwDEV_DSET(addr, base, index, val) gtwDEV_SETSET(gtwDEV_GET_TYPE(base), \
addr, \
gtwDEV_GET_SHIFT(base,index), \
gtwDEV_GET_MASK(base,index), \
val)
//device type
#define gtwDEV_TYPE_TYPE (u8)
#define gtwDEV_TYPE_POLE_SHIFT (0)
#define gtwDEV_TYPE_POLE_MASK (0x03)
#define gtwDEV_TYPE_POLE_1 (0)
#define gtwDEV_TYPE_POLE_2 (1)
#define gtwDEV_TYPE_POLE_3 (2)
#define gtwDEV_TYPE_POLE_4 (3)
读取 if( gtwDEV_GET_VAL(TYPE, POLE,1) == gtwDEV_GET(addr, TYPE, POLE))
写入 gtwDEV_GET(addr, TYPE, POLE,4)
|