src/platforms/shared/README.md
Common, platform‑agnostic components used by multiple targets (data export, UI, SPI drivers).
active_strip_data/: Zero‑copy strip data export and screenmap tracking across frames. See active_strip_data.h for ActiveStripData manager and JSON helpers.ui/: JSON‑driven UI system. ui/json/ contains JsonUiManager, components (Slider, Button, Checkbox, Dropdown, NumberField, Audio, Title, Description), and integration guide (readme.md).Shared platform code includes multi-lane SPI transposer infrastructure supporting 1/2/4/8 parallel data lanes:
NEW: Unified bit-interleaving driver for all parallel SPI widths. Transposes sequential pixel data into parallel bitstreams for simultaneous multi-strip output.
Supported Widths:
transpose2()transpose4()transpose8() ✨Key Features:
SPITransposer classtranspose2(), transpose4(), transpose8() methodsLegacy Compatibility:
spi_transposer_dual.* - Deprecated wrappers for 2-lane (calls transpose2())spi_transposer_quad.* - Deprecated wrappers for 4-lane/8-lane (calls transpose4()/transpose8())Platform-independent SPI configuration APIs organized by lane count:
Interfaces:
spi_hw_1.h - Single-lane SPI (SpiHw1)spi_hw_2.h - Dual-lane SPI (SpiHw2)spi_hw_4.h - 4-lane SPI (SpiHw4)spi_hw_8.h - 8-lane SPI (SpiHw8) ✨ NEWExample Configuration:
namespace fl {
struct SpiHw8 {
struct Config {
uint8_t data0, data1, data2, data3; // First 4 data pins
uint8_t data4, data5, data6, data7; // Next 4 data pins (8-lane)
uint8_t clock; // Shared clock pin
// ... other config
};
};
}
Configuration supports:
The transposer and interfaces are used by both:
See platform-specific READMEs for implementation details:
src/platforms/esp/32/README.md - ESP32 hardware multi-lane SPIsrc/platforms/shared/spi_bitbang/README.md - Software multi-width SPIActiveStripData listens to EngineEvents to clear and publish per‑frame data; exposes legacy and new JSON creators and parsing helpers, plus on‑demand screenmap updates.show(), the driver renders pixels. When the frame completes, EngineEvents::onEndShowLeds fires.ActiveStripData listens and clears per‑frame accumulators, then snapshots strip/screenmap data for export.EngineEvents::onEndFrame applies any pending control changes via the UI manager.Bridge stub outline:
// Pseudocode for a host bridge loop
void pump() {
if (auto json = ActiveStripData::createLegacyJson(/*alloc*/)) {
platform_send_json(json.ptr);
ActiveStripData::freeJson(json.ptr);
}
if (auto incoming = platform_recv_ui_json()) {
JsonUiManager::instance().updateUiComponents(incoming);
}
}