BF533的SDRAM控制器最大支持128M bytes的SDRAM空间;总线宽度可以配置为4位、8位、16位。处理器与SDRAM的连线包括数据总线D[0:15]、地址总线A[1:19]、SDRAM刷新专用信号SA10,时钟信号SCLK、时钟使能信号SCKE、行锁存信号SRAS#,列锁存信号SCAS#,写使能信号SWE#,片选信号SMS#和总线屏蔽信号ABE[1:0].
SDRAM的起始地址为0x0000 0000,尾地址为0x03ff ffff,共64MB;若为32MB SDRAM,则尾地址为0x01ff ffff;
1.如何配置EBIU的寄存器
首先,在所使用的SDRAM的手册中,找到时序参数,如下图所示:
假设SCLK=135M,即7.4ns:
a.配置EBIU_SDRRC:SDRAM刷新率控制器;
- fsclk=135M=135*10^6 Hz----------系统总线频率;
- 查上表得,tREF=64 ms= 0.064 s;-------SDRAM行刷新时间;
- NRA为refresh cycles:NRA=8192----行数
- tRAS=从存储体激活到预充电之间的时间,以时钟周期为单位:44 /7.4=6;
- tRP=存储体从预充电到再次被激活之间的最小时间,以时钟周期为单位:20/7.4=3
RDIV = (135*10^6*0.064)/8192-(6+3)=0x415;
b.配置SDBCTL:存储体控制寄存器
c.配置SDGCTL:SDRAM全局控制器
TWR位:存储器手册上要求1clk+7.5ns,所以需要3个clk;其它位的计算相同;
最后,得到的各个寄存器的值如下:
void Init_SDRAM(void) { *pEBIU_SDRRC = 0x00000415; // *pEBIU_SDBCTL = 0x0025; //64 MB,10bit width *pEBIU_SDBCTL = 0x0013; //32 MB,9bit width *pEBIU_SDGCTL = 0x0099998d; // 0x0091998d; ssync(); }
为了对SDRAM进行测试,可以用下面的函数对其进行遍历,具体的使用方法如下:
#define pADDR (volatile unsigned short *)0x1000 #define SDRAM_START 0x00000000 // start address of SDRAM //#define SDRAM_SIZE 0x04000000 // 64 MB #define SDRAM_SIZE 0x02000000 // 32 MB void ezTurnOnLED(uint16_t led); int TEST_SDRAM(void); void main(void) { int i; Set_PLL(22,5); //cclk = 27*22=594M,sclk=594/5=118M Init_EBIU(); Init_SDRAM(); *pADDR = 0x1234; i = *pADDR; printf("addr is %x\n",pADDR); printf("data is %x\n",i); *pADDR = 0xaa55; i = *pADDR; printf("addr is %x\n",pADDR); printf("data is %x\n",i); if( 0 == TEST_SDRAM()) { printf("Test Failed!\r\n"); } else printf("Test Successed!\r\n"); while(1); } /************************************************************************* *函数功能:测试SDRAM; *入口参数:无; *出口参数: 测试正常,返回1,否则返回0 *注意:根据SDRAM的位宽修改nIndex和pDst的类型; ************************************************************************/ int TEST_SDRAM(void) { volatile unsigned short *pDst; unsigned short nIndex = 0xFFFF; //16位位宽 int bPass = 1; // returning 1 indicates a pass, anything else is a fail // write all FFFF's for(pDst = (unsigned short *)SDRAM_START; pDst < (unsigned short *)(SDRAM_START + SDRAM_SIZE); pDst++ ) { *pDst = nIndex; } // verify all FFFF's for(pDst = (unsigned short *)SDRAM_START; pDst < (unsigned short *)(SDRAM_START + SDRAM_SIZE); pDst++ ) { if( nIndex != (*pDst) ) { bPass = 0; return false; } } // write all AAAAAA's for(nIndex = 0xAAAA, pDst = (unsigned short *)SDRAM_START; pDst < (unsigned short *)(SDRAM_START + SDRAM_SIZE); pDst++ ) { *pDst = nIndex; } // verify all AAAAA's for(nIndex = 0xAAAA, pDst = (unsigned short *)SDRAM_START; pDst < (unsigned short *)(SDRAM_START + SDRAM_SIZE); pDst++ ) { if( nIndex != *pDst ) { bPass = 0; return false; } } // write all 555555's for(nIndex = 0x5555, pDst = (unsigned short *)SDRAM_START; pDst < (unsigned short *)(SDRAM_START + SDRAM_SIZE); pDst++ ) { *pDst = nIndex; } // verify all 55555's for(nIndex = 0x5555, pDst = (unsigned short *)SDRAM_START; pDst < (unsigned short *)(SDRAM_START + SDRAM_SIZE); pDst++ ) { if( nIndex != *pDst ) { bPass = 0; return false; } } return true; }