STM32H7-QUADSPI XIP及优化(WIP)

H750的128K真的不够用

STM32H7-QUADSPI XIP及优化(WIP)

简介

新款STM32的QUADSPI外设具有多种功能,配置也相当灵活,同时支持XIP功能。本文以STM32H750为例介绍STM32中的QUADSPI外设以及通过内置Flash执行位于QSPI Flash中的程序,并实现一个简易的USB DFU bootloader。

注:WIP标记未整理文档


QSPI及QSPI Flash

QSPI(Quad SPI)是在原有SPI的总线结构上增加了两条数据线(IO2,IO3),在数据传输时四条数据线按需切换数据方向,理论可实现4倍于SPI的传输速率,通常用于存储器件的连接。

Quad SPI连接示例[1]

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

QSPI Flash系统框图[2]

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域中,其位置如下

STM32H7 QUADSPI外设

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;
MemoryMapped配置

该参数配置QUADSPI外设为四线快速读模式,会产生如下图所示的操作时序:

四线快速读(0xEB)命令

关键参数解释:

  • InstructionMode :命令的发送方式,这里选择单线模式发送
  • AddressMode :地址的发送方式,该命令需要通过四线发送24bit地址
  • AddressSize :地址长度,24bit
  • AlternateByteMode :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 

> 

OpenOCD读取QSPI内容

USB DFU Bootloader(WIP)

修改HAL工程以XIP方式执行(WIP)

性能优化(WIP)

需注意的问题(WIP)

参考文献

[1] AXI Quad SPI v3.2 LogiCORE IP Product Guide (PG153)

[2] W25Q128FV Datasheet