RT600 BootROM RM解析 (6)
RT600 RM CH41:RT6xx 非安全BootROM (6)
FlexSPI Driver的API详解!
41.10 FlexSPI 闪存驱动 API
41.10.1 如何阅读本节
所有器件均提供基于 ROM 的 FlexSPI 闪存驱动 API。
41.10.2 功能
- 用于识别外部串行闪存设备的 API
- 用于向外部串行闪存设备编程数据或从中读取数据的 API
- 用于部分或完全擦除外部串行闪存设备的 API
41.10.3 概述
基于 ROM 的 FlexSPI 闪存驱动 API 集包含多个独立 API,以减少在 RT6xx 器件上启用外部闪存支持的工作量。借助这些 API,支持市场上大多数串行 NOR 闪存设备,包括但不限于:
- 支持 JESD216 标准或更高版本的串行 NOR 闪存设备
- HyperFLASH 设备
- Micron Xcella Flash 设备
- Macronix OctaFlash 设备
- Adesto EcoXiP Flash 设备
注意
- HyperFLASH 是 Cypress 或 ISSI 的符合 HyperBus 标准的闪存设备。
- Xcella 是 Xcella 联盟的商标。
- OctaFlash 是 Macronix Octal Flash 的商标。
- EcoXiP 是 Adesto Octal Flash 的商标。
41.10.3.1 FlexSPI 驱动 API 位置
FlexSPI 驱动 API 的位置见图 231。

