DSP 的EMIF 接口,常用于DSP 扩展外部存储器,可外接同步存储器也可接异步存储器
本文主要讲解了基于CSL的EMIF 接口的配置。
要对EMIF进行配置,要按如下过程:
第一步:
打开EMIF 控制器,对于TMS320C6455 要执行一下代码:
CSL_FINST(((CSL_DevRegs*)CSL_DEV_REGS)->PERCFG1, DEV_PERCFG1_EMIFACTL, \
ENABLE);
该代码是如何实现对EMIF 控制器的使能在上一文中已经详细分析过,这里不在重复。
第二步:
执行函数CSL_emifaInit(NULL)初始化EMIF CSL 模块,代码如下:
CSL_Status status;
status = CSL_emifaInit(NULL);
第三步:
执行函数CSL_emifaOpen打开EMIF 设备,代码如下:
CSL_Status status;
CSL_EmifaObj emifaObj;
CSL_EmifaHandle hEmifa;
status CSL_emifaInit(NULL);
hEmifa = CSL_emifaOpen( &emifaObj, CSL_EMIFA, NULL, &status);
第四步:
执行函数CSL_emifaHwSetup对EMIF 设备进行配置,代码如下:
CSL_EmifaHandle hEmifa;
CSL_EmifaAsync asyncMem = CSL_EMIFA_ASYNCCFG_DEFAULTS;
CSL_EmifaAsyncWait asyncWait = CSL_EMIFA_ASYNCWAIT_DEFAULTS;
CSL_EmifaMemType value;
CSL_EmifaHwSetup hwSetup;
CSL_Status status;
value.ssel = 0;
value.async = &asyncMem;
value.sync = NULL;
hwSetup.asyncWait = &asyncWait;
hwSetup.ceCfg[0] = &value;
hwSetup.ceCfg[1] = NULL;
hwSetup.ceCfg[2] = NULL;
hwSetup.ceCfg[3] = NULL;
//Initialize and Open the Emifa CSL
...
//Open Emifa Module
status = CSL_emifaHwSetup(hEmifa, &hwSetup);
...
第五步:
配置完毕,在执行完以上几步后,就可以通过EMIF 接口对存储器进行操作了。
——————————————————————————————————————————————————
重点来了,如何知道怎么配置EMIF 接口呢??也就是第五步中的hwSetup 变量如何来定义与赋值???
这就是本文所要将的重点。
——————————————————————————————————————————————————
首先要知道hwSetup 变量如何来定义的,看一下代码:
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;
该变量中包含了两个指针结构体变量,*asyncWait 该变量用于配置异步等待配置寄存器,
*ceCfg[NUMCHIPENABLE] 该变量用于选择所要配置的寄存器类型,同步还是异步
其中NUMCHIPENABLE在CSL 中已经定义为4,因为有四个空间CE2-CE5
再来看看*asyncWait 该变量是如何定义的,如下:
typedef struct {
/** Asynchronous Ready Pin Polarity */
CSL_EmifaArdyPol asyncRdyPol;
/** Maximum Extended Wait cycles */
Uint8 maxExtWait;
/** Turn Around cycles */
Uint8 turnArnd;
} CSL_EmifaAsyncWait;
该变量又有三个变量,第一个asyncRdyPol,表示异步Ready 信号的极性,是个枚举类型。
第二个变量maxExtWait,表示异步存储器的最大等待周期数
第三个变量turnArnd,表示翻转周期数
枚举类型变量asyncRdyPol定义,如下:
typedef enum {
/** strobe period extended when ARDY is low */
CSL_EMIFA_ARDYPOL_LOW = 0,
/** strobe period extended when ARDY is high */
CSL_EMIFA_ARDYPOL_HIGH = 1
} CSL_EmifaArdyPol;
接下来看看变量*ceCfg[NUMCHIPENABLE]的定义,如下:
typedef struct {
/** Synchronous/asynchronous memory select. Asynchronous memory mode
* when ssel is set to 0 and synchronous when ssel is 1.
*/
Uint8 ssel;
/** Pointer to structure of asynchronous type. The pointer
* value should be NULL if the chip select value is synchronous.
*/
CSL_EmifaAsync *async;
/** Pointer to structure of synchronous type. The pointer value
* should be NULL if the chip select value is asynchronous.
*/
CSL_EmifaSync *sync;
} CSL_EmifaMemType;
其中ssel是用来选择存储器类型的,同步还是异步
变量*async又是一个结构体,是对异步存储器的一些参数的设置
变量*sync又是一个结构体,是对同步存储器的一些参数的设置
看看变量*async的定义:
typedef struct {
/** Select Strobe Mode Enable */
Uint8 selectStrobe;
/** Select WE Strobe Mode Enable */
Uint8 weMode;
/** Asynchronous Ready Input Enable */
Uint8 asyncRdyEn;
/** Write Setup Width */
Uint8 wSetup;
/** Write Strobe Width */
Uint8 wStrobe;
/** Write Hold Width */
Uint8 wHold;
/** Read Setup Width */
Uint8 rSetup;
/** Read Strobe Width */
Uint8 rStrobe;
/** Read Hold Width */
Uint8 rHold;
/** Asynchronous Memory Size */
Uint8 asize;
} CSL_EmifaAsync;
每个参数的含义是什么,可以查看CSL API 参考手册
看看变量*sync的定义:
typedef struct {
/** Read Byte Enable enable */
Uint8 readByteEn;
/** Synchronous Memory Chip Enable Extend */
Uint8 chipEnExt;
/** Synchronous Memory Read Enable Mode */
Uint8 readEn;
/** Synchronous Memory Write Latency */
Uint8 w_ltncy;
/** Synchronous Memory Read Latency */
Uint8 r_ltncy;
/** Synchronous Memory Device Size */
Uint8 sbsize;
} CSL_EmifaSync;
每个参数的含义是什么,可以查看CSL API 参考手册
————————————————————————————————————
上面对hwSetup 变量进行了细致深入的介绍,相信大家,可能有点云里雾里的感觉,
下面我们来看看下面这幅图:
相信大家看了这图后,对该变量的结构和层次有了一个比较清楚的了解。
一下代码是将CE2配置为同步存储器接口模式,代码如下:
/*
* main.c
*/
#include <stdio.h>
#include "Define.h"
#include "csl_emifa.h"
#include "cslr_dev.h"
#define EMIFA_MEMTYPE_ASYNC 0
#define EMIFA_MEMTYPE_SYNC 1
extern int g_Reversal;
/* Handle for the EMIFA instance */
CSL_EmifaHandle hEmifa;
void main(void) {
Uint32 data_read=0;
CSL_EmifaObj emifaObj;
CSL_Status status;
CSL_EmifaHwSetup hwSetup ;
CSL_EmifaMemType synValCe2;
CSL_EmifaSync syncMemCe2=CSL_EMIFA_SYNCCFG_DEFAULTS;
CSL_FINST(((CSL_DevRegs*)CSL_DEV_REGS)->PERCFG1, DEV_PERCFG1_EMIFACTL, \
ENABLE);
synValCe2.ssel = EMIFA_MEMTYPE_SYNC;
synValCe2.async = NULL;
synValCe2.sync = &syncMemCe2;
syncMemCe2.readByteEn = 0;
syncMemCe2.chipEnExt=0 ;
syncMemCe2.readEn=1;
syncMemCe2.w_ltncy=0;
syncMemCe2.r_ltncy=0;
syncMemCe2.sbsize=2;
/* setup the hardware parameters */
hwSetup.asyncWait = &asyncWait;
hwSetup.ceCfg[0] = &synValCe2;
hwSetup.ceCfg[1] = NULL;
hwSetup.ceCfg[2] = NULL;
hwSetup.ceCfg[3] = NULL;
/* Initialize EMIFA CSL module */
status = CSL_emifaInit(NULL);
if (status != CSL_SOK) {
printf("EMIFA: Initialization error.\n");
printf("\tReason: CSL_emifaInit [status = 0x%x].\n", status);
return;
}
else {
printf("EMIFA: Module Initialized.\n");
}
/* Opening the EMIFA instance */
hEmifa = CSL_emifaOpen(&emifaObj, CSL_EMIFA, NULL, &status);
if ((status != CSL_SOK) || (hEmifa == NULL)) {
printf("EMIFA: Error opening the instance. [status = 0x%x, hEmifa \
= 0x%x]\n", status, hEmifa);
return;
}
else {
printf("EMIFA: Module instance opened.\n");
}
/* Setting up configuration parameter using HwSetup */
status = CSL_emifaHwSetup(hEmifa, &hwSetup);
if (status != CSL_SOK) {
printf("EMIFA: Error in HW Setup.\n");
printf("Read write operation fails\n");
return;
}
else {
printf("EMIFA: Module Hardware setup is successful.\n");
}
printf("\tInfo: Async read write \n");
while (1)
{
}
return;
}