FastLED 3.9.15
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_NOEXCEPT : ns(0), high(0) {}
40
42 constexpr EdgeTime(bool high_level, u32 ns_duration) FL_NOEXCEPT
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_NOEXCEPT
62 : offset(offsetParam), count(countParam) {}
63};
64
74
88 // Bit 0 timing thresholds
93
94 // Bit 1 timing thresholds
99
100 // Reset pulse threshold
102
103 // Gap tolerance (optional, for handling transmission gaps like PARLIO DMA gaps)
108};
109
146 u32 tolerance_ns = 150) FL_NOEXCEPT;
147
151enum class RxWaitResult : u8 {
155};
156
171
178 switch (type) {
179 case RxDeviceType::PLATFORM_DEFAULT: return "PLATFORM_DEFAULT";
180 case RxDeviceType::ISR: return "ISR";
181 case RxDeviceType::RMT: return "RMT";
182 case RxDeviceType::FLEXPWM: return "FLEXPWM";
183 case RxDeviceType::FLEXIO: return "FLEXIO";
184 case RxDeviceType::LPC_SCT_CAPTURE: return "LPC_SCT_CAPTURE";
185 }
186 return "UNKNOWN";
187}
188
216struct RxConfig {
217 // Hardware parameters
218 size_t buffer_size = 512;
220
221 // Signal detection parameters
223 u32 signal_range_max_ns = 100000;
224 u32 skip_signals = 0;
225 bool start_low = true;
226
227 // Internal loopback configuration (ESP32 RMT only)
228 // When true, RX receives from TX output internally (no external wire needed).
229 // IMPORTANT: For RMT TX → RMT RX loopback on ESP32-S3, both TX and RX MUST be
230 // configured on the SAME GPIO with io_loop_back=true. This is required because
231 // ESP32-S3 has a hardware limitation where RMT TX GPIO output stops when RMT RX
232 // is actively receiving on a different GPIO.
233 bool io_loop_back = false;
234
235 // DMA streaming mode (ESP32 RMT only). Non-DMA RMT RX caps a single receive
236 // at one mem-block fill (~4096 symbols, ≈170 WS2812B LEDs). DMA mode + ESP-IDF
237 // 5.3+ en_partial_rx fires the ISR multiple times per transmission — each fill
238 // copies into a DRAM accumulation buffer, extending capture to the full
239 // buffer_size. DMA bypasses on-chip RMT memory (uses DRAM), so it does NOT
240 // consume the shared RX pool and is safe to enable alongside other RMT
241 // channels. ESP32-S3 has one shared DMA slot; acquisition is coordinated via
242 // RmtMemoryManager::allocateDMA(). See issue #2254.
243 bool use_dma = false;
244
246 constexpr RxConfig() FL_NOEXCEPT = default;
247};
248
256class RxDevice {
257
258public:
259
281 template <RxDeviceType TYPE>
283
308 virtual bool begin(const RxConfig& config) FL_NOEXCEPT = 0;
309
314 virtual bool finished() const FL_NOEXCEPT = 0;
315
321 virtual RxWaitResult wait(u32 timeout_ms) FL_NOEXCEPT = 0;
322
329 virtual fl::result<u32, DecodeError> decode(const ChipsetTiming4Phase &timing,
330 fl::span<u8> out) FL_NOEXCEPT = 0;
331
360 virtual size_t getRawEdgeTimes(fl::span<EdgeTime> out, size_t offset = 0) FL_NOEXCEPT = 0;
361
366 virtual const char* name() const FL_NOEXCEPT = 0;
367
372 virtual int getPin() const FL_NOEXCEPT = 0;
373
413 virtual bool injectEdges(fl::span<const EdgeTime> edges) FL_NOEXCEPT = 0;
414
415protected:
416 // Allow shared_ptr to access protected destructor
417 friend class fl::shared_ptr<RxDevice>;
419 virtual ~RxDevice() FL_NOEXCEPT = default;
420
421private:
430};
431
432// Explicit specialization declarations — definitions live in
433// fl/channels/rx.cpp.hpp. Declaring them here prevents implicit
434// instantiation of the primary template at call sites (e.g.,
435// channel.cpp.hpp), which would otherwise collide with the explicit
436// specializations when both live in the same translation unit.
442
443} // namespace fl
virtual int getPin() const FL_NOEXCEPT=0
Get GPIO pin number.
virtual RxWaitResult wait(u32 timeout_ms) FL_NOEXCEPT=0
Wait for data with timeout.
virtual size_t getRawEdgeTimes(fl::span< EdgeTime > out, size_t offset=0) FL_NOEXCEPT=0
Get raw edge timings in universal format (for debugging)
virtual const char * name() const FL_NOEXCEPT=0
Get device type name.
virtual bool begin(const RxConfig &config) FL_NOEXCEPT=0
Initialize (or re-arm) RX channel with configuration.
static fl::shared_ptr< RxDevice > createDummy() FL_NOEXCEPT
Create dummy RxDevice instance (default fallback)
Definition rx.cpp.hpp:43
static fl::shared_ptr< RxDevice > create(int pin) FL_NOEXCEPT
Template factory method to create RX device by type.
virtual fl::result< u32, DecodeError > decode(const ChipsetTiming4Phase &timing, fl::span< u8 > out) FL_NOEXCEPT=0
Decode captured data to bytes into a span.
virtual bool injectEdges(fl::span< const EdgeTime > edges) FL_NOEXCEPT=0
Manually inject edge timings for testing (Phase 1 - PARLIO gap simulation)
virtual bool finished() const FL_NOEXCEPT=0
Check if receive operation is complete.
RxDevice() FL_NOEXCEPT=default
fl::UISlider offset("Offset", 0.0f, 0.0f, 1.0f, 0.01f)
unsigned char u8
Definition stdint.h:131
Optional< T > optional
Definition optional.h:16
@ RMT
ESP32 RMT peripheral (all ESP32 variants).
Definition bus.h:62
expected< T, E > result
Alias for expected (Rust-style naming)
Definition result.h:31
ChipsetTiming4Phase make4PhaseTiming(const ChipsetTiming &timing_3phase, u32 tolerance_ns) FL_NOEXCEPT
Create 4-phase RX timing from 3-phase chipset timing with tolerance.
Definition rx.cpp.hpp:51
constexpr nullopt_t nullopt
Definition optional.h:13
RxWaitResult
Result codes for RX wait() operations.
Definition rx.h:151
@ TIMEOUT
Operation timed out.
Definition rx.h:153
@ SUCCESS
Operation completed successfully.
Definition rx.h:152
DecodeError
Error codes for RX decoder operations.
Definition rx.h:68
@ 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:163
@ LPC_SCT_CAPTURE
SCT input-capture + DMA receiver (LPC8xx). Skeleton + decoder land in #3015; bench-verified register-...
Definition rx.h:169
@ FLEXPWM
FlexPWM input-capture receiver (Teensy 4.x)
Definition rx.h:167
@ FLEXIO
FlexIO shifter-based receiver (Teensy 4.x, FLEXIO1; see FastLED#2764)
Definition rx.h:168
@ 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:164
@ RMT
RMT-based receiver (ESP32)
Definition rx.h:166
@ ISR
GPIO ISR-based receiver (ESP32)
Definition rx.h:165
const char * toString(RxDeviceType type) FL_NOEXCEPT
Convert RxDeviceType to human-readable string.
Definition rx.h:177
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:95
u32 reset_min_us
Reset pulse minimum duration (e.g., 50us)
Definition rx.h:101
u32 gap_tolerance_ns
Maximum gap duration to tolerate (0 = no gap tolerance, treat as error)
Definition rx.h:104
u32 t0l_min_ns
Bit 0 low time minimum (e.g., 700ns)
Definition rx.h:91
u32 t1l_min_ns
Bit 1 low time minimum (e.g., 300ns)
Definition rx.h:97
u32 t1h_max_ns
Bit 1 high time maximum (e.g., 950ns)
Definition rx.h:96
u32 t0h_min_ns
Bit 0 high time minimum (e.g., 250ns)
Definition rx.h:89
u32 t0h_max_ns
Bit 0 high time maximum (e.g., 550ns)
Definition rx.h:90
u32 t1l_max_ns
Bit 1 low time maximum (e.g., 600ns)
Definition rx.h:98
u32 t0l_max_ns
Bit 0 low time maximum (e.g., 1000ns)
Definition rx.h:92
4-phase RX timing thresholds for chipset detection
Definition rx.h:87
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)
#define FL_NOEXCEPT
size_t offset
Starting edge index.
Definition rx.h:57
constexpr EdgeRange(size_t offsetParam, size_t countParam) FL_NOEXCEPT
Constructor.
Definition rx.h:61
size_t count
Number of edges to extract.
Definition rx.h:58
u32 ns
Duration in nanoseconds (31 bits, max ~2.1s)
Definition rx.h:35
constexpr EdgeTime(bool high_level, u32 ns_duration) FL_NOEXCEPT
Construct from high/low state and duration.
Definition rx.h:42
u32 high
High/low level (1 bit: 1=high, 0=low)
Definition rx.h:36
constexpr EdgeTime() FL_NOEXCEPT
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:224
u32 signal_range_min_ns
Minimum pulse width (glitch filter, default: 100ns)
Definition rx.h:222
size_t buffer_size
Buffer size in symbols/edges (default: 512)
Definition rx.h:218
bool start_low
Pin idle state: true=LOW (WS2812B), false=HIGH (inverted)
Definition rx.h:225
bool use_dma
Use DMA streaming for RX (RMT only, default: false)
Definition rx.h:243
u32 signal_range_max_ns
Maximum pulse width (idle threshold, default: 100μs)
Definition rx.h:223
fl::optional< u32 > hz
Optional clock frequency (RMT only, default: 40MHz)
Definition rx.h:219
bool io_loop_back
Enable internal RMT loopback (RMT only, default: false)
Definition rx.h:233
constexpr RxConfig() FL_NOEXCEPT=default
Default constructor with common WS2812B defaults.
Configuration for RX device initialization.
Definition rx.h:216