EMIF_FMKS(转)

今天刚上手一块SEED-DEC6713,看到EMIF_FMKS(GBLCTL,NOHOLD,DISABLE)甚是不解,以前没有碰到过这种写法所以查阅资料理解如下。

DSP开发板自带程序中有如下语句:

EMIF_Config MyEMIFcfg0={
  0x30        |
  EMIF_FMKS(GBLCTL,NOHOLD,DISABLE) |
  EMIF_FMKS(GBLCTL,CLK1EN,DISABLE) |
  EMIF_FMKS(GBLCTL,CLK2EN,ENABLE),……}

EMIF_FMKS(GBLCTL,NOHOLD,DISABLE)是在CSL_emifahal.h里预定义的一个宏,如下:
#define EMIF_FMKS(REG,FIELD,SYM)\
    _PER_FMKS(EMIF,##REG,##FIELD,##SYM)

这里有##和\两个符号需要大家理解一下,举个例子:

1、“##”是宏定义中使用的连字符。

#define a(w, h)   a_##w##x##h
那么a(720, 576) 就等价于 a_720x576

2、‘\’ 是程序换行符。用法就顾名思义了,需要注意的是‘\’的后面不能有空格,那样它会失效,编译会出问题的。

所以上面的语句可以等同于#define EMIF_FMKS(REG,FIELD,SYM)  _PER_FMKS(EMIF,##REG,##FIELD,##SYM)

看到这里 貌似有点思路了吧……嘿嘿,下面继续:

根据《TMS320C6000 Chip Support Library API Reference Guide》查找上语句操作如下:

Field Make Symbolically <PER>_FMKS
Macro  <PER>_FMKS(<REG>,<FIELD>,<SYM>)
Arguments <REG> Register name
<FIELD> Field name
<SYM> Symbolic field value
Return Value Uint32 In-place and masked-field value
Description This macro takes the symbolic field value then shifts it over and masks it to
form the in-place field value. It can be bit-wise OR’ed with other FMK or FMKS
macros to form a register value as an alternative to the RMK macro.
Example Uint32 x;
x = DMA_FMKS(AUXCTL, CHPRI, HIGHEST)
  | DMA_FMKS(AUXCTL, AUXPRI, CPU);

以上中文我们可以理解为:根据define用法,上面的语句是操作_PER_FMKS(,,,)即:
_PER_FMKS(EMIF,REG,FIELD,SYM) //EMIFA是要操作的寄存器,REG=GBLCTL,FIELD=NOHOLD,SYM=DISABLE即:
_PER_FMKS(EMIF,GBLCTL,NOHOLD,DISABLE)

到此步步推入,可能写的有点繁琐如下:EMIF_FMKS(GBLCTL,NOHOLD,DISABLE)

等价于:_PER_FMKS(EMIF,GBLCTL,NOHOLD,DISABLE)

又根据宏定义:

    #define _PER_FMKS(PER,REG,FIELD,SYM) (\
    (_PER_FSYM(##PER,##REG,##FIELD,##SYM)<<_PER_FSHIFT(##PER,##REG,##FIELD))\
    &_PER_FMASK(##PER,##REG,##FIELD)\
  )

接着等价于:((_PER_FSYM(EMIF,GBLCTL,NOHOLD,DISABLE)<<_PER_FSHIFT(EMIF,GBLCTL,NOHOLD))&_PER_FMASK(EMIF,GBLCTL,NOHOLD))

根据宏定义:

   #define _PER_FSHIFT(PER,REG,FIELD) \
    _##PER##_##REG##_##FIELD##_SHIFT

  #define _PER_FMASK(PER,REG,FIELD) \
    _##PER##_##REG##_##FIELD##_MASK

  #define _PER_FSYM(PER,REG,FIELD,SYM)\
    PER##_##REG##_##FIELD##_##SYM

继续等价于:((_EMIF_GBLCTL_NOHOLD_DISABLE)<<_EMIF_GBLCTL_NOHOLD_SHIFT)&_EMIF_GBLCTL_NOHOLD_MASK)

好了:到此最后碰到问题了……这到底是什么意思呢?

原来

#define _PER_FSHIFT(PER,REG,FIELD) \
    _##PER##_##REG##_##FIELD##_SHIFT
假如:
你设置:_EMIF_FSHIFT(EMIF,GBLCTL,BUSREQ) 
那么就是:_EMIF_GBLCTL_BUSREQ_SHIFT
然后再一个CSL头文件中会有一个定义:
#define _EMIF_GBLCTL_BUSREQ_SHIFT    0x0000000Bu
然后说EMIF、GBLCTL、BUSREQ是怎么来的,那就需要看一些TI的文档了---CSL支持库的那个文档

我们查csl_emifhal.h头文件中可以看到

#define  EMIF_GBLCTL_NOHOLD_DISABLE  0x00000000u

#define _EMIF_GBLCTL_NOHOLD_SHIFT    0x00000007u

#define _EMIF_GBLCTL_NOHOLD_MASK     0x00000080u

最终等价:((_EMIF_GBLCTL_NOHOLD_DISABLE)<<_EMIF_GBLCTL_NOHOLD_SHIFT)&_EMIF_GBLCTL_NOHOLD_MASK)

即变成了0x00000000u

至此我们就完全理解了  这只是一种TI的写法而已 最终还是和我们平时接触的是一样的……

你可能感兴趣的:(EMIF_FMKS(转))