RT595 系列使用 FlexSPI 與外部 RAM 通訊的方式

一、概述

RT595 集成了 FlexSPI 電路,用於實現高速串行外部存儲器與主控經片之間的通信,FlexSPI代表Flexible Serial Peripheral Interface,它提供了一種靈活的方式來連接和操作外部閃存設備,例如 Flash、Hyper RAM … 等,主要用於支援各種透過 Standard SPI、Dual SPI、Quad SPI、Octal SPI 進行通訊的設備,RT595 的 FlexSPI 架構如圖 1,藉由 IO_CTL對 IO 引腳進行控制,再對應 SPI Bus port 引腳將其配置到外部 Flash 進行通訊,以 NXP MIMXRT595-EVK 為例,如圖 2 透過對應的 SPI Bus port ( FLEXSPI1 Port ) 與外部 RAM 進行通訊,本文將著重於透過 RT595 的 FlexSPI 模組對外部 RAM 的設定、擦除 / 讀寫進行解析進行解說。

圖 1 ( 註 1 )

圖 2 ( 註 2 )

二、 需求物件:

        2.1 硬體

                2.1.1 NXP RT595 EVK 詳細規格如下列網址所示

https://www.nxp.com/design/development-boards/i-mx-evaluation-and-development-boards/i-mx-rt595-evaluation-kit:MIMXRT595-EVK

                2.1.2 Type A to mini B USB Cable : 1 pcs

        2.2 軟體

                2.2.1 MCUXPRESSO ( IDE ) 軟體開發環境如下列網址所示

https://www.nxp.com/design/software/development-software/mcuxpresso-software-and-tools-/mcuxpresso-integrated-development-environment-ide:MCUXpresso-IDE

 2.2.2 NXP RT595 SDK 原廠提供的 RT595 EVK Sample Code 如下列網址所示

                       https://mcuxpresso.nxp.com/en/welcome


三、 操作方式:

3.1 開啟 evkmimxrt595_flexspi_octal_polling_transfer 的範例,並將範例燒錄到 EVK 上,NXP RT595 EVK 板上配置有燒錄功能的 IC,如圖 3 紅框

圖 3 ( 註 3 )

3.2 將 USB Cable 連結到模組板 USB Connector,USB Cable 另一端連結到PC 如圖 4

圖 4  ( 註 3 )

3.3 執行 MCUXPRESSO 並將 NXP 的 SDK 導入到 IDE 中,操作流程如圖 5、6

        3.3.1 點擊 import SDK example(s)

        3.3.2 彈出 SDK import Wizard 視窗,點選 RT595

        3.3.3 點選 Next

        3.3.4 點選 sample code evkmimxrt595_flexspi_psram_polling_transfer

        3.3.5 點選 Finish 完成 Project 建立

圖 5

圖 6

3.4 Pin define

 3.4.1 開啟 SDK 建立好的專案 evkmimxrt595_flexspi_octal_polling_transfer

        3.4.2 點選 flexspi_psram_polling_transfer.c ( 如圖 7 )

        3.4.3 查看 BOARD_InitPsRamPins 中的 Code ( 如圖 7 )

圖 7

        3.4.4 查看 BOARD_InitPsRamPins 將在分頁中開啟 pin_mux.c

        3.4.5 pin_mux.c 將會看到針對 FlexSPI 使用到的 Pin 設定

 3.4.6 宣告一變數 port4_pin11_config 將對 P4_11 ( FLEXSPI1_SCLK ) 的相關參數儲存其中,參數如下 ( 如圖 8 ):

 a ) IOPCTL_PIO_FUNC2:選擇 IOPCTL function 為 2 ( FLEXSPI1_SCLK 功能 )

        b ) IOPCTL_PIO_PULLDOWN_EN:Pullup / Pulldown 功能 Enable

        c ) IOPCTL_PIO_PUPD_DI: Pull down 設定

 d ) IOPCTL_PIO_INBUF_EN:對應 Reference Manual 建議,在 SPI 應用下開啟此功能

 e ) IOPCTL_PIO_SLEW_RATE_NORMAL:對應 Datasheet建議,在 SPI 應用下使用 Standard mode

        f ) IOPCTL_PIO_FULLDRIVE_EN:Full output drive mode

        g ) IOPCTL_PIO_ANAMUX_DI:Analog multiplexor disabled

        h ) IOPCTL_PIO_PSEDRAIN_DI:Normal push-pull output

        i ) IOPCTL_PIO_INV_DI:Input function is not inverted

3.4.7 IOCON_PinMuxSet function 中有 4 個參數需填入如下

a ) IOCON : 對應到 RT595 的 IOPCTL register address ( 0x40004000 )

b ) 4U : 對應到硬體規劃的 GPIO Port 上 ( 這邊宣告為 Port 4 )

c ) 11U : 對應到硬體規劃的 GPIO Port Pin 上 ( 這邊宣告為 Port 4 Pin 11 )