41.10.4 FlexSPI 闪存驱动 API
FlexSPI 闪存驱动 API 提供简化用户应用中闪存编程工作的功能。ROM API 的详细信息见下一节。
表 1088. FlexSPI 闪存驱动 API 列表
函数原型 | API 描述 | 章节 |
---|---|---|
status_t flexspi_nor_flash_init (uint32_t instance, flexspi_nor_config_t *config); |
初始化 FlexSPI 控制器 | 41.10.4.1 |
status_t flexspi_nor_flash_page_program (uint32_t instance, flexspi_nor_config_t *config, uint32_t dstAddr, const uint32_t *src); |
向指定闪存地址编程数据 | 41.10.4.2 |
status_t flexspi_nor_flash_erase_all (uint32_t instance, flexspi_nor_config_t *config); |
擦除整个闪存 | 41.10.4.3 |
status_t flexspi_nor_flash_erase (uint32_t instance, flexspi_nor_config_t *config, uint32_t start, uint32_t length); |
擦除指定闪存区域 | 41.10.4.4 |
表 1088. FlexSPI 闪存驱动 API 列表(续)
函数原型 | API 描述 | 章节 |
---|---|---|
status_t flexspi_nor_flash_erase_sector (uint32_t instance, flexspi_nor_config_t *config, uint32_t address); |
擦除指定闪存扇区 | 41.10.4.5 |
status_t flexspi_nor_flash_erase_block (uint32_t instance, flexspi_nor_config_t *config, uint32_t address); |
擦除指定闪存块 | 41.10.4.6 |
status_t flexspi_nor_flash_read (uint32_t instance, flexspi_nor_config_t *config, uint32_t *dst, uint32_t start, uint32_t bytes); |
从指定起始地址读取固定长度的数据 | 41.10.4.7 |
void flexspi_clock_config (uint32_t instance, uint32_t freqOption, uint32_t sampleClkMode); |
配置 FlexSPI 时钟频率和数据采样模式 | 41.10.4.8 |
status_t flexspi_nor_set_clock_source (uint32_t clockSource); |
选择 FlexSPI 时钟源 | 41.10.4.9 |
status_t flexspi_nor_get_config (uint32_t instance, flexspi_nor_config_t *config, serial_nor_config_option_t *option); |
从外部闪存获取闪存配置 | 41.10.4.10 |
status_t flexspi_command_xfer (uint32_t instance, flexspi_xfer_t *xfer) |
传输 FlexSPI 命令 | 41.10.4.11 |
status_t flexspi_update_lut (uint32_t instance, uint32_t seqIndex, const uint32_t *lutBase, uint32_t seqNumber) |
更新 FlexSPI 查找表 | 41.10.4.12 |
41.10.4.1 flexspi_nor_flash_init
此例程根据参数 0 和参数 1 中指定的参数初始化 FlexSPI 控制器。
表 1089. flexspi_nor_flash_init API
例程 | flexspi_nor_flash_init |
---|---|
原型 | status_t flexspi_nor_flash_init (uint32_t instance, flexspi_nor_config_t *config); |
输入参数 | 参数 0:FlexSPI 控制器实例,仅支持 0 参数 1:闪存配置块FCB |
结果 | 错误代码:0 = 无错误。参见表 1104 “闪存 API 的返回和错误代码”。 |
描述 | 使用参数 1 指向的参数配置 FlexSPI 控制器。 |
41.10.4.1.1 参数 0:FlexSPI 控制器实例
这是 FlexSPI 的实例号,仅支持 0。
41.10.4.1.2 参数 1:闪存配置块缓冲区
该参数指向闪存配置块 (FCB),其中包含与外部闪存设备相关的参数,例如闪存大小、页大小、扇区大小。flexspi_nor_config_t
的详细信息见 表 1001。
41.10.4.2 flexspi_nor_flash_page_program
表 1090. flexspi_nor_flash_page_program API
例程 | flexspi_nor_flash_page_program |
---|---|
原型 | status_t flexspi_nor_flash_page_program (uint32_t instance, flexspi_nor_config_t *config, uint32_t dstAddr, const uint32_t *src); |
输入参数 | 参数 0:FlexSPI 控制器实例 参数 1:闪存配置块 参数 2:要编程的目标地址 参数 3:要编程的数据。注意:该参数必须指向字对齐的地址。 |
结果 | 错误代码:0 = 无错误。参见表 1104 “闪存 API 的返回和错误代码”。 |
描述 | 向指定的目标地址编程数据 |
41.10.4.3 flexspi_nor_flash_erase_all
表 1091. flexspi_nor_flash_erase_all API
例程 | flexspi_nor_flash_erase_all |
---|---|
原型 | status_t flexspi_nor_flash_erase_all (uint32_t instance, flexspi_nor_config_t *config); |
输入参数 | 参数 0:FlexSPI 控制器实例,仅支持 0 参数 1:闪存配置块 |
结果 | 错误代码:0 = 无错误。参见表 1104 “闪存 API 的返回和错误代码”。 |
描述 | 擦除整个外部闪存 |
41.10.4.4 flexspi_nor_flash_erase
表 1092. flexspi_nor_flash_erase API
例程 | flexspi_nor_flash_erase API |
---|---|
原型 | status_t flexspi_nor_flash_erase (uint32_t instance, flexspi_nor_config_t *config, uint32_t start, uint32_t length); |
输入参数 | 参数 0:FlexSPI 控制器实例,仅支持 0 参数 1:闪存配置块 参数 2:要擦除的起始地址 参数 3:要擦除的长度 |
结果 | 错误代码:0 = 无错误。参见表 1104 “闪存 API 的返回和错误代码”。 |
描述 | 擦除指定的闪存区域 |
41.10.4.5 flexspi_nor_flash_erase_sector
表 1093. flexspi_nor_flash_erase_sector API
例程 | flexspi_nor_flash_erase_sector API |
---|---|
原型 | status_t flexspi_nor_flash_erase_sector (uint32_t instance, flexspi_nor_config_t *config, uint32_t address); |
输入参数 | 参数 0:FlexSPI 控制器实例,仅支持 0 参数 1:闪存配置块 参数 2:要擦除的扇区地址 |
结果 | 错误代码:0 = 无错误。参见表 1104 “闪存 API 的返回和错误代码”。 |
描述 | 擦除一个指定扇区 |
41.10.4.6 flexspi_nor_flash_erase_block
表 1094. flexspi_nor_flash_erase_block
例程 | flexspi_nor_flash_erase_block |
---|---|
原型 | status_t flexspi_nor_flash_erase_block (uint32_t instance, flexspi_nor_config_t *config, uint32_t address); |
输入参数 | 参数 0:FlexSPI 控制器实例,仅支持 0 参数 1:闪存配置块 参数 2:要擦除的块地址 |
结果 | 错误代码:0 = 无错误。参见表 1104 “闪存 API 的返回和错误代码”。 |
描述 | 擦除一个指定块 |
41.10.4.7 flexspi_nor_flash_read
表 1095. flexspi_nor_flash_read
例程 | flexspi_nor_flash_read |
---|---|
原型 | status_t flexspi_nor_flash_read (uint32_t instance, flexspi_nor_config_t *config, uint32_t *dst, uint32_t start, uint32_t bytes) |
输入参数 | 参数 0:FlexSPI 控制器实例,仅支持 0 参数 1:闪存配置块 参数 2:用于存储读取数据的缓冲区地址 参数 3:读取地址 参数 4:读取大小 |
结果 | 错误代码:0 = 无错误。参见表 1104 “闪存 API 的返回和错误代码”。 |
描述 | 用于从 FlexSPI NOR 闪存读取数据 |
41.10.4.8 flexspi_clock_config
表 1096. flexspi_clock_config
例程 | flexspi_clock_config |
---|---|
原型 | void flexspi_clock_config (uint32_t instance, uint32_t freqOption, uint32_t sampleClkMode) |
输入参数 | 参数 0:FlexSPI 控制器实例,仅支持 0 参数 1:FlexSPI 接口时钟频率选择 参数 2:FlexSPI 控制器数据采样模式 |
结果 | 错误代码:0 = 无错误。参见表 1104 “闪存 API 的返回和错误代码”。 |
描述 | 用于配置 FlexSPI 接口的时钟频率和数据采样模式 |
41.10.4.8.1 参数 0:FlexSPI 控制器实例
这是 FlexSPI 的实例号,仅支持 0。
41.10.4.8.2 参数 1:FlexSPI 接口时钟频率选择
用于选择 FlexSPI SPI 工作时钟,可能的选项如下:
- kFlexSpiSerialClk_30MHz = 1,
- kFlexSpiSerialClk_50MHz = 2,
- kFlexSpiSerialClk_60MHz = 3,
- kFlexSpiSerialClk_80MHz = 4,
- kFlexSpiSerialClk_100MHz = 5,
- kFlexSpiSerialClk_120MHz = 6,
- kFlexSpiSerialClk_133MHz = 7,
- kFlexSpiSerialClk_166MHz = 8,
- kFlexSpiSerialClk_200MHz = 9
41.10.4.8.3 参数 2:FlexSPI 控制器数据采样模式
用于选择 FlexSPI 接口数据采样模式,可能的选项如下:
- kFlexSpiClk_SDR, //!<单数据速率 (SDR) 模式的时钟配置
- kFlexSpiClk_DDR, //!<双倍数据速率 (DDR) 模式的时钟配置
41.10.4.9 flexspi_nor_set_clock_source
表 1097. flexspi_nor_set_clock_source
例程 | flexspi_nor_set_clock_source |
---|---|
原型 | status_t flexspi_nor_set_clock_source (uint32_t clockSource) |
输入参数 | 参数 0:FlexSPI 接口的时钟源 |
结果 | 错误代码:0 = 无错误。参见表 1104 “闪存 API 的返回和错误代码”。 |
描述 | 仅用于选择 FlexSPI 接口的时钟源,不进行其他配置 |
41.10.4.9.1 参数 0:FlexSPI 接口时钟源选择
FlexSPI 接口的时钟源选择如下:
- kFlexspiClockSrc_MainClk = 0(主时钟)、
- kFlexspiClockSrc_MainPllClk(主 PLL 时钟)、
- kFlexspiClockSrc_Aux0PllClk(辅助 0 PLL 时钟)、
- kFlexspiClockSrc_48M_Clk(48MHz 时钟)、
- kFlexspiClockSrc_Aux1PllClk(辅助 1 PLL 时钟)
41.10.4.10 flexspi_nor_get_config
表 1098. flexspi_nor_get_config
例程 | flexspi_nor_get_config |
---|---|
原型 | status_t flexspi_nor_get_config (uint32_t instance, flexspi_nor_config_t *config, serial_nor_config_option_t *option); |
输入参数 | 参数 0:FlexSPI 控制器实例,仅支持 0 参数 1:闪存配置块 参数 2:闪存配置选项块 |
结果 | 错误代码:0 = 无错误。参见表 1104 “闪存 API 的返回和错误代码”。 |
描述 | 探测闪存设备是否存在,并根据从闪存设备读取的参数生成闪存配置块。 |
41.10.4.10.1 参数 0:FlexSPI 控制器实例
这是 FlexSPI 的实例号,仅支持 0。
41.10.4.10.2 参数 1:闪存配置块
该参数指向闪存配置块 (FCB),其中包含与外部闪存设备相关的参数,例如闪存大小、页大小、扇区大小。flexspi_nor_config_t 的详细信息见表 1001。
41.10.4.10.3 参数 2:闪存配置选项块
该参数为 FlexSPI 驱动提供了一种简化选项,用于探测闪存并后续获取闪存参数。该块的定义如下:
1 | typedef struct _serial_nor_config_option { |
serial_nor_config_option_t
结构体的详细信息如下表所示。
表 1099. serial_nor_config_option_t 定义
偏移量 | 字段 | 描述 |
---|---|---|
0 | option0 | 详见 option0 定义 |
4 | option1 | 可选,仅当 option0 中的 option_size 字段非零时有效。详见 option1 定义 |
表 1100. option0 定义
字段 | 位范围 | 描述 |
---|---|---|
tag | 31:28 | 配置选项的标签,固定为 0x0C |
option_size | 27:24 | 大小(字节)=(Option Size + 1) × 4 若仅需要 option0,则为 0 |
device_type | 23:20 | 设备检测类型: 0 - 读取 SFDP 用于 SDR 命令 1 - 读取 SFDP 用于 DDR 读取命令 2 - HyperFLASH 1V8 3 - HyperFLASH 3V 4 - Macronix Octal DDR 6 - Micron Octal DDR 8 - Adesto EcoXiP DDR |
query_pads | 19:16 | 查询命令(读取 SFDP 或 MID)期间的数据引脚数: 0 - 1 引脚 1 - 2 引脚 2 - 4 引脚 3 - 8 引脚 |
cmd_pads | 15:12 | 闪存访问命令期间的命令引脚数: 0 - 1 引脚 1 - 2 引脚 2 - 4 引脚 3 - 8 引脚 |
quad_mode_setting |
11:8 | 四线模式使能设置: 0 - 未配置 1 - 在状态寄存器 1 中设置位 6 2 - 在状态寄存器 2 中设置位 1 3 - 在状态寄存器 2 中设置位 7 4 - 通过 0x31 命令在状态寄存器 2 中设置位 1 注意:该字段仅在设备符合 JESD216 标准(9 长字 SFDP 表)时有效 |
misc_mode | 7:4 | 杂项模式: 0 - 未启用 1 - 启用 0-4-4 模式以提高随机读取性能 3 - 数据顺序交换模式(仅适用于 MXIC OctaFlash) 5 - 选择 FlexSPI 数据采样源为内部环回(详见 FlexSPI 使用说明) 6 - 配置 FlexSPI NOR 闪存运行于标准 SPI 模式 注意:实验性特性,产品中请勿使用,保持为 0 |
max_freq | 3:0 | 闪存最大工作速度: 0 - 不更改 FlexSPI 时钟设置 其他值 - 参见 FlexSPI 时钟设置熔丝图 |
表 1101. option1 定义
字段 | 位范围 | 描述 |
---|---|---|
flash_connection | 31:28 | 闪存连接选项: 0 - 单闪存连接到端口 A 1 - 并行模式 2 - 单闪存连接到端口 B |
drive_strength | 27:24 | FlexSPI 引脚的驱动强度 |
dqs_pinmux_group | 23:20 | DQS 引脚复用组选择 |
pinmux_group | 19:16 | 引脚复用组选择 |
status_override | 15:8 | 设备模式配置期间覆盖状态寄存器值 |
dummy_cycles | 7:0 | 读取命令的哑周期数: 0 - 使用检测到的哑周期数 其他值 - 闪存数据表中提供的哑周期数 |
典型选项配置如下:
- 四线 NOR - 四线 SDR 读取:option0 =
0xc0000004
(80 MHz) - 四线 NOR - 四线 DDR 读取:option0 =
0xc0100003
(60 MHz) - HyperFLASH 1V8:option0 =
0xc0233004
(80 MHz) - HyperFLASH 3V0:option0 = 0xc0333004(80 MHz)
- MXIC OPI DDR(默认启用 OPI DDR):option=0xc0433004(80 MHz)
- Micron Octal DDR:option0=0xc0600004(80 MHz)
- Micron OPI DDR:option0=0xc0603004(80 MHz,SPI->OPI DDR)
- Micron OPI DDR(默认启用 DDR 读取):option0 = 0xc0633004(80 MHz)
- Adesto OPI DDR:option0=
0xc0803004
(80 MHz)
41.10.4.11 flexspi_command_xfer
表 1102. flexspi_command_xfer
例程 | flexspi_command_xfer |
---|---|
原型 | status_t flexspi_command_xfer (uint32_t instance, flexspi_xfer_t *xfer) |
输入参数 | 参数 0:FlexSPI 控制器实例,仅支持 0 参数 1:FlexSPI 传输上下文 |
结果 | 错误代码:0 = 无错误。参见表 1104 “闪存 API 的返回和错误代码”。 |
描述 | 通过 FlexSPI 接口发送在 FlexSPI 传输上下文中配置的命令。 |
41.10.4.11.1 参数 0:FlexSPI 控制器实例
这是 FlexSPI 的实例号,仅支持 0。
41.10.4.11.2 参数 1:FlexSPI 传输上下文
定义如下:
1 | typedef enum _FlexSPIOperationType { |
41.10.4.12 flexspi_update_lut
表 1093. flexspi_update_lut
例程 | flexspi_update_lut |
---|---|
原型 | status_t flexspi_update_lut (uint32_t instance, uint32_t seqIndex, const uint32_t *lutBase, uint32_t seqNumber) |
输入参数 | 参数 0:FlexSPI 控制器实例,仅支持 0 参数 1:要更新的 FlexSPI 查找表序列起始索引 参数 2:命令序列存储指针 参数 3:要更新的命令序列数量 注意:有关命令序列的信息,请参见 33.4.7 节 “查找表”。 |
结果 | 错误代码:0 = 无错误。参见表 1104 “闪存 API 的返回和错误代码”。 |
描述 | 通过 FlexSPI 接口发送在 FlexSPI 传输上下文中配置的命令。 |
41.10.4.12.1 参数 0:FlexSPI 控制器实例
这是 FlexSPI 的实例号,仅支持 0。
41.10.4.12.2 参数 1:要更新的 FlexSPI 查找表序列起始索引
- seqIndex 范围:0~15
- 参数 3 的 seqNumber 范围:0~15
- seqIndex + seqNumber 应 ≤ 16
41.10.4.12.3 参数 2:命令序列存储指针
存储要更新的命令序列的缓冲区。
41.10.4.12.4 参数 3:要更新的命令序列数量
- seqIndex 范围:0~15
- 参数 3 的 seqNumber 范围:0~15
- seqIndex + seqNumber 应 ≤ 16
41.10.4.13 闪存驱动 API 的可能返回和错误代码
表 1104. 闪存 API 的返回和错误代码
返回代码 | 错误代码 | 描述 |
---|---|---|
0 | kStatus_Success | 操作成功 |
1 | kStatus_Fail | 操作失败 |
4 | kStatus_Invalidargument | 参数 0 或参数 0 指向的 FCB 中的数据无效 |
6000 | kStatus_FLEXSPI_SequenceExecutionTimeout | FlexSPI 序列执行超时 |
6001 | kStatus_FLEXSPI_InvalidSequence | FlexSPI LUT 序列无效 |
6002 | kStatus_FLEXSPI_DeviceTimeout | FlexSPI 设备超时 |
20100 | kStatus_FLEXSPINOR_ProgramFail | 页编程失败 |
20101 | kStatus_FLEXSPINOR_EraseSectorFail | 扇区擦除失败 |
表 1104.Flash API 返回和错误代码(续)
返回代码 | 错误代码 | 描述 |
---|---|---|
20102 | kStatus_FLEXSPINOR_EraseAllFail | 芯片擦除失败 |
20103 | kStatus_FLEXSPINOR_WaitTimeout | 执行超时 |
20104 | kStatus_FlexSPINOR_NotSupported | 页面大小溢出 |
20105 | kStatus_FlexSPINOR_WriteAlignmentError | 地址对齐错误 |
20106 | kStatus_FlexSPINOR_CommandFailure | 擦除 / 编程验证错误 |
20107 | kStatus_FlexSPINOR_SFDP_NotFound | API 调用期间发生超时 |
20108 | kStatus_FLEXSPINOR_Unsupported_SFDP_Version | 不识别的 SFDP 版本 |
20109 | kStatus_FLEXSPINOR_Flash_NotFound | 闪存检测失败 |
20110 | kStatus_FLEXSPINOR_DTRRead_DummyProbeFailed | DDR 读取虚拟探测失败 |
RT600 BootROM RM解析 (6)
https://dustofstars.github.io/NXP/RT600/BootROM/rt600-bootrom-rm解析-6/