DSP

DSP CSL 片上支持库 EMIF

2019-07-13 09:53发布

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 #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. "); printf(" Reason: CSL_emifaInit [status = 0x%x]. ", status); return; } else { printf("EMIFA: Module Initialized. "); } /* 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] ", status, hEmifa); return; } else { printf("EMIFA: Module instance opened. "); } /* Setting up configuration parameter using HwSetup */ status = CSL_emifaHwSetup(hEmifa, &hwSetup); if (status != CSL_SOK) { printf("EMIFA: Error in HW Setup. "); printf("Read write operation fails "); return; } else { printf("EMIFA: Module Hardware setup is successful. "); } printf(" Info: Async read write "); while (1) { } return; }