LED Controller Design
Design Traceability
Design ID | Implements Requirement | Priority |
---|---|---|
DSN-LED-ARCH-01 | REQ-LED-1 | Mandatory |
DSN-LED-ARCH-02 | REQ-LED-2, REQ-LED-3 | Mandatory |
DSN-LED-API-01 | REQ-LED-2 | Mandatory |
DSN-LED-API-02 | REQ-LED-2, REQ-LED-4 | Mandatory |
DSN-LED-TIMING-01 | REQ-LED-1 | Mandatory |
DSN-LED-DATA-01 | REQ-LED-4 | Mandatory |
DSN-LED-MEM-01 | REQ-LED-3 | Mandatory |
DSN-LED-ERR-01 | REQ-LED-2, REQ-LED-3 | Mandatory |
DSN-SIM-LED-01 | REQ-SYS-SIM-1 | Mandatory |
Target Design Architecture
DSN-LED-ARCH-01: RMT Peripheral Hardware Abstraction Design
Addresses: REQ-LED-1
Design: ESP32 RMT (Remote Control) peripheral abstraction for WS2812 timing generation.
- RMT Channel Configuration: 80MHz resolution, configurable GPIO pin, 64-symbol memory blocks
- Encoder Configuration: Bytes encoder with precise WS2812 timing (T0H=0.4µs, T0L=0.8µs, T1H=0.8µs, T1L=0.4µs)
- Transmission Queue: 4-deep queue for overlapping operations
- Clock Source: Default ESP32 RMT clock for consistent timing
- Channel Management: Single channel allocation with proper cleanup
Validation: RMT channel created successfully, timing parameters match WS2812 datasheet, transmission completes without errors.
DSN-LED-ARCH-02: RAM Buffer Architecture Design
Addresses: REQ-LED-2, REQ-LED-3
Design: In-memory LED state buffer for performance optimization and atomic updates.
- Buffer Structure: Array of
led_color_t
structures (3 bytes per LED: R, G, B) - Dynamic Allocation:
malloc()
during initialization based on configured LED count (REQ-LED-3) - State Separation: RAM buffer independent from physical LED state until
led_show()
- Update Pattern: Modify buffer → call
led_show()
→ physical update - Memory Management: Allocation during init, deallocation during cleanup
Validation: Buffer allocates correctly for configured LED count, updates modify only buffer until show, memory freed on cleanup.
DSN-LED-API-01: Pixel-Level Control API Design
Addresses: REQ-LED-2
Design: Individual LED pixel manipulation with bounds checking and color utilities.
led_set_pixel(index, color)
: Set specific LED color with index validationled_get_pixel(index)
: Read current LED color from bufferled_clear_pixel(index)
: Turn off specific LED (set to black)- Color Structure:
led_color_t
with 8-bit RGB components - Predefined Colors: Constants for common colors (RED, GREEN, BLUE, WHITE, OFF, etc.)
- Bounds Checking: Index validation against configured LED count
Validation: Index validation prevents buffer overruns, color values stored accurately, predefined colors work correctly.
DSN-LED-API-02: Batch Operations API Design
Addresses: REQ-LED-2, REQ-LED-4
Design: Efficient batch operations for common patterns and hardware updates.
led_clear_all()
: Set all LEDs to off state in single operationled_show()
: Transmit complete buffer to hardware via RMT (enables REQ-LED-4)- Color Utilities:
led_color_rgb()
constructor,led_color_brightness()
scaling - Status Functions:
led_get_count()
,led_is_initialized()
for state queries - Atomic Updates: Buffer modifications independent until
led_show()
called
Validation: Clear all zeros entire buffer, show triggers RMT transmission, utilities produce correct colors.
DSN-LED-TIMING-01: WS2812 Timing Specification Design
Addresses: REQ-LED-1
Design: Precise WS2812 protocol timing using RMT encoder configuration.
- Bit 0 Encoding: High 0.4µs (32 ticks), Low 0.8µs (64 ticks)
- Bit 1 Encoding: High 0.8µs (64 ticks), Low 0.4µs (32 ticks)
- Reset Period: 50µs (4000 ticks) low signal between frames
- Clock Resolution: 80MHz RMT clock for 12.5ns tick precision
- MSB First: Most significant bit transmitted first per WS2812 protocol
Validation: Timing measurements match WS2812 datasheet specifications, LED strips respond correctly.
DSN-LED-DATA-01: Color Representation and Conversion Design
Addresses: REQ-LED-4
Design: RGB color representation with GRB hardware conversion for WS2812 compatibility.
- API Color Format: RGB (Red, Green, Blue) for user-friendly interface
- Hardware Format: GRB (Green, Red, Blue) as required by WS2812 LEDs
- Conversion Logic: Reorder RGB→GRB during
led_show()
transmission preparation - Data Buffer: Temporary allocation for GRB transmission data
- Brightness Scaling: Integer arithmetic for brightness adjustment without floating point
Validation: Color values convert correctly RGB→GRB, brightness scaling maintains color ratios, no precision loss.
DSN-LED-MEM-01: Dynamic Memory Management Design
Addresses: REQ-LED-3
Design: Controlled dynamic allocation with proper cleanup and error handling.
- Initialization Allocation: LED buffer
malloc()
based on configured count - Validation: LED count bounds (1-1000) to prevent excessive allocation
- Cleanup:
free()
buffer and reset pointers during deinitialization - Temporary Allocation: GRB data buffer during transmission (freed immediately)
- Error Recovery: Cleanup partial initialization on failure
Validation: Memory allocated correctly, no leaks after deinitialization, error paths clean up properly.
DSN-LED-ERR-01: Error Handling and Validation Design
Addresses: REQ-LED-2, REQ-LED-3
Design: Comprehensive input validation and state checking with appropriate error codes.
- State Validation: Check initialization before operations
- Bounds Checking: LED index validation against configured count (REQ-LED-3)
- Parameter Validation: Non-null config, valid LED count range
- RMT Error Handling: Propagate RMT peripheral errors to caller
- Graceful Degradation: Safe operation when not initialized (return errors, not crash)
Validation: Invalid inputs return appropriate error codes, operations fail safely, system remains stable.
Simulator Design (DSN-SIM)
DSN-SIM-LED-01: LED Controller Simulator Design
Addresses: REQ-SYS-SIM-1
Design: Provide a simulator implementation for the LED controller that exposes the full public API (led_controller.h
) while replacing RMT transmission with a rate-limited terminal visualization.
- API Compatibility: The simulator SHALL implement all public functions declared in
led_controller.h
and return the same error codes and behavior as the hardware implementation. - Buffer Semantics: Maintain the same in-memory buffer and batch
led_show()
semantics as the hardware implementation. - Visualization: Rate-limited (≈1Hz) terminal output using Unicode emoji blocks (🔴🟢🔵🟡🟣⚪⚫) to represent per-pixel color state.
- Non-intrusive: The simulator SHOULD NOT change header files, configuration, or higher-layer logic (e.g., display logic).
Validation: Simulator build compiles with CONFIG_TARGET_EMULATOR=y
, led_show()
logs appear ~1x/sec and reflect buffer state.
Example simulator led_controller_sim.c
snippet (for design guidance):
// Rate-limited output - only display ~1x per second
static uint64_t last_display_time = 0;
esp_err_t led_show(void) {
uint64_t now = esp_timer_get_time();
if (now - last_display_time < 1000000) { // 1 second = 1,000,000 us
return ESP_OK; // Suppress output, just return success
}
last_display_time = now;
// Now do the emoji output
printf("\n[LED Strip]: ");
for (int i = 0; i < led_count; i++) {
led_color_t* color = &led_buffer[i];
if (color->red > 200 && color->green < 50 && color->blue < 50) {
printf("🔴"); // Red
} else if (color->green > 200 && color->red < 50 && color->blue < 50) {
printf("🟢"); // Green
} else if (color->blue > 200 && color->red < 50 && color->green < 50) {
printf("🔵"); // Blue
} else if (color->red > 200 && color->blue > 200 && color->green < 50) {
printf("🟣"); // Magenta/Purple
} else if (color->red > 200 && color->green > 200 && color->blue < 50) {
printf("🟡"); // Yellow
} else if (color->red + color->green + color->blue > 600) {
printf("⚪"); // White/bright
} else if (color->red + color->green + color->blue > 100) {
printf("🟡"); // Dim/mixed
} else {
printf("⚫"); // Off
}
}
printf("\n");
return ESP_OK;
}