Files
espressif__led_strip/NOTE_SPI.md

110 lines
3.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# SPI-based LED Strip Driver Analysis
## Overview
This driver emulates RMT (Remote Control) signals for WS2812B/SK6812 LED strips using SPI peripheral. It works by encoding each data bit into multiple SPI bits to achieve the required timing characteristics.
## Clock Configuration
- **SPI Clock Frequency**: 2.5 MHz (`LED_STRIP_SPI_DEFAULT_RESOLUTION`)
- **SPI Bit Period**: 1/2.5MHz = **400 nanoseconds**
- **Tolerance**: ±300 KHz (2.2 MHz to 2.8 MHz accepted)
## Bit Encoding Scheme
Each **1 RMT data bit** is encoded as **3 SPI bits**, giving a total symbol period of 1.2 μs.
### Encoding Patterns
| Data Bit | SPI Pattern (MSB first) | High Time | Low Time | Total Time |
| -------- | ----------------------- | --------- | -------- | ---------- |
| **0** | `100` (binary) | 400 ns | 800 ns | 1200 ns |
| **1** | `110` (binary) | 800 ns | 400 ns | 1200 ns |
### WS2812B Timing Compatibility
The encoding matches WS2812B specifications:
- **T0H** (0 high time): ~400ns (spec: 350±150ns)
- **T0L** (0 low time): ~800ns (spec: 800±150ns)
- **T1H** (1 high time): ~800ns (spec: 700±150ns)
- **T1L** (1 low time): ~400ns (spec: 600±150ns)
## Why 3 Bits per Symbol?
The choice of 3 SPI bits per data bit is driven by timing requirements:
1. **Duty Cycle Ratio**: WS2812B needs approximately 1:2 or 2:1 high/low ratios
2. **Granularity**:
- 2 bits would only give 50/50 split (insufficient)
- 3 bits provides 33/66% or 66/33% ratios (optimal)
- 4+ bits would make the period too long (>1.6μs)
3. **Clock Frequency**: At 2.5 MHz, 3 bits = 1.2μs matches the ~1.25μs WS2812B bit period
## Memory Usage
Each LED color component requires:
- **1 byte** of actual data
- **3 bytes** of SPI transmission data (3:1 expansion)
For RGB LEDs:
- 3 bytes per pixel → 9 bytes SPI data per pixel
For RGBW LEDs:
- 4 bytes per pixel → 12 bytes SPI data per pixel
Defined as: `SPI_BYTES_PER_COLOR_BYTE = 3`
## Bit Mapping Function
The `__led_strip_spi_bit()` function expands each 8-bit color value into 24 SPI bits (3 bytes):
```c
static void __led_strip_spi_bit(uint8_t data, uint8_t *buf)
```
**Input**: 1 byte of color data (8 bits)
**Output**: 3 bytes written to buffer (24 SPI bits = 8 RMT symbols)
### Bit Order
The function processes bits from LSB to MSB and maps them across 3 bytes:
- Bit 0 (LSB) → buf[2] bits 2:1
- Bit 1 → buf[2] bits 5:4, plus bit 7
- Bit 2 → buf[2] bit 7, buf[1] bit 0
- Bit 3 → buf[1] bits 3:2
- Bit 4 → buf[1] bits 6:5
- Bit 5 → buf[0] bits 1:0
- Bit 6 → buf[0] bits 4:3
- Bit 7 (MSB) → buf[0] bits 7:6
Each data bit becomes a 3-bit pattern:
- `0``100` (binary)
- `1``110` (binary)
## Data Transmission
The `led_strip_spi_refresh()` function handles transmission with chunking:
1. **Total data size**: `strip_len × bytes_per_pixel × 3`
2. **Max transfer size**: Limited by SPI bus configuration (`max_transfer_sz`)
3. **Chunked transfers**: Data sent in chunks if it exceeds max transfer size
4. **Transmission mode**: `spi_device_polling_transmit()` used for blocking transfer
## Advantages of SPI Emulation
1. **No RMT peripheral needed**: Frees up RMT channels for other uses
2. **DMA support**: Can use DMA for efficient transfers
3. **Precise timing**: Hardware SPI ensures consistent bit timing
4. **Scalability**: Can drive long LED strips with proper DMA buffer sizing
## Limitations
1. **3x memory overhead**: Requires 3× the buffer space vs. RMT
2. **Fixed clock**: Requires SPI clock source with ~2.5 MHz capability
3. **No flexibility**: Cannot easily adjust timing for non-WS2812B LEDs
4. **SPI bus exclusive**: Ties up an entire SPI peripheral
## Date
Analysis performed: 2025年11月10日