110 lines
3.7 KiB
Markdown
110 lines
3.7 KiB
Markdown
# 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日
|