STM32H7-QUADSPI XIP及优化(WIP)
H750的128K真的不够用

简介
新款STM32的QUADSPI外设具有多种功能,配置也相当灵活,同时支持XIP功能。本文以STM32H750为例介绍STM32中的QUADSPI外设以及通过内置Flash执行位于QSPI Flash中的程序,并实现一个简易的USB DFU bootloader。
注:WIP标记未整理文档
QSPI及QSPI Flash
QSPI(Quad SPI)是在原有SPI的总线结构上增加了两条数据线(IO2,IO3),在数据传输时四条数据线按需切换数据方向,理论可实现4倍于SPI的传输速率,通常用于存储器件的连接。

QSPI Flash是NOR Flash的一种,通信接口兼容SPI,Dual SPI及Quad SPI。在3.3V下可以实现104MHz的最大时钟频率。

QSPI存储器件访问会经过以下五个阶段:
- 指令阶段(Instruction Phase)
- 地址阶段(Address Phase)
- Alternate-byte Phase
- 等待周期阶段(Dummy cycle Phase)
- 数据阶段(Data Phase)
指令阶段
该阶段主机发送8位的操作指令到Flash,用于指定将要进行的操作。根据Flash模式的不同,指令可以通过单线(IO0)发送(SPI/QSPI模式)或四线发送(QPI模式)。
地址阶段
该阶段主机发送24或32位的地址,根据命令和模式的不同,地址可能不需要发送,或通过单线、双线、四线模式发送。
Alternate-byte 阶段
QSPI Flash可通过Alternate byte设置额外参数,如连续读命令。该Alternate byte根据命令也可通过1/2/4线发送。在QPI模式下,Alternate-byte也计入dummy cycle。
等待周期阶段
该阶段用于等待Flash内部同步状态,根据Flash读写时钟的不同设置。通常来讲,在高频率下需要更多dummy cycles,同时也取决于Flash配置(命令C0H)。
数据阶段
在数据阶段中,数据从主机传输到Flash或者从Flash传输到主机,在该模式下所有IO的状态被确定,输入侧为High-Z,输出侧写入数据。IO方向的切换发生在dummy phase结束的下降沿。
一个完整的操作时序如下图所示:

STM32 QUADSPI外设
STM32H7中的QUADSPI外设位于D1域中,其位置如下

QUADSPI外设有三种工作模式,分别为
- 间接(Indirect)模式
- 状态轮询(Status-flag polling)模式
- XIP(Memory-Mapped)模式
间接模式
间接模式下QUADSPI外设操作类似于SPI外设,通过设置传输模式和寄存器收发数据,通过这种方式写入或擦除Flash后需要轮询状态寄存器判断操作完成。
状态轮询模式
该模式下,QUADSPI外设通过设置轮询命令和超时,在操作结束后由硬件自动轮询状态寄存器,通过中断指示CPU传输完成。
XIP模式
在XIP模式下,Flash的内容会被Map进地址空间,可以通过直接访问地址的方式读取Flash内容,XIP模式下Flash不可被写入。
HAL配置QSPI XIP模式
CubeMX不直接支持配置为XIP模式,需要在用户代码中配置。本文中使用的Flash型号为华邦的W25Q128FVSIG,其配置示例如下:
QSPI_CommandTypeDef sCommand;
QSPI_MemoryMappedTypeDef sMemMappedCfg;
sCommand.InstructionMode = QSPI_INSTRUCTION_1_LINE;
sCommand.AddressMode = QSPI_ADDRESS_4_LINES;
sCommand.AddressSize = QSPI_ADDRESS_24_BITS;
sCommand.DataMode = QSPI_DATA_4_LINES;
sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_4_LINES;
sCommand.AlternateBytesSize = QSPI_ALTERNATE_BYTES_8_BITS;
sCommand.AlternateBytes = 0xFF;
sCommand.DdrMode = QSPI_DDR_MODE_DISABLE;
sCommand.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY;
sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD;
sCommand.Instruction = 0xEB;
sCommand.DummyCycles = 4;
sMemMappedCfg.TimeOutActivation = QSPI_TIMEOUT_COUNTER_DISABLE;
sMemMappedCfg.TimeOutPeriod = 0;
该参数配置QUADSPI外设为四线快速读模式,会产生如下图所示的操作时序:

关键参数解释:
InstructionMode
:命令的发送方式,这里选择单线模式发送AddressMode
:地址的发送方式,该命令需要通过四线发送24bit地址AddressSize
:地址长度,24bitAlternateByteMode
:Alternate-byte的发送方式,四线方式发送Instruction
:指令字,1个字节。这里为四线快速读(0xEB)指令- 其余参数暂时保持默认即可
设置参数后,执行
HAL_QSPI_MemoryMapped(&hqspi, &sCommand, &sMemMappedCfg);
操作返回成功后,即可在总线 0x90000000
访问到QSPI Flash中的内容。
Open On-Chip Debugger
> mdw 0x90000000 128
0x90000000: 20020000 90004ccd 900006f1 900006f9 900006fb 900006fd 900006ff 00000000
0x90000020: 00000000 00000000 00000000 90004a01 90000701 00000000 90004aa1 90004b05
0x90000040: 90004d1d 90000703 90004d1d 90004d1d 9000070b 90000713 90004d1d 90004d1d
0x90000060: 90004d1d 90004d1d 90004d1d 90004d1d 90004d1d 90004d1d 90004d1d 90004d1d
0x90000080: 90004d1d 90004d1d 90004d1d 90004d1d 90004d1d 90004d1d 90004d1d 90004d1d
0x900000a0: 90004d1d 90004d1d 90004d1d 90004d1d 90004d1d 90004d1d 90004d1d 90004d1d
0x900000c0: 90004d1d 90004d1d 90004d1d 90004d1d 90004d1d 90004d1d 90004d1d 90004d1d
0x900000e0: 90004d1d 90004d1d 00000000 90004d1d 90004d1d 90004d1d 90004d1d 90004d1d
0x90000100: 90004d1d 90004d1d 90004d1d 90004d1d 90004d1d 90004d1d 90004d1d 90000715
0x90000120: 90004d1d 90004d1d 90004d1d 90004d1d 90004d1d 90004d1d 90004d1d 90004d1d
0x90000140: 00000000 00000000 00000000 00000000 90004d1d 90004d1d 90004d1d 90004d1d
0x90000160: 90004d1d 90004d1d 90004d1d 90004d1d 90004d1d 90004d1d 90004d1d 90004d1d
0x90000180: 90004d1d 90000725 90004d1d 90004d1d 90004d1d 90004d1d 90004d1d 90004d1d
0x900001a0: 90004d1d 90004d1d 90004d1d 90004d1d 90000729 90004d1d 90004d1d 90004d1d
0x900001c0: 90004d1d 90004d1d 90004d1d 90004d1d 90004d1d 90004d1d 90004d1d 90004d1d
0x900001e0: 90004d1d 90004d1d 90004d1d 90004d1d 90004d1d 90004d1d 90004d1d 90004d1d
>
USB DFU Bootloader(WIP)
修改HAL工程以XIP方式执行(WIP)
性能优化(WIP)
需注意的问题(WIP)
参考文献
[1] AXI Quad SPI v3.2 LogiCORE IP Product Guide (PG153)
[2] W25Q128FV Datasheet