d ) port4_pin11_config : 該參數用來定義 IOPCTL register 的參數,詳細參數說明如 3.4.6 所示

                其餘 FLEXSPI1 Pin 的設定方式類似,這邊就不再敘述

圖 8

3.5 RAM init 相關設定

        3.5.1 查看 BOARD_InitPsRam 中的 Code ( 如圖 9 )

圖 9

3.5.2 宣告一變數 deviceconfig 將預計述定的參數填入其中 ( 如圖 10 ),deviceconfig 的參數如下:

.flexspiRootClk = 396000000 FLEXSPI 的時鐘頻率
.isSck2Enabled = false 不開啟 SCK 2 的時鐘功能
.flashSize = 0x2000 的大小 ( KByte )
.CSIntervalUnit = kFLEXSPI_CsIntervalUnit1SckCycle CS 的間隔單位可配置為 1 或 256 個週期
.CSInterval = 5 CS 訊號斷言間隔,通過多個 CS 間隔單位來獲取 CS 訊號斷言間隔週期
.CSHoldTime = 3 CS 訊號保持時間
.CSSetupTime = 3 CS 訊號建立時間
.dataValidTime = 1 對外部設備的數據有效時間
.columnspace = 0 列空間大小
.enableWordAddress = 0 是否使能字(4字節)地址
.AWRSeqIndex = 1 寫命令的AHB序列ID
.AWRSeqNumber = 1 AHB 寫命令的序列數目
.ARDSeqIndex = 0 讀命令序列ID
.ARDSeqNumber = 1 AHB讀命令的序列數目
.AHBWriteWaitUnit = kFLEXSPI_AhbWriteWaitUnit2AhbCycle AHB 寫等待單位
.AHBWriteWaitInterval = 0 AHB 寫等待間隔,通過多個 AHB 寫間隔單位來完成AHB寫等待週期
.enableWriteMask = true 啟用 DQS pin 作為 data 採樣的機制


圖 10

3.5.2 customLUT ( 如圖 11 ) 參數解析可參考大大通博文 “ RT595 系列使用 FlexSPI 與外部 Flash 通訊的方式 ”,如網址 ( RT595 系列使用 FlexSPI 與外部 Flash 通訊的方式 - 大大通(繁體站) (wpgdadatong.com) )

圖 11

3.5.3 Power 相關的 API ( 如圖 12 )

3.5.3.1 POWER_DisablePD(kPDRUNCFG_APD_FLEXSPI1_SRAM):Powered ON FLEXSPI1 SRAM 的 Array Power

3.5.3.2 POWER_DisablePD(kPDRUNCFG_PPD_FLEXSPI1_SRAM):Powered ON FLEXSPI1 SRAM 的 Periphery Power

3.5.3.3 POWER_ApplyPD :API to apply updated PMC PDRUNCFG bits in the Sysctl0

3.5.3.4 CLOCK_AttachClk(kAUX0_PLL_to_FLEXSPI1_CLK):將 AUX0_PLL 連接到 FLEXSPI1_CLK

3.5.3.5 CLOCK_SetClkDiv(kCLOCK_DivFlexspi1Clk, 1):Flexspi1 時鐘分頻器設定為 1

3.5.3.6 RESET_PeripheralReset(kFLEXSPI1_RST_SHIFT_RSTn) :Reset peripheral module

圖 12


3.5.4 CACHE64 的相關設定 ( 如圖 13 )

3.5.4.1 CACHE64_GetDefaultConfig(&cacheCfg):將 CACHE64 Default 參數設定到 cacheCfg 變數中

3.5.4.2 CACHE64_Init(CACHE64_POLSEL1, &cacheCfg):將 cacheCfg 的參數 init 到 CACHE64 IP 中

3.5.4.3 CACHE64_EnableWriteBuffer(CACHE64_CTRL1, true):啟用 CACHE64 Write Buffer

3.5.4.4 CACHE64_EnableCache(CACHE64_CTRL1):重啟 CACHE64

圖 13

3.5.5 FLEXSPI_GetDefaultConfig ( 如圖 14 ) 參數解析可參考大大通博文 “ RT595 系列使用 FlexSPI 與外部 Flash 通訊的方式 ”,如網址 ( RT595 系列使用 FlexSPI 與外部 Flash 通訊的方式 - 大大通(繁體站) (wpgdadatong.com) )

3.5.6 設定除 FLEXSPI_GetDefaultConfig 以外的參數 ( 如圖 14 ),說明如下:

config->ahbConfig.enableAHBPrefetch = true AHB 讀取預取使能
config->ahbConfig.enableAHBBufferable = true FlexSPI 將在所有數據傳輸到外部設備並且 AHB 命令完成後返回 AHB 總線就緒
config->ahbConfig.enableAHBCachable = true當存在 AHB 總線緩存讀取訪問時,AHB 總線可支援緩存讀訪問
ahbConfig.enableReadAddressOpt = true沒有 AHB 讀取突發起始地址對齊限制
config->ahbConfig.buffer[i].bufferSize = 256U AHB RX 緩衝區大小

