24 SEMC相关
文章目录
- 24.1 SEMC 简介
- 24.2 SEMC 框图剖析
- 24.2.1 通讯引脚
- 24.2.1.1 SEMC 的片选信号
- 24.2.1.2 数据选通信号 DQS
- 24.2.2 存储器控制器
- 24.2.3 IP 命令和 AXI 命令
- 24.2.4 驱动时钟
- 24.4 SEMC 初始化配置结构体
- 24.4.1 dqsMode
- 24.4.2 cmdTimeoutCycles
- 24.4.3 busTimeoutCycles
- 24.4.4 queueWeight
24.1 SEMC 简介
RT10529使用SEMC外设来管理扩展的存储器,SEMC是Smart External Memory Controller的缩写,译为智能的外部存储控制器。
- 可以用于驱动包括 SRAM、SDRAM、NorFlash、NAND Flash 等类型的存储器以及使用 8080 接口协议(DBI 接口)的显示器和设备。
- SEMC 支持使用 8、16 位的方式访问 SDRAM,最多支持控制 4 个 SDRAM 存储器,每个 SDRAM存储器最大容量为 512Mb(64MByte),支持使用 ARM 内核的 AXI 接口控制SDRAM。
24.2 SEMC 框图剖析
24.2.1 通讯引脚
右侧显示的是 SEMC 与外部多种类型存储设备的连接
- 地址线 SEMC_ADDR 和数据线 SEMC_DA 是所有控制器都共用的
24.2.1.1 SEMC 的片选信号
SEMC 外设把 SDRAM 的控制分成了 Region#0/1/2/3 四个区域
- 控制时每个区域有一个对应的片选信号 CS0/1/2/3
- 每个区域可以连接到一个外部 SDRAM 存储器进行控制
- 当触发访问到某区域时,与之对应的片选信号会使能与其连接的 SDRAM
RT1052 提供了可软件定制信号的引脚 SEMC_CSX0/1/2/3,它们中的任意一个引脚都可以“变形”成 CS1/2/3 中的任意一个信号
- CS0 片选信号只能使用 SEMC_CS0 引脚
24.2.1.2 数据选通信号 DQS
在 RT1052 中包含一个数据选通信号 SEMC_DQS,它是 DDR 类型的 SDRAM 中才有的信号
- 功能主要用来在一个时钟周期内准确地区分出每个传输周期,并便于接收方准确接收数据。
- 它是双向的,在写入时它用来传送由主控芯片发来的 DQS 信号,读取时,则由 SDRAM 芯片生成 DQS向主控发送,完全可以说,它就是数据的同步信号。
RT1052 不支持驱动 DDR 类型的 SDRAM
- 设计硬件时,必须使 RT1052 的这个 SEMC_DQS 引脚悬空
- 在软件配置方面必须开启该引脚的 SION 功能
- 而且要把 SEMC的模块控制寄存器 MCR[DQSMD] 位置 1,即配置为使用 DQS 引脚的读选通信号
24.2.2 存储器控制器
SEMC 外设内部包含有 SDRAM/NOR/SRAM/NAND/8080 设备使用的不同控制器
- 不同的控制器有专用的寄存器用于配置其工作模式。
例如配置 SEMC 通用控制的寄存器主要有 MCR、IOCR、BMCR0/1、IPCR0/1/2、IPCMD 以及 IP-TXDAT/IPRXDAT;
- SDRAM 专用的控制寄存器的为 BR0/1/2/3 以及 SDRAMCR0/1/2/3;
- NAND的专用控制寄存器为 BR4/8 以及 NANDCR0/1/2/3。
24.2.3 IP 命令和 AXI 命令
使用 FlexSPI 外设时,有 IP 命令和 AHB 命令两种方式,SEMC 外设也类似,它支持使用 IP 命令和 AXI 命令控制外部存储器。
- 其中 AXI 是 Advanced eXtensible Interface 的缩写,这是 ARM 公司提出的 AMBA 协议的一部分,是一种高性能、高带宽、低延迟的片内总线。
24.2.4 驱动时钟
控制 SDRAM 时,SEMC的 SEMC_CLK 线的时钟信号是由 SEMC 根时钟 SEMC_CLK_ROOT 提供的
SEMC 根时钟有 3 个可选输入来源:
- PLL2 PFD2:该时钟常规配置为 396MHz,为了 SDRAM 运行更稳定,本开发板把该时钟配置为 316.8MHz。
- PLL3 PFD1:该时钟常规配置为 454.74MHz。
- PERIPH CLK: 这 是 AHB_CLK_ROOT 的 时 钟 源,PERIPH CLK 分 频 后 得 到AHB_CLK_ROOT,SEMC 也可以使用这个时钟源
时钟源经过一个 3 位的分频器,它可对时钟进行 1~8 分频,分频后得到 SEMC 根时钟 SEMC_CLK_ROOT。
24.4 SEMC 初始化配置结构体
SEMC 配置结构体 semc_config_t
/*!
2 * @brief SEMC 配置结构体
3 * busTimeoutCycles: 当 busTimeoutCycles 设置为 0 时 , 总线的超时周期为
4 * 255*1024. 使用其它值时,总线周期为 busTimeoutCycles*1024
5 * cmdTimeoutCycles: 用于设置命令执行超时周期,与 busTimeoutCycles 类似
6 */
7 typedef struct _semc_config_t {
8 semc_dqs_mode_t dqsMode; /*!< Dummy 读选通模式 */
9 uint8_t cmdTimeoutCycles; /*!< 命令执行超时周期 */
10 uint8_t busTimeoutCycles; /*!< 总线超时周期 */
11 semc_axi_queueweight_t queueWeight; /*!< AXI queue weight. */
12 } semc_config_t;
24.4.1 dqsMode
寄存器位 MCR[DQSMD],它用于选择 DQS 的读选通模式
- 可选值分别为使用内部回环的读选通信号(kSEMC_Loopbackinternal)和从 DQS 引脚得到的读选通信号(kSEMC_Loopbackdqspad)。
- DQS 信号用于接收方更准确地接收数据,应用时需要把它设置成 kSEMC_Loopbackdqspad 才能以高频率的时钟访问 SDRAM
24.4.2 cmdTimeoutCycles
寄存器位 MCR[CTO],它用于设定命令执行超时周期
- 当 SEMC 命令的执行时间超过该配置值时,可触发 IPCMDERR 和 AXICMDERR 中断。
- 当此成员被赋值为 0 时,超时周期被配置为 2561024 个时钟周期,赋为其它值时被配置为 cmdTimeoutCycles1024。
24.4.3 busTimeoutCycles
寄存器位 MCR[BTO],它用于设定 AXI 总线超时周期
- 当此成员被赋值为 0 时,超时周期被配置为 2551024 个时钟周期,赋为其它值时被配置为 busTimeoutCycles1024。
24.4.4 queueWeight
寄存器位 BMCR0/1,在 AXI 接口控制器中包含有 Queue A 和 Queue B 两个队列用来缓冲
AXI 访问触发的请求
- queueWeight 就是用于定制 Queue A 和 Queue B 相关的权重配置,本成员本身也是一个结构体类型
1 /*! @brief SEMC AXI queue 权重配置 */
2 typedef struct _semc_axi_queueweight {
3 semc_queuea_weight_t *queueaWeight; /*!< queue a 的权重配置 */
4 semc_queueb_weight_t *queuebWeight; /*!< queue b 的权重配置 */
5 } semc_axi_queueweight_t;
6
7 /*! @brief SEMC AXI queue a 权重配置 */
8 typedef struct _semc_queuea_weight {
9 /*!< queue 0 的 qos 权重配置 */
10 uint32_t qos : 4;
11 /*!< queue 0 的 aging 权重配置 */
12 uint32_t aging : 4;
13 /*!< queue 0 的读 / 写切换( switch )权重配置 */
14 uint32_t slaveHitSwith : 8;
15 /*!< queue 0 的读 / 写无切换( no switch )权重配置 */
16 uint32_t slaveHitNoswitch : 8;
17 } semc_queuea_weight_t;
18
19 /*! @brief SEMC AXI queue b 权重配置 */
20 typedef struct _semc_queueb_weight {
21 /*!< queue 1 的 qos 权重配置 */
22 uint32_t qos : 4;
23 /*!< queue 1 的 aging 权重配置 */
24 uint32_t aging : 4;
25 /*!< queue 1 的读 / 写切换( switch )权重配置 */
26 uint32_t slaveHitSwith : 8;
27 /*!< queue 1 的页碰撞( page hit )权重配置 */
28 uint32_t weightPagehit : 8;
29 /*!< queue 1 的 bank 翻转 (bank rotation) 权重 */
30 uint32_t bankRotation : 8;
31 } semc_queueb_weight_t;