如何無痛使用片外SDRAM?
stm32 已經成功初始化了 STM32H7 上的外部 SDRAM(32MB) 如何在開發中無痛使用SDRAM 使它像普通 RAM 一樣“自然地”使用?
[todo] 重要
MMT(Memory Management Tool) of STM32CubeMx
The Memory Management Tool (MMT) displays the memory map and defines memory attributes applied in user projects opened/created in STM32CubeMX. The tool is located in the “Tools” tab. It allows the user to declare memory regions at application level (referred to as “application region” or AppReg in this document). The hardware constraints related to TrustZone?, Memory Protection Unit and the memory granularity are handled by MMT and made transparent to the user, so that the focus can be put on the memory regions at the application level. A linker file is generated according to the application regions declared and configured by the user. The MMT key features are:
- Memory map display
- Application regions management
- Linker file generation
MMT interacts with peripherals starting from the moment the user enters its interface:
- Checks their settings
- Updates other peripherals involved in memory map configuration
The peripherals are updated only when the first toggle button is ON.?
MMT updates the linker scripts only when the second toggle button is ON.?
STM32H7 FMC SDRAM 配置
嵌入式STM32上設置好外部SDRAM并不難。
// code verified OK STM32H743IIT6 -?W9825G6KH-6I - 32MB
#include "main.h"
#include "SDRAM_W9825G6KH.h" //externel sdram memory devicestatic void FMC_SDRAM_ClockInit(void);
static void FMC_SDRAM_GPIOInit(void);
void SDRAM_Init(void);/*
** 功能:FMC的SDRAM控制器初始化 + 外部SDRAM存儲設備初始化
** 配置:1. 時鐘源來自PLL2也需要適配。GPIO引腳也需要適配。
** 2. 初始化SDRAM控制器+外設時序初始化
** 注意:注意棧溢出。
*/
void SDRAM_Init(void)
{/*** 第一步:配置SDRAM控制器的時鐘源*/FMC_SDRAM_ClockInit();/*** 第二步:配置SDRAM控制器與外部存儲設備的引腳*/FMC_SDRAM_GPIOInit();/*** 第三步:FMC SDRAM 控制器初始化 -----------------------------*/FMC_SDRAM_TimingTypeDef SDRAM_Timing = {0};SDRAM_HandleTypeDef hsdram = {0};/* SDRAM device configuration */hsdram.Instance = FMC_SDRAM_DEVICE; /* SDRAM在BANK5,6 */hsdram.Init.SDBank = FMC_SDRAM_BANK1; /* 第一個SDRAM BANK */hsdram.Init.ColumnBitsNumber = FMC_SDRAM_COLUMN_BITS_NUM_9; /* 列數量 */hsdram.Init.RowBitsNumber = FMC_SDRAM_ROW_BITS_NUM_13; /* 行數量 */hsdram.Init.MemoryDataWidth = FMC_SDRAM_MEM_BUS_WIDTH_16; /* 數據寬度為16位 */ hsdram.Init.InternalBankNumber = FMC_SDRAM_INTERN_BANKS_NUM_4; /* 一共4個BANK */hsdram.Init.CASLatency = FMC_SDRAM_CAS_LATENCY_2; /* CAS延遲為2個周期 */hsdram.Init.WriteProtection = FMC_SDRAM_WRITE_PROTECTION_DISABLE; /* 失能寫保護 */hsdram.Init.SDClockPeriod = FMC_SDRAM_CLOCK_PERIOD_2; /* SDRAM時鐘=fmc_ker_ck/2=220M/2=110M=9.1ns */hsdram.Init.ReadBurst = FMC_SDRAM_RBURST_ENABLE; /* 使能突發訪問 */hsdram.Init.ReadPipeDelay = FMC_SDRAM_RPIPE_DELAY_1; /* 讀通道延遲1個fmc_ker_ck時鐘周期 *//* Timing configuration for xxxMhz as SDRAM clock frequency */SDRAM_Timing.LoadToActiveDelay = 2; /* 加載模式寄存器到激活時間的延遲為2個時鐘周期 */SDRAM_Timing.ExitSelfRefreshDelay = 8; /* 退出自刷新延遲為8個時鐘周期 */SDRAM_Timing.SelfRefreshTime = 7; /* 自刷新時間為7個時鐘周期 */SDRAM_Timing.RowCycleDelay = 7; /* 行循環延遲為7個時鐘周期 */SDRAM_Timing.WriteRecoveryTime = 2; /* 恢復延遲為2個時鐘周期 */SDRAM_Timing.RPDelay = 2; /* 行預充電延遲為2個時鐘周期 */SDRAM_Timing.RCDDelay = 2; /* 行到列延遲為2個時鐘周期 */if(HAL_SDRAM_Init(&hsdram, &SDRAM_Timing) != HAL_OK){ Error_Handler();}/* Program the SDRAM external device -----------------------** 第四步:外部 SDRAM 存儲設備的時序初始化*/__IO uint32_t tmpmrd =0;FMC_SDRAM_CommandTypeDef command;/* Step 1: Configure a clock configuration enable command */command.CommandMode = FMC_SDRAM_CMD_CLK_ENABLE;command.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1;command.AutoRefreshNumber = 1;command.ModeRegisterDefinition = 0;HAL_SDRAM_SendCommand(&hsdram, &command, SDRAM_TIMEOUT);/* Step 2: 此時最小需要500us延遲;HAL庫粒度為1ms,延遲1ms */HAL_Delay(1);/* Step 3: Configure a PALL (precharge all) command */command.CommandMode = FMC_SDRAM_CMD_PALL;command.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1;command.AutoRefreshNumber = 1;command.ModeRegisterDefinition = 0;HAL_SDRAM_SendCommand(&hsdram, &command, SDRAM_TIMEOUT);/* Step 4 : Configure a Auto-Refresh command */command.CommandMode = FMC_SDRAM_CMD_AUTOREFRESH_MODE;command.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1;command.AutoRefreshNumber = 8;command.ModeRegisterDefinition = 0;HAL_SDRAM_SendCommand(&hsdram, &command, SDRAM_TIMEOUT);/* Step 5: Program the external memory mode register */tmpmrd = (uint32_t)SDRAM_MODEREG_BURST_LENGTH_1 |SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL |SDRAM_MODEREG_CAS_LATENCY_2 |SDRAM_MODEREG_OPERATING_MODE_STANDARD |SDRAM_MODEREG_WRITEBURST_MODE_SINGLE;command.CommandMode = FMC_SDRAM_CMD_LOAD_MODE;command.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1;command.AutoRefreshNumber = 1;command.ModeRegisterDefinition = tmpmrd;HAL_SDRAM_SendCommand(&hsdram, &command, SDRAM_TIMEOUT);/* Step 6: Set the refresh rate counter */HAL_SDRAM_ProgramRefreshRate(&hsdram, REFRESH_COUNT); }/* configure PLL2->R as output at 220MHz for FMC */
static void FMC_SDRAM_ClockInit(void)
{RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_FMC;PeriphClkInitStruct.PLL2.PLL2M = 25;PeriphClkInitStruct.PLL2.PLL2N = 440;PeriphClkInitStruct.PLL2.PLL2P = 2;PeriphClkInitStruct.PLL2.PLL2Q = 2;PeriphClkInitStruct.PLL2.PLL2R = 2; //220MHz PLL2R OutputPeriphClkInitStruct.PLL2.PLL2RGE = RCC_PLL2VCIRANGE_0;PeriphClkInitStruct.PLL2.PLL2VCOSEL = RCC_PLL2VCOWIDE;PeriphClkInitStruct.FmcClockSelection = RCC_FMCCLKSOURCE_PLL2;if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK){Error_Handler();}/* Peripheral clock enable */__HAL_RCC_FMC_CLK_ENABLE();
}/*
1. 配置FMC內的SDRAM控制器對外部SDRAM存儲設備物理連接引腳
*/
static void FMC_SDRAM_GPIOInit(void)
{GPIO_InitTypeDef GPIO_InitStruct ={0};/* 1. GPIO Ports Clock Enable */;//在MX_GPIO_Init函數里實現的。/** FMC GPIO ConfigurationPF0 ------> FMC_A0PF1 ------> FMC_A1PF2 ------> FMC_A2PF3 ------> FMC_A3PF4 ------> FMC_A4PF5 ------> FMC_A5PC0 ------> FMC_SDNWEPH2 ------> FMC_SDCKE0PH3 ------> FMC_SDNE0PF11 ------> FMC_SDNRASPF12 ------> FMC_A6PF13 ------> FMC_A7PF14 ------> FMC_A8PF15 ------> FMC_A9PG0 ------> FMC_A10PG1 ------> FMC_A11PE7 ------> FMC_D4PE8 ------> FMC_D5PE9 ------> FMC_D6PE10 ------> FMC_D7PE11 ------> FMC_D8PE12 ------> FMC_D9PE13 ------> FMC_D10PE14 ------> FMC_D11PE15 ------> FMC_D12PD8 ------> FMC_D13PD9 ------> FMC_D14PD10 ------> FMC_D15PD14 ------> FMC_D0PD15 ------> FMC_D1PG2 ------> FMC_A12PG4 ------> FMC_BA0PG5 ------> FMC_BA1PG8 ------> FMC_SDCLKPD0 ------> FMC_D2PD1 ------> FMC_D3PG15 ------> FMC_SDNCASPE0 ------> FMC_NBL0PE1 ------> FMC_NBL1*/GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3|GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15;GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;GPIO_InitStruct.Pull = GPIO_NOPULL;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;GPIO_InitStruct.Alternate = GPIO_AF12_FMC;HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);GPIO_InitStruct.Pin = GPIO_PIN_0;GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;GPIO_InitStruct.Pull = GPIO_NOPULL;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;GPIO_InitStruct.Alternate = GPIO_AF12_FMC;HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);GPIO_InitStruct.Pin = GPIO_PIN_2|GPIO_PIN_3;GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;GPIO_InitStruct.Pull = GPIO_NOPULL;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;GPIO_InitStruct.Alternate = GPIO_AF12_FMC;HAL_GPIO_Init(GPIOH, &GPIO_InitStruct);GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_8|GPIO_PIN_15;GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;GPIO_InitStruct.Pull = GPIO_NOPULL;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;GPIO_InitStruct.Alternate = GPIO_AF12_FMC;HAL_GPIO_Init(GPIOG, &GPIO_InitStruct);GPIO_InitStruct.Pin = GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15|GPIO_PIN_0|GPIO_PIN_1;GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;GPIO_InitStruct.Pull = GPIO_NOPULL;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;GPIO_InitStruct.Alternate = GPIO_AF12_FMC;HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_14|GPIO_PIN_15|GPIO_PIN_0|GPIO_PIN_1;GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;GPIO_InitStruct.Pull = GPIO_NOPULL;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;GPIO_InitStruct.Alternate = GPIO_AF12_FMC;HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);}
Flexible memory controller (FMC)
stm32h743iit6 RM0433
The flexible memory controller (FMC) includes three memory controllers:
-
The NOR/PSRAM memory controller
-
The NAND memory controller
-
The Synchronous DRAM (SDRAM/Mobile LPSDR SDRAM) controller
The FMC functional block makes the interface with: synchronous and asynchronous static memories, SDRAM memories, and NAND flash memory. Its main purposes are: ? to translate AXI transactions into the appropriate external device protocol ? to meet the access time requirements of the external memory devices
關于靜態存儲器、動態存儲器、Nand Flash
所有外部存儲器都與FMC控制器共享地址、數據和控制信號。 每個外部設備都通過唯一的片選信號進行訪問。FMC 每次只能對一個外部設備執行一次訪問。
FMC 的主要特性如下:
? 與靜態存儲器映射設備接口,包括: – 靜態隨機存取存儲器 (SRAM) – NOR 閃存/OneNAND 閃存 – PSRAM(4 個存儲體) – 帶有 ECC 硬件的 NAND 閃存,可校驗高達 8 KB 的數據 ? 與同步 DRAM(SDRAM/Mobile LPSDR SDRAM)存儲器接口 ? 支持突發模式,可更快地訪問同步設備,例如 NOR 閃存、PSRAM 和 SDRAM ? 可編程連續時鐘輸出,用于異步和同步訪問 ? 8、16 或 32 位寬數據總線 ? 每個存儲體均具有獨立的片選控制 ? 每個存儲體均具有獨立的配置 ? 寫使能和字節通道選擇輸出,可用于 PSRAM、SRAM 和 SDRAM 設備 ? 外部異步等待控制 ? 16 x 32 位深度的寫 FIFO 寫 FIFO 適用于所有存儲器控制器,包括: – 寫數據 FIFO,存儲待寫入存儲器的數據 – 寫地址 FIFO,用于存儲地址(最多 28 位)加上數據大小(最多 2 位)。在突發模式下工作時,僅存儲起始地址, 除非跨越頁邊界(對于 PSRAM 和 SDRAM)。在這種情況下,突發會被拆分成兩個 FIFO 條目。 ? 為 SDRAM 控制器提供 6 x64 位深度(6 x14 位地址標記)的可緩存讀取 FIFO。
啟動時,FMC 引腳必須由用戶應用程序配置。應用程序未使用的 FMC I/O 引腳可用于其他用途。更詳細地講,
在系統啟動時就需要根據外部設備類型和相關特性設置好FMC寄存器參數,并且直到系統再次復位或上電前不能再次修改FMC絕大多數的寄存器參數,除了極少部分on-the-fly特性的FMC寄存器比特位可以被再次修改,他們是:
-
FMC_PCR 寄存器中的 ECCEN 和 PBKEN 位
-
FMC_SR 寄存器中的 IFS、IRS 和 ILS 位
-
FMC_SDCMR 寄存器中的 MODE[2:0]、CTB1/CTB2、NRFS 和 MRD 位
-
FMC_SDRTR 寄存器中的 REIE 和 CRE 位。
當FMC使能時,需要按照如下流程去修改FMC的參數:
-
首先禁用 FMC,以防止在修改寄存器期間進一步訪問任何內存控制器。
-
更新所有必需的配置。
-
再次啟用 FMC。
使用 SDRAM 控制器時,如果在初始化階段后需要修改 SDCLK 時鐘比或刷新率,則必須遵循以下步驟。
-
將 SDRAM 設備置于自刷新模式。
-
通過復位 FMC_BCR1 寄存器中的 FMCEN 位來禁用 FMC。
-
更新所需參數。
-
一旦所有參數更新完成后,立即啟用 FMC。
-
最后,發送“時鐘配置啟用”命令退出自刷新模式。
FMC 內部模塊分析
FMC由以下幾個內部硬件電路模塊組成:
-
NOR Flash/PSRAM/SRAM 控制器;
-
NAND Flash 控制器;
-
SDRAM 控制器;
-
AXI 總線接口;
-
APB 總線接口(including the FMC configuration registers);內部模塊框圖如下:
FMC 內部信號
AHB interface
內部 CPU 核心通過 AHB 從機接口訪問 FMC 寄存器。
AHB 總線時鐘為訪問 FMC 寄存器提供參考時鐘。
AXI interface
內部 CPU 核心和其他總線上的主設備通過 AXI 從機接口訪問外部存儲設備。
AXI總線上的業務數據,會被轉換成外部設備協議。由于 AXI 數據總線為 64 位寬,AXI 業務數據可能會根據訪問數據的大小被拆分成多個連續的 32 位、16 位或 8 位訪問。FMC 片選 (FMC_NEx) 不會在連續的訪問之間切換。
當以下條件被觸發后,FMC就會產生一個AXI從機錯誤:
-
讀取或寫入未啟用的 FMC 存儲區(存儲區 1 至 4)。
-
在 FMC_BCRx 寄存器中的 FACCEN 位復位時讀取或寫入 NOR 閃存存儲區。
-
寫入具有寫保護的 SDRAM 存儲區(FMC_SDCRx 寄存器中的 WP 位被置位)。
-
超出 SDRAM 地址范圍(訪問保留地址范圍)。
-
在 SDRAM 存儲區尚未初始化時嘗試對其進行讀/寫訪問。
當 BMAP[1:0] 配置的 FMC bank 基地址不支持 ADDR[31:28] 里的地址,FMC 便會產生一個 AXI 解碼錯誤。
The kernel clock for the FMC is the asynchronous fmc_ker_ck clock (refer to Section 8: Reset and Clock Control (RCC) for fmc_ker_ck clock source selection).
AXI支持的存儲和業務類型
通用規則
AXI總線上的請求業務數據尺寸可以是8/16/32/64位,然而接收訪問的外部存儲設備必須具有固定的數據寬度。
單詞學習:whereas :compared with the fact that; but: 意思是:即使前面描述的是客觀事實,但是xxxx
比如,You eat a huge plate of food for lunch, whereas I have just a sandwich. 你已然吃了很多午餐了,但我僅僅吃了一個三明治。
只有當AXI業務數據寬度與外部設備數據寬度一致時,才能發揮AXI總線數據傳輸的最大性能。
當AXI業務數據寬度與外部設備的數據寬度不一致時:
-
AXI業務數據寬度大于設備數據寬度時,
-
讀寫業務:FMC會將AXI業務數據寬度分割成較小的連續訪問,以符合外部設備數據寬度。
-
-
AXI業務數據寬度小于外部設備數據寬度且外部設備(SRAM, PSRAM, SDRAM)支持字節選擇時,
-
寫業務:FMC 使用字節通道信號管理事務。
-
讀業務:FMC 根據外部設備的數據寬度返回所有字節。無用的字節將被系統丟棄。
-
-
AXI業務數據寬度小于外部設備數據寬度且外部設備 (NOR and NAND flash memories)不支持字節選擇時,
-
寫業務:FMC 寫入一些不相關的字節,可能會損壞外部設備。
-
讀業務:FMC 根據外部設備的數據寬度返回所有字節。無用的字節將被系統丟棄。
-
注意:地址對齊
-
FMC 不支持地址未對齊的讀取業務請求(例如,從奇數地址開始的半字)。
-
FMC 會根據外部設備是否支持字節選擇特性來決定是否支持地址未對齊的寫入事務。 如果外部設備不支持字節選擇(NOR 和 NAND 閃存)特性,則FMC將不會支持窄寫入事務和/或未對齊的寫入事務,因為 FMC 會寫入不相關的字節并損壞外部設備。
對 NOR 閃存/PSRAM 和 SDRAM 的封裝支持
同步存儲器必須配置為未定義長度的線性突發模式,因為并非所有主設備都能支持數據經過封裝的業務。 如果主設備生成封裝事務: ? 讀取操作將被拆分為兩個線性突發事務。 ? 如果啟用了寫入 FIFO,則寫入操作將被拆分為兩個線性突發事務;如果禁用了寫入 FIFO,則寫入操作將被拆分為多個線性突發事務。
外部設備地址的映射
從FMC的視角去看,外部存儲設備被劃分為數個256M字節大小的塊區(bank)。
Bank1: NOR/PSRAM/SRAM,(4x64MB)可用于高達4個外部 NOR flash 或者 PSRAM 存儲設備。此區塊1被劃分為4個 NOR/PSRAM 子存儲區塊,且支持子區塊片選特性:
– Bank 1 - NOR/PSRAM 1 – Bank 1 - NOR/PSRAM 2 – Bank 1 - NOR/PSRAM 3 – Bank 1 - NOR/PSRAM 4
Bank2: SDRAM Bank1,(4x64MB)供外部 SDRAM 存儲設備使用。SDRAM bank 1 or SDRAM bank 2 depending on BMAP bits configuration。
Bank3: NAND Flash, (4x64MB)用于外部 NAND flash 設備尋址。此區塊的MPU存儲屬性必須配置成 software to Device。
Bank4: Not used ,(4x64MB)保留,FMC無法使用。
Bank5: SDRAM Bank1: (4x64MB) 用于 SDRAM 設備尋址(一個設備獨占一個bank)。
Bank6: SDRAM Bank2: (4x64MB) 用于 SDRAM 設備尋址(一個設備獨占一個bank)。
可以通過 FMC_BCR1 寄存器中的 BMAP[1:0] 位修改 FMC 存儲體映射。表 154 顯示了將 NOR/PSRAM 存儲體與 SDRAM 存儲體交換或重新映射 SDRAM 存儲體 2 的配置,從而允許以兩個不同的地址映射訪問 SDRAM 存儲體。
習慣上,稱一級bank為FMC bank + 數字標號,稱二級bank為外部設備bank + 數字標號.
NOR/PSRAM 地址映射
[todo]
NAND flash 地址映射
[todo]
SDRAM 地址映射
[todo]
NOR flash/PSRAM 控制器
[todo]
NAND flash 控制器
[todo]
SDRAM 控制器
SDRAM 控制器主要特性
SDRAM 控制器支持如下主要特性:
-
支持兩個可獨立配置 SDRAM banks;
-
支持 8/16/32 數據總線寬度;
-
13位數行地址,11位數列地址,4個內部子banks: 4x16Mx32bit (256 MB), 4x16Mx16bit (128 MB), 4x16Mx8bit (64 MB);
-
支持以字、半字、字節形式訪問;
-
SDRAM時鐘可以是 fmc_ker_ck/2 or fmc_ker_ck/3;
-
行和bank邊界的自動化管理;
-
banks之間的來回往復訪問;
-
可編程的時序參數;
-
支持可編程刷新率的自動刷新操作;
-
自我刷新模式;
-
掉電模式;
-
通過軟件方式上電初始化SDRAM;
-
列地址選通延遲等級配置:等級1,等級2,等級3;
-
可緩存的讀 FIFO,深度為 6 行 x32 位(6 x14 位地址標簽);
CAS(Column Address Strobe)Latency(列地址選通延遲)是 SDRAM 的核心時序參數,在 STM32H743 的 FMC SDRAM 控制器中,它決定了從發出讀命令到數據輸出的延遲時鐘周期數。
SDRAM 外部存儲接口信號
最開始,必須配置那些規劃被 "FMC SDRAM控制器"用來與“外部SDRAM存儲設備”通信的 ”SDRAM 引腳” ,那些余下的 SDRAM 引腳可以另做他用。
SDRAM 控制器功能描述
SDRAM控制器所有的輸出(信號、地址、數據)都是在存儲時鐘(FMC_SDCLK)的下降沿做出改變。
初始化 SDRAM
SDRAM的初始化序列有軟件負責管理。如果使用兩個存儲槽(banks),那么必須通過設置 FMC_SDCMR 寄存器里的命中存儲槽Bank1/Bank2的對應的 CTB1 和 CTB2 位同時向Bank1和Bank2發出SDRAM的啟動序列。
-
將外部存儲設備的特性寫入到 FMC_SDCRx 寄存器內。 SDRAM 時鐘頻率、RBURST 和 RPIPE 是必須要寫入到 FMC_SDCR1 寄存器內的。
-
將外部存儲設備的時序特性寫入到 FMC_SDTRx 寄存器內。TRP和TRC時序參數必須寫入到 FMC_SDTR1 寄存器內。
-
設置 FMC_SDCMR 寄存器內的 MODE 位為 ‘001’ ,并配置其中的命中的bank位 Target Bank bits (CTB1 and/or CTB2),便開始向外部存儲設備輸送時鐘信號(SDCKE被驅動為高)。
-
等待"規定"的延遲時間。典型延遲時間約為 100 μs(有關上電后所需的延遲時間,請參閱 SDRAM 數據手冊)。
-
將 FMC_SDCMR 寄存器內的模式位設置為 ‘010’ 且配置好目標存儲槽對應的比特位(CTB1 and/or CTB2),發出“預充所有”的命令。
-
將 MODE 位設置為“011”,并配置目標存儲區位(CTB1 和/或 CTB2)以及 FMC_SDCMR 寄存器中的連續自動刷新命令 (NRFS) 數量。有關應發出的自動刷新命令數量,請參閱 SDRAM 數據手冊。典型數量為 8。
-
配置 MRD 字段,將 MODE 位設置為“100”,并配置 FMC_SDCMR 寄存器中的目標存儲區位(CTB1 和/或 CTB2),以發出“加載模式寄存器”命令并對 SDRAM 設備進行編程。具體來說,必須將突發長度 (BL) 設置為“1”,并選擇 CAS 延遲。如果兩個 SDRAM 存儲區的模式寄存器不同,則必須重復此步驟兩次,每個存儲區各一次,并相應地設置目標存儲區位。對于移動 SDRAM 設備,MRD 字段還用于在發出“加載模式寄存器”命令時配置擴展模式寄存器。
-
把刷新速率寫入 FMC_SDRTR 寄存器內。 刷新率對應于刷新周期之間的延遲。其值必須正確適配外部的 SDRAM 存儲設備。
此時,SDRAM 設備已準備好接受命令。如果在 SDRAM 接收訪問期間發生系統復位,數據總線可能仍由 SDRAM 設備驅動。因此,在 NOR 閃存/PSRAM/SRAM 或 NAND 閃存控制器發出任何新的訪問之前,必須先復位緊接著重新初始化 SDRAM 設備。
注意:If two SDRAM devices are connected to the FMC, all the accesses performed at the same time to both devices by the Command Mode register (Load Mode Register command) are issued using the timing parameters configured for SDRAM Bank 1 (TMRD andTRAS timings) in the FMC_SDTR1 register. 如果 FMC 連接了兩個 SDRAM 外部存儲設備,那么使用命令模式寄存器同時對兩個外部存儲設備執行的所有訪問,將都使用 FMC_SDTR1 寄存器內為SDRAM Bank 1配置的 TMRD andTRAS timings 位設定的時序發出。
SDRAM 控制器的寫周期
SDRAM 控制器接受單次和突發寫入請求,并將其轉換為單次內存訪問。在這兩種情況下,SDRAM 控制器都會跟蹤每個存儲體的活動行,以便能夠對不同的存儲體執行連續的寫入訪問(多存儲體乒乓訪問)。
在執行任何寫訪問之前,必須通過清除 FMC_SDCRx 寄存器中的 WP 位來失能 SDRAM 的 Bank 寫保護。
SDRAM 控制器始終檢查下一次訪問。 ? 如果下一次訪問位于同一行或另一個活動行,則執行寫入操作; ? 如果下一次訪問的目標是另一行(非活動行),則 SDRAM 控制器生成預充電命令,激活新行并發起寫入命令。
SDRAM 控制器的讀周期
SDRAM 控制器接受單次和突發讀取請求,并將其轉換為單次內存訪問。在這兩種情況下,SDRAM 控制器都會跟蹤每個存儲體中的活動行,以便能夠在不同的存儲體中執行連續的讀取訪問(多存儲體乒乓訪問)。