FastLED 3.10.8
Loading...
Searching...
No Matches
rx.h
Go to the documentation of this file.
1
3
4#pragma once
5
6#include "fl/stl/stdint.h"
7#include "fl/stl/optional.h"
8#include "fl/stl/result.h"
9#include "fl/stl/cstddef.h"
10#include "fl/stl/noexcept.h"
11#include "fl/stl/shared_ptr.h"
12#include "fl/stl/span.h"
13
14namespace fl {
15
16// Forward declarations
17struct ChipsetTiming;
18
34struct EdgeTime {
35 u32 ns : 31;
36 u32 high : 1;
37
39 constexpr EdgeTime() FL_NO_EXCEPT : ns(0), high(0) {}
40
42 constexpr EdgeTime(bool high_level, u32 ns_duration) FL_NO_EXCEPT
43 : ns(ns_duration), high(high_level ? 1 : 0) {}
44};
45
56struct EdgeRange {
57 size_t offset;
58 size_t count;
59
61 constexpr EdgeRange(size_t offsetParam, size_t countParam) FL_NO_EXCEPT
62 : offset(offsetParam), count(countParam) {}
63};
64
75
89 // Bit 0 timing thresholds
94
95 // Bit 1 timing thresholds
100
101 // Reset pulse threshold
103
104 // Gap tolerance (optional, for handling transmission gaps like PARLIO DMA gaps)
109};
110
147 u32 tolerance_ns = 150) FL_NO_EXCEPT;
148
152enum class RxWaitResult : u8 {
156};
157
175
182 switch (type) {
183 case RxDeviceType::PLATFORM_DEFAULT: return "PLATFORM_DEFAULT";
184 case RxDeviceType::ISR: return "ISR";
185 case RxDeviceType::RMT: return "RMT";
186 case RxDeviceType::FLEXPWM: return "FLEXPWM";
187 case RxDeviceType::FLEXIO: return "FLEXIO";
188 case RxDeviceType::LPC_SCT_CAPTURE: return "LPC_SCT_CAPTURE";
189 case RxDeviceType::I2S_RX: return "I2S_RX";
190 case RxDeviceType::PARLIO_RX: return "PARLIO_RX";
191 case RxDeviceType::PIO: return "PIO";
192 }
193 return "UNKNOWN";
194}
195
223struct RxConfig {
224 // Hardware parameters
225 size_t buffer_size = 512;
227
228 // Signal detection parameters
230 u32 signal_range_max_ns = 100000;
231 u32 skip_signals = 0;
232 bool start_low = true;
233
234 // Internal loopback configuration (ESP32 RMT only)
235 // When true, RX receives from TX output internally (no external wire needed).
236 // IMPORTANT: For RMT TX → RMT RX loopback on ESP32-S3, both TX and RX MUST be
237 // configured on the SAME GPIO with io_loop_back=true. This is required because
238 // ESP32-S3 has a hardware limitation where RMT TX GPIO output stops when RMT RX
239 // is actively receiving on a different GPIO.
240 bool io_loop_back = false;
241
242 // DMA streaming mode (ESP32 RMT only). Non-DMA RMT RX caps a single receive
243 // at one mem-block fill (~4096 symbols, ≈170 WS2812B LEDs). DMA mode + ESP-IDF
244 // 5.3+ en_partial_rx fires the ISR multiple times per transmission — each fill
245 // copies into a DRAM accumulation buffer, extending capture to the full
246 // buffer_size. DMA bypasses on-chip RMT memory (uses DRAM), so it does NOT
247 // consume the shared RX pool and is safe to enable alongside other RMT
248 // channels. ESP32-S3 has one shared DMA slot; acquisition is coordinated via
249 // RmtMemoryManager::allocateDMA(). See issue #2254.
250 bool use_dma = false;
251
252 // Streaming decode (Teensy 4.x FlexPWM). That backend decodes bits from a
253 // small DMA ring inside its ISR while the frame arrives, so it needs the
254 // decode thresholds before decode() is called. Pass the same timing you
255 // will give decode(). Unset: WS2812B defaults. Other backends ignore it.
257
260};
261
269class RxDevice {
270
271public:
272
294 template <RxDeviceType TYPE>
296
321 virtual bool begin(const RxConfig& config) FL_NO_EXCEPT = 0;
322
325 virtual const char* lastBeginError() const FL_NO_EXCEPT { return ""; }
326
331 virtual bool finished() const FL_NO_EXCEPT = 0;
332
338 virtual RxWaitResult wait(u32 timeout_ms) FL_NO_EXCEPT = 0;
339
346 virtual fl::result<u32, DecodeError> decode(const ChipsetTiming4Phase &timing,
347 fl::span<u8> out) FL_NO_EXCEPT = 0;
348
377 virtual size_t getRawEdgeTimes(fl::span<EdgeTime> out, size_t offset = 0) FL_NO_EXCEPT = 0;
378
383 virtual const char* name() const FL_NO_EXCEPT = 0;
384
389 virtual int getPin() const FL_NO_EXCEPT = 0;
390
430 virtual bool injectEdges(fl::span<const EdgeTime> edges) FL_NO_EXCEPT = 0;
431
432protected:
433 // Allow shared_ptr to access protected destructor
434 friend class fl::shared_ptr<RxDevice>;
436 virtual ~RxDevice() FL_NO_EXCEPT = default;
437
438private:
447};
448
449// Explicit specialization declarations — definitions live in
450// fl/channels/rx.cpp.hpp. Declaring them here prevents implicit
451// instantiation of the primary template at call sites (e.g.,
452// channel.cpp.hpp), which would otherwise collide with the explicit
453// specializations when both live in the same translation unit.
462
463} // namespace fl
virtual size_t getRawEdgeTimes(fl::span< EdgeTime > out, size_t offset=0) FL_NO_EXCEPT=0
Get raw edge timings in universal format (for debugging)
static fl::shared_ptr< RxDevice > create(int pin) FL_NO_EXCEPT
Template factory method to create RX device by type.
RxDevice() FL_NO_EXCEPT=default
virtual int getPin() const FL_NO_EXCEPT=0
Get GPIO pin number.
static fl::shared_ptr< RxDevice > createDummy() FL_NO_EXCEPT
Create dummy RxDevice instance (default fallback)
Definition rx.cpp.hpp:64
virtual fl::result< u32, DecodeError > decode(const ChipsetTiming4Phase &timing, fl::span< u8 > out) FL_NO_EXCEPT=0
Decode captured data to bytes into a span.
virtual bool begin(const RxConfig &config) FL_NO_EXCEPT=0
Initialize (or re-arm) RX channel with configuration.
virtual bool finished() const FL_NO_EXCEPT=0
Check if receive operation is complete.
virtual const char * name() const FL_NO_EXCEPT=0
Get device type name.
virtual bool injectEdges(fl::span< const EdgeTime > edges) FL_NO_EXCEPT=0
Manually inject edge timings for testing (Phase 1 - PARLIO gap simulation)
virtual const char * lastBeginError() const FL_NO_EXCEPT
Machine-readable reason from the most recent failed begin().
Definition rx.h:325
virtual RxWaitResult wait(u32 timeout_ms) FL_NO_EXCEPT=0
Wait for data with timeout.
fl::UISlider offset("Offset", 0.0f, 0.0f, 1.0f, 0.01f)
unsigned char u8
Definition stdint.h:131
u8 u8 fract8 blur_amount FL_NO_EXCEPT
Definition blur.h:186
ChipsetTiming4Phase make4PhaseTiming(const ChipsetTiming &timing_3phase, u32 tolerance_ns) FL_NO_EXCEPT
Create 4-phase RX timing from 3-phase chipset timing with tolerance.
Definition rx.cpp.hpp:72
Optional< T > optional
Definition optional.h:16
@ RMT
Definition bus.h:35
expected< T, E > result
Alias for expected (Rust-style naming)
Definition result.h:31
constexpr nullopt_t nullopt
Definition optional.h:13
const char * toString(RxDeviceType type) FL_NO_EXCEPT
Convert RxDeviceType to human-readable string.
Definition rx.h:181
RxWaitResult
Result codes for RX wait() operations.
Definition rx.h:152
@ TIMEOUT
Operation timed out.
Definition rx.h:154
@ SUCCESS
Operation completed successfully.
Definition rx.h:153
DecodeError
Error codes for RX decoder operations.
Definition rx.h:68
@ CAPTURE_OVERRUN
Streaming capture lost data (ring overwritten before decode)
Definition rx.h:73
@ HIGH_ERROR_RATE
Symbol decode error rate too high (>10%)
Definition rx.h:70
@ BUFFER_OVERFLOW
Output buffer overflow.
Definition rx.h:71
@ OK
No error (not typically used)
Definition rx.h:69
@ INVALID_ARGUMENT
Invalid input arguments.
Definition rx.h:72
RxDeviceType
RX device type enumeration.
Definition rx.h:164
@ I2S_RX
I2S 1-bit oversampling receiver (classic ESP32 — breaks the RMT one-shot 10-LED capture ceiling,...
Definition rx.h:173
@ LPC_SCT_CAPTURE
SCT input-capture + DMA receiver (LPC8xx). Skeleton + decoder land in #3015; bench-verified register-...
Definition rx.h:171
@ FLEXPWM
FlexPWM input-capture receiver (Teensy 4.x)
Definition rx.h:169
@ PIO
PIO receiver (RP2040/RP2350)
Definition rx.h:165
@ FLEXIO
FlexIO shifter-based receiver (Teensy 4.x, FLEXIO1; see FastLED#2764)
Definition rx.h:170
@ PLATFORM_DEFAULT
Platform default (RMT on ESP32, FLEXPWM on Teensy 4.x; FLEXIO available as opt-in on Teensy 4 — see F...
Definition rx.h:166
@ RMT
RMT-based receiver (ESP32)
Definition rx.h:168
@ ISR
GPIO ISR-based receiver (ESP32)
Definition rx.h:167
@ PARLIO_RX
PARLIO 1-bit oversampling receiver (ESP32-C6 et al — FastLED#3586)
Definition rx.h:172
Base definition for an LED controller.
Definition crgb.hpp:179
u32 t1h_min_ns
Bit 1 high time minimum (e.g., 650ns)
Definition rx.h:96
u32 reset_min_us
Reset pulse minimum duration (e.g., 50us)
Definition rx.h:102
u32 gap_tolerance_ns
Maximum gap duration to tolerate (0 = no gap tolerance, treat as error)
Definition rx.h:105
u32 t0l_min_ns
Bit 0 low time minimum (e.g., 700ns)
Definition rx.h:92
u32 t1l_min_ns
Bit 1 low time minimum (e.g., 300ns)
Definition rx.h:98
u32 t1h_max_ns
Bit 1 high time maximum (e.g., 950ns)
Definition rx.h:97
u32 t0h_min_ns
Bit 0 high time minimum (e.g., 250ns)
Definition rx.h:90
u32 t0h_max_ns
Bit 0 high time maximum (e.g., 550ns)
Definition rx.h:91
u32 t1l_max_ns
Bit 1 low time maximum (e.g., 600ns)
Definition rx.h:99
u32 t0l_max_ns
Bit 0 low time maximum (e.g., 1000ns)
Definition rx.h:93
4-phase RX timing thresholds for chipset detection
Definition rx.h:88
Generic chipset timing entry Provides T1, T2, T3 timing parameters in nanoseconds for any LED protoco...
Definition led_timing.h:86
result<T, E> type alias for fl::expected (Rust-style naming)
size_t offset
Starting edge index.
Definition rx.h:57
constexpr EdgeRange(size_t offsetParam, size_t countParam) FL_NO_EXCEPT
Constructor.
Definition rx.h:61
size_t count
Number of edges to extract.
Definition rx.h:58
constexpr EdgeTime(bool high_level, u32 ns_duration) FL_NO_EXCEPT
Construct from high/low state and duration.
Definition rx.h:42
u32 ns
Duration in nanoseconds (31 bits, max ~2.1s)
Definition rx.h:35
u32 high
High/low level (1 bit: 1=high, 0=low)
Definition rx.h:36
constexpr EdgeTime() FL_NO_EXCEPT
Default constructor (low, 0ns)
Definition rx.h:39
Universal edge timing representation (platform-agnostic)
Definition rx.h:34
u32 skip_signals
Number of signals to skip before capturing (default: 0)
Definition rx.h:231
fl::optional< ChipsetTiming4Phase > stream_timing
Definition rx.h:256
u32 signal_range_min_ns
Minimum pulse width (glitch filter, default: 100ns)
Definition rx.h:229
RxConfig() FL_NO_EXCEPT=default
Default constructor with common WS2812B defaults.
size_t buffer_size
Buffer size in symbols/edges (default: 512)
Definition rx.h:225
bool start_low
Pin idle state: true=LOW (WS2812B), false=HIGH (inverted)
Definition rx.h:232
bool use_dma
Use DMA streaming for RX (RMT only, default: false)
Definition rx.h:250
u32 signal_range_max_ns
Maximum pulse width (idle threshold, default: 100μs)
Definition rx.h:230
fl::optional< u32 > hz
Optional clock frequency (RMT only, default: 40MHz)
Definition rx.h:226
bool io_loop_back
Enable internal RMT loopback (RMT only, default: false)
Definition rx.h:240
Configuration for RX device initialization.
Definition rx.h:223