# 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日