在上一篇文章中,在用CSL配置EMIF时用到了函数:
CSL_FINST(((CSL_DevRegs*)CSL_DEV_REGS)->PERCFG1, DEV_PERCFG1_EMIFACTL, ENABLE);
现在教大家如何看懂这个函数的作用。
第一步:
寄存器PERCFG1(外设配置寄存器一),该寄存器在TMS320C6455 datasheet 中可以找到,描述如下图:
该寄存器的作用是使能EMIF 和 DDR2 存储器控制器。
位描述:
————————————————————————————————————————
DDR2CTL 0 失能 DDR2
1 使能 DDR2
————————————————————————————————————————
EMIFACTL 0 失能 EMIFA
1 使能 EMIFA
————————————————————————————————————————
第二步:
在CSL(片上支持库)的 "cslr_dev.h" 文件中,可以找到CSL_DEV_PERCFG1_EMIFACTL_ENABLE的定义,定义如下:
#define CSL_DEV_PERCFG1_EMIFACTL_ENABLE (0x00000001u)
再在CSL(片上支持库)的 "cslr_dev.h" 文件中,可以找到CSL_DEV_PERCFG1_EMIFACTL_MASK的定义,定义如下:
#define CSL_DEV_PERCFG1_EMIFACTL_MASK (0x00000001u)
再在CSL(片上支持库)的 "cslr_dev.h" 文件中,可以找到CSL_DEV_PERCFG1_EMIFACTL_SHIFT的定义,定义如下:
#define CSL_DEV_PERCFG1_EMIFACTL_SHIFT (0x00000000u)
第三步:
在CSL(片上支持库)的 "cslr.h" 文件中,可以找到CSL_FINST的定义,定义如下:
#define CSL_FINST(reg, PER_REG_FIELD, TOKEN) \
CSL_FINS((reg), PER_REG_FIELD, CSL_##PER_REG_FIELD##_##TOKEN)
再在CSL(片上支持库)的 "cslr.h" 文件中,可以找到CSL_FMK的定义,定义如下:
#define CSL_FMK(PER_REG_FIELD, val) \
(((val) << CSL_##PER_REG_FIELD##_SHIFT) & CSL_##PER_REG_FIELD##_MASK)
再在CSL(片上支持库)的 "cslr.h" 文件中,可以找到CSL_FINS的定义,定义如下:
#define CSL_FINS(reg, PER_REG_FIELD, val) \
((reg) = ((reg) & ~CSL_##PER_REG_FIELD##_MASK) \
| CSL_FMK(PER_REG_FIELD, val))
第四步:
搞懂第三步中宏定义CSL_FMK和CSL_FINST和CSL_FINS的作用,
首先要知道C语音中"a##b" 的作用,它的作用就是在字符a的后面加上b,
所以,CSL_##PER_REG_FIELD##_SHIFT 就相当与CSL_PER_REG_FIELD_SHIFT
CSL_##PER_REG_FIELD##_MASK 就相当于CSL_PER_REG_FIELD_MSK
对比CSL_FINST(((CSL_DevRegs*)CSL_DEV_REGS)->PERCFG1, DEV_PERCFG1_EMIFACTL, ENABLE);
发现宏定义CSL_FMK和CSL_FINST中的参数PER_REG_FIELD是被DEV_PERCFG1_EMIFACTL所替换
所以CSL_PER_REG_FIELD_MSK就相当于CSL_DEV_PERCFG1_EMIFACTL_MSK
CSL_PER_REG_FIELD_SHIFT就相当于CSL_DEV_PERCFG1_EMIFACTL_SHIFT
而在第二步中我们已经知道CSL_DEV_PERCFG1_EMIFACTL_MSK是等于0x00000001u的
CSL_DEV_PERCFG1_EMIFACTL_SHIFT是等于0x00000000u的
其次,我们再来看,参数ENABLE
由以上的分析,我们可以知道CSL_##PER_REG_FIELD##_##TOKEN就相当于CSL_DEV_PERCFG1_EMIFACTL_ENABLE
再由第二步中,CSL_DEV_PERCFG1_EMIFACTL_ENABLE 是等于0x00000001u的
最后还原三个宏定义:
CSL_FMK: (((val) << CSL_##PER_REG_FIELD##_SHIFT) & CSL_##PER_REG_FIELD##_MASK)
还原后:(((1) << 0) & 1) 结果为1
CSL_FINS: ((reg) = ((reg) & ~1) | CSL_FMK(PER_REG_FIELD, val))
还原后:((reg) = ((reg) & ~1) | 1 ) 结果为reg的最后一位为1
第五步:
回到第一步中寄存器的描述中,可知寄存器PERCFG1中的位EMIFACTL被置一了,
也就是使能了EMIFA 外设。