转自:http://www.61ic.com/Article/C6000/C64X/201303/47507.html
1 ABSTRACT
2 在CCS中添加CSL的头文件和库文件
3 以EMIFA为例分析CSL的架构
3.1 CSL中EMFIA的example
3.1.1 初始化并打开EMFIA
3.1.2 配置EMIFA的硬件
ABSTRACT
开发C6455的应用程序,一定会使用TI 提供的CSL(Chip Support Library),CSL 提供的API已经将底层的实现细节给我包装好了,我们只需要直接调用这些API就可以了。但是为了更好的使用这些API,我们很有必要仔细的分析这些API函数是怎样实现的。
这篇文章中我以EMIFA接口为例子,分析CSL 的相应API函数和结构体定义。
在CCS中添加CSL的头文件和库文件
CCS(Code Composer Studio)是TI公司开发的用于其公司的DSP,MSP等芯片的综合开发工具,CCS5.x的版本是基于Eclipse开发的,而CCS4.x以及其前面的版本的开发平台我不太清楚。
我使用的是CCS5.2,在CCS5.x中,CSL的库并不是默认被包含的该CCS中的,在http://www.ti.com/tool/sprc234中可以下载到最新的CSL库,下载下来的CSL库如下,里面包含了这个库实现的源代码和我们需要的库文件和头文件,以及一个PDF格式的API Reference。
从上面的图我们可以看到,这个版本的CSL已经把INTC(中断管理)做出一个单独的模块了,而其他的外设放在了另外一个模块中。
使用的时候,我们必须在工程中加入头文件我库文件所在的路径以及库文件的名字,这样在编译器编译和链接的时候才能找到它们,不然会提示找不到的错误。
以EMIFA为例分析CSL的架构
EMIFA的CSL API做得相当的规整,主要有以下的函数,而这些函都是CSL中每一个外设都会实现
是从API文档中截取下来的,其大概的描述了每一个函数所完成的事情。下面我以CSL中提供的example为例,说明一下其用法。
CSL中EMFIA的example
CSL中对每一个外设至少包含了一个example以帮助开发者快速的掌握其用法。
初始化并打开EMFIA
在Emifa_ReadWrite_example.c文件中有两个函数,在main函数中只有一句代码
CSL_FINST(((CSL_DevRegs*)CSL_DEV_REGS)->PERCFG1, DEV_PERCFG1_EMIFACTL, \
ENABLE);
要看懂这句话要一定的时间,但是我们知道其做的事情就是配置PERCFG1打开EMIFA外设(对于一般的外设,我们需要先往PERLOCK中写入一个特定的UNLOCK值后才能打开,但是对于DDR2和EMIFA是可以直接打开的,详细的解释可以看相应的文档)。
打开EMIFA后,main函数直接调用emifaReadWrite()函数了。
在emifaReadWrite()中,第一个被调用的函数就是CSL_emifaInit(NULL),从上面的解释中可以看出,这个函数是optional的,查看了其源代码以后,会发现其什么也没有做,只是单纯的返回了一个CSL_OK。
第二个被调用的函数是
hEmifa = CSL_emifaOpen(&emifaObj, CSL_EMIFA, NULL, &status);
其函数原型为
CSL_EmifaHandle CSL_emifaOpen (
CSL_EmifaObj *hEmifaObj,
CSL_InstNum emifaNum,
CSL_EmifaParam *pEmifaParam,
CSL_Status *status
);
这个函数必须详细得看一看,其第一个参数是CSL_EmifaObj*类型的,这个类型里面其实有两个域
typedef struct CSL_EmifaObj {
/** This is a pointer to the registers of the instance of EMIFA
* referred to by this object
*/
CSL_EmifaRegsOvly regs;
/** This is the instance of EMIFA being referred to by this object */
CSL_InstNum perNum;
} CSL_EmifaObj;
CSL_EmifaRegsOvly中包含EMIF这个模块的所有寄存器,CSL_InstNum表示这是第几个EMIF模块(C6455中只有一个EMIF模块,所以这个值只能是0)。
CSL_EMIFA是一个宏,其真实的值为
/** @brief Peripheral Instance for EMIFA */
#define CSL_EMIFA (0)
也就是表示只有一个EMIF模块。
第三个参数是留着以后用的
typedef struct {
/** Bit mask to be used for module specific parameters. The below
* declaration is just a place-holder for future implementation. Passed as
* an argument to CSL_emifaOpen().
*/
CSL_BitMask16 flags;
} CSL_EmifaParam;
所以总是传入NULL。
第四个参数是CSL_Status*,这个参数实际上是同时作为输入和输出参数的。
这个函数在时间运行时,首先检查status是不是NULL,如果是NULL的话,它就返回一个NULL给hEmifa ,所以我们一定要保证传入的值不是NULL,如果我们总是用CSL_emifaInit(NULL)返回的值传入的话,这个条件就总是满足了,所以我们先调用CSL_emifaInit(NULL)函数,然后再调用CSL_emifaOpen。
该函数返回值为一个handler,其实际类型是一个指针
/** @brief This is a pointer to @a CSL_EmifaObj and is passed as the first
* parameter to all EMIFA CSL APIs
*/
typedef struct CSL_EmifaObj *CSL_EmifaHandle;
如果不太能够理解的话也没有关系,其他的API函数都会以这个handler作为其第一个参数。
配置EMIFA的硬件
成功的初始化并打开硬件后,就需要安装自己的要求配置硬件了
status = CSL_emifaHwSetup(hEmifa, &hwSetup);
主要开第二个参数,hwSetup是CSL_emifaHwSetup的一个变量,这儿要特别注意,这个函数的名字叫CSL_emifaHwSetup,而其参数的类型也是CSL_emifaHwSetup的指针,CSL_emifaHwSetup的定义如下
typedef struct {
/** Pointer to structure for configuring the Asynchronous Wait Cycle
* Configuration register
*/
CSL_EmifaAsyncWait *asyncWait;
/** Array of CSL_EmifaMemType* for configuring the Chip enables
* as Async or Sync memory type.
*/
CSL_EmifaMemType *ceCfg[NUMCHIPENABLE];
} CSL_EmifaHwSetup;
要注意的是,不同的外设,他们的HwSetup类型的定义是不一样的,因为这个结构体是与硬件(Hw—>Hardward) 相关的,其实在调用这个函数之前,hwSetup各个域已经被设置为我们想要的值了,相应的设置代码我就不copy下来了。