docs: add SPI-based LED Strip Driver analysis documentation

This commit is contained in:
2025-11-10 10:42:07 +08:00
parent f56bc2d443
commit a47216c9b4

109
NOTE_SPI.md Normal file
View File

@ -0,0 +1,109 @@
# 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日