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

★博文内容均由个人提供,与平台无关,如有违法或侵权,请与网站管理员联系。

★博文作者未开放评论功能