RT600 BootROM RM解析 (6)

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。

image-20250520161048274

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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
typedef struct _serial_nor_config_option {  
union {
struct {
uint32_t misc_mode : 4; //!< 杂项模式
uint32_t quad_mode_setting : 4; //!< 四线模式设置
uint32_t cmd_pads : 4; //!< 命令引脚数
uint32_t query_pads : 4; //!< SFDP读取引脚数
uint32_t max_freq : 4; //!< 最大支持频率
uint32_t device_type : 4; //!< 设备类型
uint32_t option_size : 4; //!< 选项大小(以uint32_t为单位,大小=(option_size + 1))
uint32_t tag : 4; //!< 标签,必须为0x0C
} B;
uint32_t U;
} option0;
uint32_t dummy_cycles:8;
union {
struct {
uint32_t status_override : 8; //!< 设备模式配置期间覆盖状态寄存器值
uint32_t dummy_cycles : 8; //!< 读取前的哑周期数
uint32_t pinmux_group : 4; //!< 引脚复用组选择
uint32_t dqs_pinmux_group : 4; //!< DQS引脚复用组选择
uint32_t drive_strength : 4; //!< FlexSPI引脚驱动强度
uint32_t flash_connection : 4; //!< 闪存连接选项:0-单闪存连接到端口A,1-并行模式,2-单闪存连接到端口B
} B;
uint32_t U;
} option1;
} serial_nor_config_option_t;

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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
typedef enum _FlexSPIOperationType {  
kFlexSpiOperation_Command, //!< FlexSPI操作:仅命令,忽略TX和RX缓冲区
kFlexSpiOperation_Config, //!< FlexSPI操作:配置设备模式,TX FIFO大小在LUT中固定
kFlexSpiOperation_Write, //!< FlexSPI操作:写,仅TX缓冲区有效
kFlexSpiOperation_Read, //!< FlexSPI操作:读,仅RX缓冲区有效
kFlexSpiOperation_End = kFlexSpiOperation_Read,
} flexspi_operation_t;

//!@brief FlexSPI传输上下文
typedef struct _FlexSpiXfer {
flexspi_operation_t operation; //!< FlexSPI操作类型
uint32_t baseAddress; //!< FlexSPI操作基地址
uint32_t segId; //!< 段ID
uint32_t seqId; //!< 序列ID
uint32_t seqNum; //!< 序列编号
bool isParallelModeEnable; //!< 是否启用并行传输
uint32_t *txBuffer; //!< TX缓冲区
uint32_t txSize; //!< TX大小(字节)
uint32_t *rxBuffer; //!< RX缓冲区
uint32_t rxSize; //!< RX大小(字节)
} flexspi_xfer_t;
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 读取虚拟探测失败
作者

Gavin

发布于

2025-05-20

更新于

2025-05-20

许可协议

CC BY-NC-SA 4.0

Your browser is out-of-date!

Update your browser to view this website correctly.&npsb;Update my browser now

×