嵌入式实操----基于RT1170 使能SEMC配置SDRAM功能(八)
本文主要是通过迁移的思维,记录本人初次使用NXP MCUXpresso SDK API进行BSP开发
MCUXpresso SDK SEMC API 接口链接
在MCUXpresso SDK 框架下提供了对SEMC DDR进行操作的接口。
学习链接:https://community.nxp.com/t5/MCUXpresso-Community-Articles/i-MX-RT-memory-validation/ba-p/1130828
1. 首先阅读原理图
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qTWOXGYP-1616410062182)(http://139.224.41.215:4999/server/../Public/Uploads/2021-03-22/6057feda1d181.png)]](https://img-blog.csdnimg.cn/20210322185058688.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl8zMDk2NTE3NQ==,size_16,color_FFFFFF,t_70)
DDR芯处使用IS42S32800J-6BLA1从手册上可以看得出来该芯片支持的最大工作时钟为166Mhz.
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ySJKUJ2a-1616410062187)(http://139.224.41.215:4999/server/../Public/Uploads/2021-03-22/6057ffa173d6b.png)]](https://img-blog.csdnimg.cn/20210322185118913.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl8zMDk2NTE3NQ==,size_16,color_FFFFFF,t_70)
但是从MCU的手册上可以看出其支持的最大速率为200Mhz.
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6CBTG5s3-1616410062191)(http://139.224.41.215:4999/server/../Public/Uploads/2021-03-22/60580129bcfb3.png)]](https://img-blog.csdnimg.cn/2021032218512937.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl8zMDk2NTE3NQ==,size_16,color_FFFFFF,t_70)
2. SDK api 应用
2.1 引脚配置
引脚复用配置
2.2 时钟配置
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-75JlQGrZ-1616410062196)(http://139.224.41.215:4999/server/../Public/Uploads/2021-03-22/6058272b304cd.png)]](https://img-blog.csdnimg.cn/20210322185151551.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl8zMDk2NTE3NQ==,size_16,color_FFFFFF,t_70)
从上图可以看到时钟源从SYM_PLL2_528Mhz至SYS_PLL2_PFD1(594Mhz)再通过4分频获取148.5MHz的时钟。
相关的配置代码如下所示:
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-f82yVIHQ-1616410062201)(http://139.224.41.215:4999/server/../Public/Uploads/2021-03-22/6058267a981aa.png)]](https://img-blog.csdnimg.cn/20210322185206782.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl8zMDk2NTE3NQ==,size_16,color_FFFFFF,t_70)
2.3 外设配置
对DDR的初始化,还是需要有前置知识的,了解DDR的工作时钟、时序相关知识,以及初始化的状态机。
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Rb44zg8B-1616410062204)(http://139.224.41.215:4999/server/../Public/Uploads/2021-03-22/60582a0331852.png)]](https://img-blog.csdnimg.cn/20210322185338503.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl8zMDk2NTE3NQ==,size_16,color_FFFFFF,t_70)
进入SEMC DDR的配置界面,如下所示:
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Lc7tfEvK-1616410062208)(http://139.224.41.215:4999/server/../Public/Uploads/2021-03-22/60582a2f3707f.png)]](https://img-blog.csdnimg.cn/20210322185441406.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl8zMDk2NTE3NQ==,size_16,color_FFFFFF,t_70)

第一,需要选择DDR的时钟源及其频率
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-L13QIjQ7-1616410062210)(http://139.224.41.215:4999/server/../Public/Uploads/2021-03-22/60582b1a49ef6.png)]](https://img-blog.csdnimg.cn/20210322185513925.png)
第二,需要DDR的数据锁存模式,我们选择DQS模式。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传![(img-6PpdiigO-1616410062212)(http://139.224.41.215:4999/server/../Public/Uploads/2021-03-22/60582afe564ca.png)]](https://img-blog.csdnimg.cn/20210322185523324.png)
第三、需要配置片选信号,这个和硬件设计相关
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oBB5pDrd-1616410062214)(http://139.224.41.215:4999/server/../Public/Uploads/2021-03-22/60582b7bc8b18.png)]](https://img-blog.csdnimg.cn/20210322185534863.png)
第四、需要配置内存的物理起始位置,这个和MCU的地址分配相关。

第五、需要配置内存的容量,和所选的SDRAM芯片容量保持一致。
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-q5YFmIFn-1616410062218)(http://139.224.41.215:4999/server/../Public/Uploads/2021-03-22/60582c0e1cf83.png)]](https://img-blog.csdnimg.cn/20210322185600710.png)
第六、配置SDRAM数据线的宽度及突发长度,数据宽度从原理图上可以看出来。突发长度可以从SDRAM手册上找到。


第七、配置列地址线的个数及CAS。列地址线的个数可以从手册上找出来,CAS可以选择2或者3也是在手册上的。
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OQ2SnkBN-1616410062223)(http://139.224.41.215:4999/server/../Public/Uploads/2021-03-22/60582fb3e39ec.png)]](https://img-blog.csdnimg.cn/20210322185625551.png)
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PdpxZ9Ru-1616410062224)(http://139.224.41.215:4999/server/../Public/Uploads/2021-03-22/60582f1dd4655.png)]](https://img-blog.csdnimg.cn/20210322185637642.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl8zMDk2NTE3NQ==,size_16,color_FFFFFF,t_70)
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-p4jbMJ2h-1616410062226)(http://139.224.41.215:4999/server/../Public/Uploads/2021-03-22/60583026eac64.png)]](https://img-blog.csdnimg.cn/20210322185648822.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl8zMDk2NTE3NQ==,size_16,color_FFFFFF,t_70)
第八、预充电(Precharge)至有效(active)的等待时间tRP,在166MHz,从手册上查得该数值>=18


第九、Active Command To Read / Write Command Delay Time (tRCD)

![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qUn0WMOr-1616410062234)(http://139.224.41.215:4999/server/../Public/Uploads/2021-03-22/60583551c0021.png)]](https://img-blog.csdnimg.cn/20210322185723104.png)
第十、刷新恢复时间 取tRFC/tXSR当中的最大值。


![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-q5kHX6uD-1616410062239)(http://139.224.41.215:4999/server/../Public/Uploads/2021-03-22/6058488c43a50.png)]](https://img-blog.csdnimg.cn/20210322185750751.png)
第十一、写恢复(write recovery)时间 tWR


第十二、CKE off minimun time, 一般取tRAS


第十三、active to precharge, 取tRAS


第十四、self refresh reovery time 自刷新恢复时间,取tXSR


第十五、refresh to refresh wait time 刷新至刷新的等待时间,取tRC.


第十六、active to active wait time 有效至有效的等待时间, 取tRC = tRAS + tRP = tRCD + tWR + tRP

第十七、prescaler timer period, 取160个tCLK时钟周期
160 * 1000000000 / semc_clk = 160 * 1000000000 / 148500000

第十八、sdram idle time 必须小于 tRAS, 而tRAS的最大值为100000ns
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kfv4jMU3-1616410062262)(http://139.224.41.215:4999/server/../Public/Uploads/2021-03-22/605861ba9e04c.png)]](https://img-blog.csdnimg.cn/20210322190055421.png)
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SIgHIUB7-1616410062265)(http://139.224.41.215:4999/server/../Public/Uploads/2021-03-22/60585419c8d2c.png)]](https://img-blog.csdnimg.cn/20210322190107665.png)
且有一个限制条件:
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KsOMMcJT-1616410062267)(http://139.224.41.215:4999/server/../Public/Uploads/2021-03-22/605856c4cc5ee.png)]](https://img-blog.csdnimg.cn/20210322190122309.png)
周期为 tPrescalePeriod_Ns = 160*100000000/semc_clk
ITO* 160 * 1000000000 / 148500000 < 100000,
ITO < 92.812
ITO取值意义如下,所以我们取[1,92]
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5Qzfhzhx-1616410062269)(http://139.224.41.215:4999/server/../Public/Uploads/2021-03-22/60585a5b0f6c3.png)]](https://img-blog.csdnimg.cn/20210322190148133.png)
第十九:refresh timer period /refresh upgent period, 从手册上可以看到刷新4096次,总用耗时64ms,每次的刷新时间为 64*1000000/4096,两者相同值。
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TYL1SxUl-1616410062270)(http://139.224.41.215:4999/server/../Public/Uploads/2021-03-22/6058610be8c32.png)]](https://img-blog.csdnimg.cn/20210322190217271.png)

2.4 验证测试
SDRAM 时钟配置成148.5Mhz:
Index: D:/svn/SDK_2.8.0_MIMXRT1170-EAR3/boards/easyarm-rt1170-revb/driver_examples/semc/sdram/cm7/clock_config.c
===================================================================
--- D:/svn/SDK_2.8.0_MIMXRT1170-EAR3/boards/easyarm-rt1170-revb/driver_examples/semc/sdram/cm7/clock_config.c (revision 7)
+++ D:/svn/SDK_2.8.0_MIMXRT1170-EAR3/boards/easyarm-rt1170-revb/driver_examples/semc/sdram/cm7/clock_config.c (working copy)
@@ -136,7 +136,7 @@
CLOCK_InitPfd(kCLOCK_PllSys2, kCLOCK_Pfd1, 16);
/* Configure Semc using SysPll2Pfd1 divided by 3 */
rootCfg.mux = kCLOCK_SEMC_ClockRoot_MuxSysPll2Pfd1;
- rootCfg.div = 3;
+ rootCfg.div = 4;
CLOCK_SetRootClock(kCLOCK_Root_Semc, &rootCfg);
#endif
最终针对148.5Mhz时钟的SDRAM配置代码如下所示:
status_t BOARD_InitSEMC(void)
{
semc_config_t config;
semc_sdram_config_t sdramconfig;
uint32_t clockFrq = EXAMPLE_SEMC_CLK_FREQ;
/* Initializes the MAC configure structure to zero. */
memset(&config, 0, sizeof(semc_config_t));
memset(&sdramconfig, 0, sizeof(semc_sdram_config_t));
/* Initialize SEMC. */
SEMC_GetDefaultConfig(&config);
config.dqsMode = kSEMC_Loopbackdqspad; /* For more accurate timing. */
SEMC_Init(SEMC, &config);
/* Configure SDRAM. */
sdramconfig.csxPinMux = kSEMC_MUXCSX0;
sdramconfig.address = 0x80000000;
sdramconfig.memsize_kbytes = 32 * 1024; /* 32MB = 32*1024*1KBytes*/
sdramconfig.portSize = kSEMC_PortSize32Bit;
sdramconfig.burstLen = kSEMC_Sdram_BurstLen8;
sdramconfig.columnAddrBitNum = kSEMC_SdramColunm_9bit;
sdramconfig.casLatency = kSEMC_LatencyThree;
sdramconfig.tPrecharge2Act_Ns = 18; /* Trp 18ns */
sdramconfig.tAct2ReadWrite_Ns = 18; /* Trcd 18ns */
sdramconfig.tRefreshRecovery_Ns = 70; /* Use the maximum of the (Trfc , Txsr). */
sdramconfig.tWriteRecovery_Ns = 12; /* 12ns */
sdramconfig.tCkeOff_Ns =
42; /* The minimum cycle of SDRAM CLK off state. CKE is off in self refresh at a minimum period tRAS.*/
sdramconfig.tAct2Prechage_Ns = 42; /* Tras 42ns */
sdramconfig.tSelfRefRecovery_Ns = 70;
sdramconfig.tRefresh2Refresh_Ns = 60;
sdramconfig.tAct2Act_Ns = 60;
sdramconfig.tPrescalePeriod_Ns = 160 * (1000000000 / clockFrq);
sdramconfig.refreshPeriod_nsPerRow = 64 * 1000000 / 4096; /* 64ms/8192 */
sdramconfig.refreshUrgThreshold = sdramconfig.refreshPeriod_nsPerRow;
sdramconfig.refreshBurstLen = 1;
sdramconfig.delayChain = 2;
sdramconfig.tIdleTimeout_Ns = 92;
return SEMC_ConfigureSDRAM(SEMC, kSEMC_SDRAM_CS0, &sdramconfig, clockFrq);
}
测试结果如下所示:
SEMC SDRAM Example Start!
EXAMPLE_SEMC_CLK_FREQ: 148500000
SEMC SDRAM Write 32 bit Start, Start Address 0x80000000, Data Length 8388607 !
SEMC SDRAM Read 32 bit Data Start, Start Address 0x80000000, Data Length 8388607 !
SEMC SDRAM Write 32 bit Start, Start Address 0x80000001, Data Length 8388607 !
SEMC SDRAM Read 32 bit Data Start, Start Address 0x80000001, Data Length 8388607 !
SEMC SDRAM Write 32 bit Start, Start Address 0x80000002, Data Length 8388607 !
SEMC SDRAM Read 32 bit Data Start, Start Address 0x80000002, Data Length 8388607 !
SEMC SDRAM Write 32 bit Start, Start Address 0x80000003, Data Length 8388607 !
SEMC SDRAM Read 32 bit Data Start, Start Address 0x80000003, Data Length 8388607 !
SEMC SDRAM 32 bit Data Write and Read Compare Succeed!
SEMC SDRAM Write 16 bit Start, Start Address 0x80000000, Data Length 16777215 !
SEMC SDRAM Read 16 bit Data Start, Start Address 0x80000000, Data Length 16777215 !
SEMC SDRAM Write 16 bit Start, Start Address 0x80000001, Data Length 16777215 !
SEMC SDRAM Read 16 bit Data Start, Start Address 0x80000001, Data Length 16777215 !
SEMC SDRAM 16 bit Data Write and Read Compare Succeed!
SEMC SDRAM Memory 8 bit Write Start, Start Address 0x80000000, Data Length 33554432 !
SEMC SDRAM Read 8 bit Data Start, Start Address 0x80000000, Data Length 33554432 !
SEMC SDRAM 8 bit Data Write and Read Compare Succeed!
SEMC SDRAM Example End.
4. 总结
默认DDR工作时钟为198Mhz,本文将其修改为148.5Mz.主要是针对SDRAM各参数如何从芯片中获取,取值的约束条件做了详细说明,至于各参数的具体含义可以从DDR的协议规范当中找到,或者芯片手册当中学到。
浙公网安备 33010602011771号