A comprehensive SPI (Serial Peripheral Interface) resource for ESP32 and Embedded Systems, blended with field experience.
"If I2C is a meeting room chat, SPI is a fire hose."
SPI is the "Speed Demon" of embedded systems. It is theoretically simple (Shift Register logic), but things change when you cross the 10 MHz barrier. Cables turn into "Transmission Lines," signals reflect, and wrong Mode selection (CPOL/CPHA) turns data into garbage.
This repo explains why codes working in the lab fail in the field and provides solutions supported by Logic Analyzer / Oscilloscope analysis.
- Physics: Push-Pull structure, why no resistors? Signal Reflection and Series Resistor usage.
- Protocol: 4 Different SPI Modes (CPOL/CPHA), Shift Register logic, and Daisy Chain.
- Integration: ESP32
SPI.h, Transaction safety, asynchronous data pushing with DMA. - Troubleshooting: Bit Shifting, Crosstalk, and Analysis.
This guide consists of 4 main technical chapters that complement each other:
"Should I install pull-up resistors? No!"
- Difference between Push-Pull vs Open-Drain.
- Naming Revolution: COPI/CIPO instead of MOSI/MISO.
- Signal Integrity: What does a 33Ω Series Resistor do?
"Why is the data shifted?"
- Shift Register and circular data exchange.
- The Mode Nightmare: CPOL and CPHA combinations (Mode 0, 1, 2, 3).
- Daisy Chain: Driving chained devices like wagons with a single CS pin.
"Driving a screen at 80 MHz without blocking the CPU."
- What are
VSPIandHSPI? Pin remapping with Pin Matrix. - Transaction: Protecting settings with
beginTransaction. - DMA (Direct Memory Access): Data transfer without tiring the CPU.
"I see spikes instead of square waves on the oscilloscope!"
- Crosstalk: What happens if cables affect each other?
- Bit Shifting: Wrong clock edge selection.
- Logic Analyzer: Catching the faulty packet.
Block diagram of a typical high-speed SPI network:
graph TD
subgraph MCU [Master Controller]
ESP32[ESP32 - SPI Driver]
DMA[DMA Controller]
end
subgraph BUS [SPI Bus - Push Pull]
SCK_LINE((SCK))
MOSI_LINE((MOSI))
MISO_LINE((MISO))
CS_LINES((CS Lines))
R_SERIES[33Ω Series Resistors]
end
subgraph SLAVES [Slave Devices]
TFT["TFT Display (Write Only)"]
SENSOR[IMU Sensor]
SD[SD Card]
end
ESP32 <--> DMA
ESP32 ==> R_SERIES ==> BUS
BUS <==> TFT & SENSOR & SD
ESP32 -.-> CS_LINES -.-> TFT & SENSOR & SD
style MCU fill:#e3f2fd,stroke:#1565c0
style BUS fill:#fff9c4,stroke:#fbc02d
style SLAVES fill:#f3e5f5,stroke:#7b1fa2
- Microcontroller: Espressif ESP32 (DevKit V1)
- IDE: VS Code + PlatformIO
- Protocol: SPI (Standard & Daisy Chain)
- Hardware: Logic Analyzer (Saleae), Oscilloscope (Rigol)
- Libraries: Arduino
SPI.h,TFT_eSPI