Back
Loading views...QSPI
QSPI (Quad SPI) Protocol
Overview
QSPI (Quad SPI) is an extended version of SPI that uses 4 bidirectional data lines (IO0–IO3) instead of one, effectively quadrupling the data throughput. It is primarily used for interfacing with NOR flash memories (W25Qxxx, MX25Lxxx) requiring high-speed execution-in-place (XIP) or fast firmware updates.
1. Theory & Fundamentals
- Extends standard SPI with 2 (Dual SPI) or 4 (Quad SPI) data lines
- Modes: Standard (1-1-1), Dual (1-1-2 or 1-2-2), Quad (1-1-4 or 1-4-4), QPI (4-4-4)
- Notation 1-4-4: command on 1 line, address on 4 lines, data on 4 lines
- Speeds: Up to 133 MHz (DDR quad = 266 MB/s effective)
- Memory-mapped (XIP): MCU can execute code directly from QSPI flash
- Physical: SCLK, CS#, IO0 (MOSI), IO1 (MISO), IO2 (WP#), IO3 (HOLD#)
2. Frame / Packet Structure
Standard Fast Read (0x0B): CMD(1) | ADDR(3) | DUMMY(1) | DATA(n)
Quad Fast Read (0xEB): CMD(1) | ADDR(4-wire) | DUMMY(2) | DATA(4-wire, n)
QPI Read (4-4-4): CMD(4-wire) | ADDR(4-wire) | DUMMY | DATA(4-wire)
- Dummy cycles: Required between address and data for timing (device-specific)
- DDR (Double Data Rate): Sample on both clock edges
3. Protocol Mechanics
- CS# active LOW initiates transaction
- Direction: In Quad mode, all 4 IO lines are bidirectional — direction controlled by command type
- Write Enable: WEL bit must be set before program/erase
- Status Register: Poll WIP (Write In Progress) bit after write/erase
- Sector erase: Typically 4KB blocks, takes 50–400ms
- Page program: 256 bytes max per transaction
4. Hardware Implementation
- STM32 QUADSPI peripheral: Dedicated hardware on F4, F7, H7 families
- NOR Flash: W25Q128 (16MB), MX25L25635 (32MB), IS25LP128 (16MB)
- PCB: Match trace lengths for IO0–IO3, SCLK; use ground plane; decouple 100nF at VCC
- Voltage: 3.3V, some devices support 1.8V
- Pull-ups on IO2/IO3: Needed if not in quad mode (WP# and HOLD# must be driven HIGH)
5. Register-Level / Configuration
// STM32 QUADSPI initialization
QUADSPI->CR = (0x1 << QUADSPI_CR_PRESCALER_Pos) // QSPI clock = AHB/2
| QUADSPI_CR_SSHIFT // Sample shift
| QUADSPI_CR_EN; // Enable
QUADSPI->DCR = (23 << QUADSPI_DCR_FSIZE_Pos) // Flash size = 2^(23+1) = 16MB
| (1 << QUADSPI_DCR_CSHT_Pos); // CS high time
// Quad Fast Read command setup
void QSPI_ReadQuad(uint32_t addr, uint8_t *buf, uint32_t len) {
QUADSPI->CCR = 0xEB // Quad Fast Read command
| (3 << QUADSPI_CCR_ADSIZE_Pos) // 24-bit address
| (3 << QUADSPI_CCR_ADMODE_Pos) // Quad address
| (3 << QUADSPI_CCR_DMODE_Pos) // Quad data
| (6 << QUADSPI_CCR_DCYC_Pos) // 6 dummy cycles
| (1 << QUADSPI_CCR_IMODE_Pos); // Single-line instruction
QUADSPI->AR = addr;
QUADSPI->DLR = len - 1;
// Read DRs in loop or use DMA
}
6. Driver / Software Development
// Enable QSPI memory-mapped (XIP) mode
void QSPI_MemoryMapped(void) {
QUADSPI->CCR = 0xEB // Quad Fast Read
| QUADSPI_CCR_FMODE // Memory-mapped mode = 11
| ...;
// Now MCU can read from 0x90000000 directly
uint8_t *flash = (uint8_t *)0x90000000;
uint8_t byte = flash[0x1000]; // Read byte from flash offset 4096
}
// Write page (256 bytes)
void QSPI_PageProgram(uint32_t addr, uint8_t *data) {
QSPI_WriteEnable();
// Issue Page Program command (0x32 or 0x02)
// Poll WIP bit until complete
}
7. Debugging & Testing
- Logic analyzer with QSPI mode (check IO0–IO3 simultaneously)
- Verify dummy cycle count matches flash datasheet exactly
- Common issues: Quad mode not enabled in flash status register; wrong dummy cycles → wrong data
- Start with 1-1-1 mode first, then enable quad progressively
- Check IO2/IO3 driven correctly (not floating as WP#/HOLD#)
8. Real-World Applications
- Store firmware in external QSPI NOR flash, execute in-place
- Large asset storage: Fonts, graphics, audio for embedded GUI
- Firmware OTA updates: Write new firmware to QSPI, swap at next boot
- Configuration storage: Large parameter sets in NOR flash
- Code execution from 16/32MB external flash on memory-constrained MCUs
9. Advanced Topics & Edge Cases
- XIP with instruction cache: Use I-cache to avoid repeated flash reads
- QPI mode: All phases (command, address, data) on 4 lines
- DDR mode: Sample on both rising and falling edges of SCLK
- Flash locking: Hardware/software write protection registers
- Multi-bank QSPI: STM32H7 supports two QSPI banks
10. Standards & Variants
| Mode | Lines | Throughput (100MHz) |
|---|---|---|
| SPI | 1 | 12.5 MB/s |
| Dual SPI | 2 | 25 MB/s |
| Quad SPI | 4 | 50 MB/s |
| DDR Quad | 4 | 100 MB/s |
💡 Practical Examples
Example 1: Read flash JEDEC ID
CS_Low(); SPI_Send(0x9F);
uint8_t mfr=SPI_Send(0), type=SPI_Send(0), cap=SPI_Send(0);
CS_High(); // W25Q128: EF 40 18
Example 2: Erase and write sector
QSPI_SectorErase(0x000000); // Erase sector 0
QSPI_PageProgram(0x000000, data); // Write 256 bytes
QSPI_WaitNotBusy(); // Poll WIP bit
Example 3: Memory-mapped execution
// Link .rodata section to QSPI memory map (0x90000000+)
// Cortex-M accesses it transparently via AHB bus
const uint8_t logo[] __attribute__((section(".qspi_data"))) = {...};
🧪 Practice Questions
Beginner
- How many data lines does Quad SPI use compared to standard SPI?
- What is XIP (Execute In Place)?
- What is the purpose of dummy cycles in QSPI?
- What is the W25Q128 JEDEC ID?
- What does WIP bit indicate?
Intermediate
- Explain the difference between 1-1-4 and 1-4-4 QSPI modes.
- How do you enable Quad mode in a W25Q128 flash chip?
- Calculate throughput for Quad DDR SPI at 80MHz clock.
- Implement QSPI sector erase with WIP polling.
- How does memory-mapped QSPI work in STM32?
Advanced
- Implement a complete W25Q128 QSPI driver with all operations.
- Design a dual-bank OTA firmware update system using QSPI.
- Optimize QSPI for minimum latency in an RTOS environment.
- How would you implement wear leveling for QSPI NOR flash?
- Debug a QSPI data corruption issue at 80MHz.
Hands-on Projects
- QSPI File System: LittleFS on W25Q128 with read/write/delete operations.
- Firmware OTA: Download new firmware via UART, store in QSPI, boot from it.
- Graphics Asset Store: Store bitmap images in QSPI, render to LCD at full speed.
Checklist
- [ ] Explain QSPI modes (1-1-1, 1-1-4, 1-4-4, 4-4-4)
- [ ] Configure STM32 QUADSPI peripheral
- [ ] Read JEDEC ID from W25Q128
- [ ] Enable Quad mode in flash status register
- [ ] Perform sector erase and page program
- [ ] Implement memory-mapped (XIP) mode
- [ ] Use DMA for bulk transfers
- [ ] Debug with logic analyzer
- [ ] Implement complete NOR flash driver
- [ ] Build OTA update system with QSPI