小猫爪:i.MX RT1050学习笔记8-SEMC
1 前言
在介绍RT1050启动的时候说到RT支持各种外部存储器启动,其中一个外部存储器接口就是SEMC(Smart External Memory Controller),其可以支持SDRAM,SRAM,NOR Flash, NAND Flash,还可以支持8080显示器,接下来就对其简单介绍一下。
2 SEMC
RT10529 使用SEMC 外设来管理扩展的存储器,SEMC 是Smart External Memory Controller 的缩写,译为智能的外部存储控制器。它可以用于驱动包括SRAM、SDRAM、NorFlash、NAND Flash 等类型的存储器以及使用8080 接口协议(DBI 接口)的显示器和设备。本章节中我们只讲述SEMC控制SDRAM的功能。SEMC 支持使用8、16 位的方式访问SDRAM,最多支持控制4 个SDRAM存储器,每个SDRAM存储器最大容量为512Mb(64MByte),支持使用ARM内核的AXI 接口控制SDRAM。
下面介绍一下SEMC的基本特征。
①支持8个存储区域,每个存储区域大小可达512Mbit
②支持AXI接口和IP总线接口
③SDRAM:支持8/16位模式,支持4片选信号
④NAND:支持8/16位模式,不支持 HW ECC,对于AXI写操作支持32位传输
⑤NOR:支持16位模式,支持异步模式,仅支持IP操作,支持ADMUX和AADM
⑥SRAM:支持16位模式,支持异步模式,支持ADMUX和AADM
以上的一些特征只是我挑了一部分说了一下,对于其具体的特征大家可以自行参考官方文档参考指南。
(注:在这里的ADMUX和AADM分别为Address/Data Multiple模式以及Advanced Address/Data Multiple模式,其中Address/Data Multiple模式简单的来说就是数据线可以当地址线使用,其中ADMUX模式最大支持16位数据选址,而AADM则最大支持24位选址。)
2.1 SEMC的结构
SEMC的模块框架图如下图所示:
从图中,我们可以清楚地看到SEMC的五个部分,分别是AXI接口控制器,IP总线接口控制器,AXI/IP仲裁器,存储器控制器和IO控制器。从图中就可以清楚地看出我们可以通过AXI和IP两种接口去访问存储器接口器,然后通过IO接口对外部存储器进行读写操作。
2.2 AXI和IP
SMEC支持使用IP 命令和AXI 命令控制外部存储器。
2.2.1 AXI
AXI 是Advanced eXtensible Interface 的缩写,这是ARM 公司提出的AMBA 协议的一部分,是一种高性能、高带宽、低延迟的片内总线。
在RT1052 中,地址0x8000 0000~0xDFFF FFFF 的1.5GB 空间是分配给SEMC 的外部存储器的映射区域,使用SEMC 控制的SDRAM、NOR、 PSRAM、NAND 以及 8080 接口的设备共用该空间,在初始化存储设备参数的时候可在该区域指定具体映射的基地址。例如指定SDRAM使用0x8000 0000 作为基地址,NAND Flash 使用0000 作为基地址。当访问这些映射的地址时,会触发AXI 命令,从而使SEMC外设产生控制时序从对应的外部存储器中访问数据。
2.2.1 IP
使用IP 命令访问实际上就是通过向相应的寄存器写入配置,从而使SEMC 产生访问时序的方式。相关的寄存器有IP 命令控制寄存器IPCR0/1/2、IP 命令寄存器IPCMD 以及收发数据寄存器IPRXDAT/IPTXDAT。控制的流程如下:
(1) 通过IPCR0/1/2 以及IPTXDAT 寄存器设置好要访问的设备地址、传输的数据大小、写屏蔽(即类似UDQM、LDQM的配置)以及要传输的数据;
(2) 通过IPCMD 寄存器设置好要发送的访问指令,例如控制SDRAM时的预充电(PRECHARGE)、行有效(ACTIVE)、读写等指令(READ/WRITE)等;
(3) 等待IP命令执行完成;
(4) 若是读访问,可通过IPRXDAT 寄存器得到存储器返回的数据。使用IP 命令控制SEMC 时,可以通过NXP 提供的库函数SEMC_SendIPCommand 来实现。
2.3 IO接口定义
下表列出SEMC复用引脚相关信息。
引脚名称 | SDRAM | NAND | NOR (ADMUX16bit) |
SRAM (ADMUX16bit) |
DBI |
---|---|---|---|---|---|
SEMC_DATA00 | D0 | D0 | D0/A0 | D0/A0 | D0 |
SEMC_DATA01 | D1 | D1 | D1/A1 | D1/A1 | D1 |
SEMC_DATA02 | D2 | D2 | D2/A2 | D2/A2 | D2 |
SEMC_DATA03 | D3 | D3 | D3/A3 | D3/A3 | D3 |
SEMC_DATA04 | D4 | D4 | D4/A4 | D4/A4 | D4 |
SEMC_DATA05 | D5 | D5 | D5/A5 | D5/A5 | D5 |
SEMC_DATA06 | D6 | D6 | D6/A6 | D6/A6 | D6 |
SEMC_DATA07 | D7 | D7 | D7/A7 | D7/A7 | D7 |
SEMC_DATA08 | D8 | D8 | D8/A8 | D8/A8 | D8 |
SEMC_DATA09 | D9 | D9 | D9/A9 | D9/A9 | D9 |
SEMC_DATA10 | D10 | D10 | D10/A10 | D10/A10 | D10 |
SEMC_DATA11 | D11 | D11 | D11/A11 | D11/A11 | D11 |
SEMC_DATA12 | D12 | D12 | D12/A12 | D12/A12 | D12 |
SEMC_DATA13 | D13 | D13 | D13/A13 | D13/A13 | D13 |
SEMC_DATA14 | D14 | D14 | D14/A14 | D14/A14 | D14 |
SEMC_DATA15 | D15 | D15 | D15/A15 | D15/A15 | D15 |
SEMC_DM1 | DQM1 | - | - | UB# | - |
SEMC_DM0 | DQM0 | - | - | LB# | - |
SEMC_ADDR00 | A0 | - | A16 | A16 | - |
SEMC_ADDR01 | A1 | - | A17 | A17 | - |
SEMC_ADDR02 | A2 | - | A18 | A18 | - |
SEMC_ADDR03 | A3 | - | A19 | A19 | - |
SEMC_ADDR04 | A4 | - | A20 | A20 | - |
SEMC_ADDR05 | A5 | - | A21 | A21 | - |
SEMC_ADDR06 | A6 | - | A22 | A22 | - |
SEMC_ADDR07 | A7 | - | A23 | A23 | - |
SEMC_ADDR08 | A8 | CE# | CE#/A24 | CE#/A24 | |
SEMC_ADDR09 | A9 | CLE | - | CRE | - |
SEMC_ADDR10 | A10 | - | - | - | - |
SEMC_ADDR11 | A11 | WE# | WE# | WE# | |
SEMC_ADDR12 | A12 | RE# | OE# | OE# | |
SEMC_BA0 | BA0 | - | - | - | - |
SEMC_BA1 | BA1 | ALE | ADV# | ADV# | DCX |
SEMC_CAS | CAS# | - | - | - | - |
SEMC_RAS | RAS# | - | - | - | - |
SEMC_WE | WE# | - | - | - | - |
SEMC_CKE | CKE | - | - | - | - |
SEMC_CLK | CLK | - | - | - | - |
SEMC_CS0 | CS0 | - | - | - | - |
SEMC_CSX0 | CS | CE# | CE# | CE# | CSX |
SEMC_CSX1 | CS | CE# | CE# | CE# | CSX |
SEMC_CSX2 | CS | CE# | CE# | CE# | CSX |
SEMC_CSX3 | CS | CE# | CE# | CE# | CSX |
SEMC_RDY | CS | R/B# | CE# | CE# | CSX |
SEMC_DQS | DQS | - | DQS | DQS | - |
我们从这张表中不难看出只有NOR和SRAM支持ADMUX(Address/Data MUX Mode)。
3 SEMC应用实例
我们在使用SEMC时,一般应用上会使用SDRAM和NAND比较多,使用SDRAM来扩展RAM,使用NAND作为启动设备和存储设备,至于NOR则是更多的使用串行NOR,并行NOR现在也不怎么多见了,外置SRAM则成本太高,用的概率则也不会太多。下面我们举SDRAM和NAND的例子来说明一下SEMC的具体使用方法。
3.1 SEMC-SDRAM
一般用户会采用外加SDRAM来增加RAM大小。根据引脚定义描述表进行硬件连接,一般都不会出什么问题。
(注意DQS:在这里需要注意的一点就是DQS这个信号,在使用SDRAM时,需要将RT1052 的这个SEMC_DQS 引脚悬空,然后在软件配置方面必须开启该引脚的SION 功能。SEMC 的模块控制寄存器MCR[DQSMD]位置1,即配置为使用DQS 引脚的读选通信号。寄存器位MCR[DQSMD],它用于选择DQS 的读选通模式,可选值分别为使用内部回环的读选通信号(kSEMC_Loopbackinternal)和从DQS 引脚得到的读选通信号(kSEMC_Loopbackdqspad),DQS 信号用于接收方更准确地接收数据,应用时需要把它设置成kSEMC_Loopbackdqspad 才能以高频率的时钟访问SDRAM。)
NXP官方的SDK提供了非常方便的初始化函数,分别是初始化SEMC控制器的SEMC_Init和初始化SDRAM控制器的SEMC_ConfigureSDRAM。具体的应用细节大家可以参考NXP的SDK包中SEMC的实例程序。
(注意:在一些应用中常常希望能够把SDRAM用作C程序的堆、栈又或者是具有初始值的全局变量,甚至是希望在调试阶段直接把代码下载到SDRAM中运行,在这些情况下我们必须把SDRAM的初始化过程确保初始化C语言运行环境时或下载代码到SDRAM时存储器已经能正常访问。在这里我们可以通过两种方法去实现,第一种则是针对debug时,使用脚本文件来进行初始化;第二种则是针对从外部存储器启动的情况下,通过配置iamge文件中DCD数据进行初始化,具体操作我会在后面的文章中作详细的介绍。)
3.1 SEMC-NAND
NXP官方的SDK提供了非常方便的初始化函数,分别是初始化SEMC控制器的SEMC_Init和初始化SDRAM控制器的Nand_Flash_Init。而且还提供了相关的读写命令函数,都在SDK包里的fsl_semc_nand_flash.c文件里,大家可以自行去参考,在这里则不再多说了。
(注意:同SARAM一样,如果使用NAND作为启动设备时,则需要进行提前初始化,但是这里得注意一点的就是NAND不支持XIP,所以其也不支持debug。)
END