* 上述 i 值為緩衝區規劃

config->ahbConfig.buffer[0].masterIndex = 11 AHB RX Buffer 根據 AHB Master 的 ID (MSTR_ID) 進行分配,內容非0即使用
config->ahbConfig.buffer[0].bufferSize = 1024 AHB RX 緩衝區大小 ( 1 KB )
config->ahbConfig.buffer[0].enablePrefetch = true AHB 讀取預取使能。
ahbConfig.buffer[0].priority = 7 AHB RX 緩衝區分配的 AHB 主讀優先級
ahbConfig.buffer[FSL_FEATURE_FLEXSPI_AHB_BUFFER_COUNT - 1].bufferSize = 1024 AHB RX 緩衝區大小 ( 1 KB )


3.5.7 將參數設定完畢後透過 FLEXSPI_Init 將 config 參數設定到 FLEXSPI1 register 中

圖 14

3.5.8 將 3.5.1 中提及的 deviceconfig 參數,透過 FLEXSPI_SetFlashConfig Function 設定到 FLEXSPI1 register 中 ( 如圖 15 )

3.5.9 將 3.5.2 中提及的 customLUT 參數,透過 FLEXSPI_UpdateLUT Function 設定到 FLEXSPI1 register 中 ( 如圖 15 )

3.5.10 透過 FLEXSPI_SoftwareReset Function 對 FLEXSPI1 IP 執行 software reset ( 如圖 15 )

圖 15

3.5.11 完成 FLEXSPI1 register 設定後即可透過 FLEXSPI1 Port 對 RAM 進行通訊,因此透過 flexspi_hyper_ram_reset 對 RAM 進行 reset ( 如圖 16 )

圖 16

3.5.12 查看 flexspi_hyper_ram_reset 中的參數與指令 ( 如圖 17 ) 並核對 RAM ( APS6408L-OBM-BA ) Datasheet ( 圖 18 ) 解析如下:

deviceAddress = 0 ,因 RAM A0 ~ A3 在 reset ( FFh ) 指令時不需參考,因此為 0
port = kFLEXSPI_PortA1,透過 RT595 的 FLEXSPI1 Port 對 RAM 進行資訊傳輸
cmdType = kFLEXSPI_Command,宣告為僅執行指令的參數,後續不做 write、read 工作
SeqNumber = 1,設定要執行的序列數目,reset 的指令數量為 1,因此設定 1 即可
seqIndex = 4,對照第 4 組 customLUT 的 RAM 參數

圖 17

圖 18 ( 註 4 )

3.5.13 後續的 flexspi_hyper_ram Function 解析方式與 3.5.12 雷同,因此後續解析將省略


3.6 BOARD_InitPsRam 設定完畢後回到 Main Code 中查看 flexspi_hyper_ram_ipcommand_write_data Function ( 如圖 19 )

3.6.1 查看 flexspi_hyper_ram_ipcommand_write_data 中的參數與指令 ( 如圖 20 ),參數解析如下:

deviceAddress = address,SDK 範例中將針對 RAM 每次寫入 1024 Byte 筆資料,並持續執行 0x800000 次 ( APS6408L-OBM-BA 的 Max Size )
port = kFLEXSPI_PortA1,透過 RT595 的 FLEXSPI1 Port 對 RAM 進行資訊傳輸
cmdType = kFLEXSPI_Write,因此這邊設定為 Write,對 RAM 進行寫入
SeqNumber = 1,設定要執行的序列數目,Write 的指令數量為 1,因此設定 1 即可
seqIndex = HYPERRAM_CMD_LUT_SEQ_IDX_WRITEDATA ( 1 ),對照第 1 組 customLUT 的 RAM 參數
data = buffer,將存放於 buffer 中的值寫入 RAM
dataSize = length,寫入的資料長度

圖 19

圖 20

3.7 flexspi_hyper_ram_ahbcommand_read_data 的解析方式與 3.6 相同,主要用來將 flexspi_hyper_ram_ipcommand_write_data Function 寫入的值讀回來,用以驗證 write、read 功能有正常執行

3.8 後續的其他 Function 的解析方式與上述解析雷同,本範例解析完畢


註 1:作者:NXP Semiconductors;出處:NXP 文件 IMXRT500RM Rev. 0.1 的 Fig.122

註 2:作者:NXP Semiconductors;出處:NXP 文件 spf-45800_d1

註 3 :作者:NXP Semiconductors;出處:NXP 文件 MIMXRT595EVKHUG User's Guide Rev. 0, 的 Fig.1

註 4:作者:AP Memory CO., LTD.;出處: AP Memory 文件 APM Octal PSRAM Datasheet.pdf - Rev. 3.7 的 8.4 Command Truth Table

★博文內容均由個人提供,與平台無關,如有違法或侵權,請與網站管理員聯繫。

★博文作者未開放評論功能