FastLED 3.9.15
Loading...
Searching...
No Matches
rx.cpp.hpp
Go to the documentation of this file.
1
3// ok no header (RxDevice class is declared in fl/channels/rx.h)
4
5#include "platforms/is_platform.h"
6#include "fl/channels/rx.h"
7// IWYU pragma: begin_keep
8#include "platforms/shared/rx_device_dummy.h" // ok platform headers
9// IWYU pragma: end_keep // ok platform headers
11#include "fl/stl/string.h"
12
13#ifdef FL_IS_ESP32
14// IWYU pragma: begin_keep
15#include "platforms/esp/32/drivers/rmt_rx/rmt_rx_channel.h" // ok platform headers
16#include "platforms/esp/32/drivers/gpio_isr_rx/gpio_isr_rx.h" // ok platform headers
17#endif
18// IWYU pragma: end_keep
19
20#ifdef FL_IS_TEENSY_4X
21// IWYU pragma: begin_keep
22#include "platforms/arm/teensy/teensy4_common/rx_flexio_channel.h" // ok platform headers
23#include "platforms/arm/teensy/teensy4_common/rx_flexpwm_channel.h" // ok platform headers
24// IWYU pragma: end_keep
25#endif
26
27#ifdef FL_IS_STUB
28// IWYU pragma: begin_keep
29#include "platforms/shared/rx_device_native.h" // ok platform headers
30#include "fl/stl/noexcept.h"
31// IWYU pragma: end_keep
32#endif
33
34#ifdef FL_IS_ARM_LPC
35// IWYU pragma: begin_keep
36#include "platforms/arm/lpc/rx_sct_capture.h" // ok platform headers
37// IWYU pragma: end_keep
38#endif
39
40namespace fl {
41
42// Private static helper - creates dummy device (singleton pattern)
44 static fl::shared_ptr<RxDevice> dummy = fl::make_shared<DummyRxDevice>( // okay static in header
45 "RX devices not supported on this platform"
46 );
47 return dummy;
48}
49
50// Implementation of make4PhaseTiming function
52 u32 tolerance_ns) FL_NOEXCEPT {
53 // Calculate derived values from 3-phase timing
54 // The encoder uses:
55 // Bit 0: T1 high + (T2+T3) low
56 // Bit 1: (T1+T2) high + T3 low
57 u32 t0h = timing_3phase.T1; // Bit 0 high time
58 u32 t0l = timing_3phase.T2 + timing_3phase.T3; // Bit 0 low time
59 u32 t1h = timing_3phase.T1 + timing_3phase.T2; // Bit 1 high time
60 u32 t1l = timing_3phase.T3; // Bit 1 low time
61
63
64 // Bit 0 timing thresholds
65 result.t0h_min_ns = (t0h > tolerance_ns) ? (t0h - tolerance_ns) : 0;
66 result.t0h_max_ns = t0h + tolerance_ns;
67 result.t0l_min_ns = (t0l > tolerance_ns) ? (t0l - tolerance_ns) : 0;
68 result.t0l_max_ns = t0l + tolerance_ns;
69
70 // Bit 1 timing thresholds
71 result.t1h_min_ns = (t1h > tolerance_ns) ? (t1h - tolerance_ns) : 0;
72 result.t1h_max_ns = t1h + tolerance_ns;
73 result.t1l_min_ns = (t1l > tolerance_ns) ? (t1l - tolerance_ns) : 0;
74 result.t1l_max_ns = t1l + tolerance_ns;
75
76 // Reset pulse threshold
77 result.reset_min_us = timing_3phase.RESET;
78
79 // gap_tolerance_ns retains its default value of 0
80
81 return result;
82}
83
84} // namespace fl
85
86
87
88// ESP32-specific explicit template specializations
89namespace fl {
90
91#ifdef FL_IS_ESP32
92
93// RMT device specialization for ESP32
94template <>
95fl::shared_ptr<RxDevice> RxDevice::create<RxDeviceType::RMT>(int pin) FL_NOEXCEPT {
96 auto device = RmtRxChannel::create(pin);
97 if (!device) {
98 return fl::make_shared<DummyRxDevice>("RMT RX channel creation failed");
99 }
100 return device;
101}
102
103// ISR device specialization for ESP32
104template <>
105fl::shared_ptr<RxDevice> RxDevice::create<RxDeviceType::ISR>(int pin) FL_NOEXCEPT {
106 auto device = GpioIsrRx::create(pin);
107 if (!device) {
108 return fl::make_shared<DummyRxDevice>("GPIO ISR RX creation failed");
109 }
110 return device;
111}
112
113// FLEXPWM not available on ESP32
114template <>
115fl::shared_ptr<RxDevice> RxDevice::create<RxDeviceType::FLEXPWM>(int pin) FL_NOEXCEPT {
116 (void)pin;
117 return fl::make_shared<DummyRxDevice>("FLEXPWM RX not supported on ESP32");
118}
119
120// FLEXIO not available on ESP32 (Teensy 4.x peripheral). See FastLED#2764.
121template <>
122fl::shared_ptr<RxDevice> RxDevice::create<RxDeviceType::FLEXIO>(int pin) FL_NOEXCEPT {
123 (void)pin;
124 return fl::make_shared<DummyRxDevice>("FLEXIO RX not supported on ESP32");
125}
126
127// LPC_SCT_CAPTURE not available on ESP32 (LPC8xx peripheral). See FastLED#3015.
128template <>
129fl::shared_ptr<RxDevice> RxDevice::create<RxDeviceType::LPC_SCT_CAPTURE>(int pin) FL_NOEXCEPT {
130 (void)pin;
131 return fl::make_shared<DummyRxDevice>("LPC_SCT_CAPTURE RX not supported on ESP32");
132}
133
134// DEFAULT maps to RMT on ESP32
135template <>
136fl::shared_ptr<RxDevice> RxDevice::create<RxDeviceType::PLATFORM_DEFAULT>(int pin) FL_NOEXCEPT {
138}
139
140#elif defined(FL_IS_TEENSY_4X)
141
142// FLEXPWM device specialization for Teensy 4.x
143template <>
144fl::shared_ptr<RxDevice> RxDevice::create<RxDeviceType::FLEXPWM>(int pin) FL_NOEXCEPT {
145 auto device = FlexPwmRxChannel::create(pin);
146 if (!device) {
147 return fl::make_shared<DummyRxDevice>("FlexPWM RX channel creation failed");
148 }
149 return device;
150}
151
152// FLEXIO device specialization for Teensy 4.x — Phase 1A skeleton (FastLED#2764).
153// Returns a real FlexIoRxChannel object whose methods report inactive until
154// Phase 1B lands the FLEXIO1 register programming.
155template <>
156fl::shared_ptr<RxDevice> RxDevice::create<RxDeviceType::FLEXIO>(int pin) FL_NOEXCEPT {
157 auto device = FlexIoRxChannel::create(pin);
158 if (!device) {
159 return fl::make_shared<DummyRxDevice>("FlexIO RX channel creation failed");
160 }
161 return device;
162}
163
164// RMT not available on Teensy
165template <>
166fl::shared_ptr<RxDevice> RxDevice::create<RxDeviceType::RMT>(int pin) FL_NOEXCEPT {
167 (void)pin;
168 return fl::make_shared<DummyRxDevice>("RMT RX not supported on Teensy");
169}
170
171// ISR not available on Teensy
172template <>
173fl::shared_ptr<RxDevice> RxDevice::create<RxDeviceType::ISR>(int pin) FL_NOEXCEPT {
174 (void)pin;
175 return fl::make_shared<DummyRxDevice>("ISR RX not supported on Teensy");
176}
177
178// LPC_SCT_CAPTURE not available on Teensy (LPC8xx peripheral). See FastLED#3015.
179template <>
180fl::shared_ptr<RxDevice> RxDevice::create<RxDeviceType::LPC_SCT_CAPTURE>(int pin) FL_NOEXCEPT {
181 (void)pin;
182 return fl::make_shared<DummyRxDevice>("LPC_SCT_CAPTURE RX not supported on Teensy");
183}
184
185// DEFAULT maps to FLEXPWM on Teensy 4.x (intentionally NOT switched to FLEXIO yet
186// — that ships in a separate PR after Phase 3 verification per FastLED#2764).
187template <>
188fl::shared_ptr<RxDevice> RxDevice::create<RxDeviceType::PLATFORM_DEFAULT>(int pin) FL_NOEXCEPT {
190}
191
192#elif defined(FL_IS_ARM_LPC)
193
194// LPC8xx SCT input-capture + DMA receiver. See FastLED#3015.
195template <>
196fl::shared_ptr<RxDevice> RxDevice::create<RxDeviceType::LPC_SCT_CAPTURE>(int pin) FL_NOEXCEPT {
197 auto device = LpcSctRxChannel::create(pin);
198 if (!device) {
199 return fl::make_shared<DummyRxDevice>("LPC SCT-capture RX channel creation failed");
200 }
201 return device;
202}
203
204// RMT not available on LPC
205template <>
206fl::shared_ptr<RxDevice> RxDevice::create<RxDeviceType::RMT>(int pin) FL_NOEXCEPT {
207 (void)pin;
208 return fl::make_shared<DummyRxDevice>("RMT RX not supported on LPC");
209}
210
211// ISR not available on LPC (Cortex-M0+ ISR latency cannot decode 800 kHz). See #3015.
212template <>
213fl::shared_ptr<RxDevice> RxDevice::create<RxDeviceType::ISR>(int pin) FL_NOEXCEPT {
214 (void)pin;
215 return fl::make_shared<DummyRxDevice>("ISR RX not feasible on LPC Cortex-M0+ (use LPC_SCT_CAPTURE)");
216}
217
218// FLEXPWM not available on LPC
219template <>
220fl::shared_ptr<RxDevice> RxDevice::create<RxDeviceType::FLEXPWM>(int pin) FL_NOEXCEPT {
221 (void)pin;
222 return fl::make_shared<DummyRxDevice>("FLEXPWM RX not supported on LPC");
223}
224
225// FLEXIO not available on LPC
226template <>
227fl::shared_ptr<RxDevice> RxDevice::create<RxDeviceType::FLEXIO>(int pin) FL_NOEXCEPT {
228 (void)pin;
229 return fl::make_shared<DummyRxDevice>("FLEXIO RX not supported on LPC");
230}
231
232// DEFAULT maps to LPC_SCT_CAPTURE on LPC.
233template <>
234fl::shared_ptr<RxDevice> RxDevice::create<RxDeviceType::PLATFORM_DEFAULT>(int pin) FL_NOEXCEPT {
236}
237
238#elif defined(FL_IS_STUB)
239
240// RMT device specialization (native stub for host/desktop testing)
241template <>
242fl::shared_ptr<RxDevice> RxDevice::create<RxDeviceType::RMT>(int pin) FL_NOEXCEPT {
243 return NativeRxDevice::create(pin);
244}
245
246// ISR device specialization (native stub for host/desktop testing)
247template <>
248fl::shared_ptr<RxDevice> RxDevice::create<RxDeviceType::ISR>(int pin) FL_NOEXCEPT {
249 return NativeRxDevice::create(pin);
250}
251
252// FLEXPWM device specialization (native stub for host/desktop testing)
253template <>
254fl::shared_ptr<RxDevice> RxDevice::create<RxDeviceType::FLEXPWM>(int pin) FL_NOEXCEPT {
255 return NativeRxDevice::create(pin);
256}
257
258// FLEXIO device specialization (native stub for host/desktop testing). Same
259// NativeRxDevice fallback as the other backends so host-stub tests can exercise
260// `RxBackend::FLEXIO` against the synthetic capture buffer.
261template <>
262fl::shared_ptr<RxDevice> RxDevice::create<RxDeviceType::FLEXIO>(int pin) FL_NOEXCEPT {
263 return NativeRxDevice::create(pin);
264}
265
266// LPC_SCT_CAPTURE device specialization (native stub). Same NativeRxDevice
267// fallback so host-stub tests can exercise `RxBackend::LPC_SCT_CAPTURE`
268// against the synthetic capture buffer.
269template <>
270fl::shared_ptr<RxDevice> RxDevice::create<RxDeviceType::LPC_SCT_CAPTURE>(int pin) FL_NOEXCEPT {
271 return NativeRxDevice::create(pin);
272}
273
274// DEFAULT maps to RMT on stub (same as ESP32 default)
275template <>
276fl::shared_ptr<RxDevice> RxDevice::create<RxDeviceType::PLATFORM_DEFAULT>(int pin) FL_NOEXCEPT {
278}
279
280#else
281
282// RMT device specialization (dummy for non-ESP32, non-stub)
283template <>
284fl::shared_ptr<RxDevice> RxDevice::create<RxDeviceType::RMT>(int pin) FL_NOEXCEPT {
285 (void)pin; // Suppress unused parameter warning
286 return RxDevice::createDummy();
287}
288
289// ISR device specialization (dummy for non-ESP32, non-stub)
290template <>
291fl::shared_ptr<RxDevice> RxDevice::create<RxDeviceType::ISR>(int pin) FL_NOEXCEPT {
292 (void)pin; // Suppress unused parameter warning
293 return RxDevice::createDummy();
294}
295
296// FLEXPWM device specialization (dummy for unsupported platforms)
297template <>
298fl::shared_ptr<RxDevice> RxDevice::create<RxDeviceType::FLEXPWM>(int pin) FL_NOEXCEPT {
299 (void)pin; // Suppress unused parameter warning
300 return RxDevice::createDummy();
301}
302
303// FLEXIO device specialization (dummy for unsupported platforms)
304template <>
305fl::shared_ptr<RxDevice> RxDevice::create<RxDeviceType::FLEXIO>(int pin) FL_NOEXCEPT {
306 (void)pin; // Suppress unused parameter warning
307 return RxDevice::createDummy();
308}
309
310// LPC_SCT_CAPTURE device specialization (dummy for unsupported platforms)
311template <>
312fl::shared_ptr<RxDevice> RxDevice::create<RxDeviceType::LPC_SCT_CAPTURE>(int pin) FL_NOEXCEPT {
313 (void)pin; // Suppress unused parameter warning
314 return RxDevice::createDummy();
315}
316
317// DEFAULT maps to RMT on unsupported platforms (returns dummy)
318template <>
319fl::shared_ptr<RxDevice> RxDevice::create<RxDeviceType::PLATFORM_DEFAULT>(int pin) FL_NOEXCEPT {
321}
322
323#endif // FL_IS_ESP32 / FL_IS_TEENSY_4X / FL_IS_ARM_LPC / FL_IS_STUB
324
325} // namespace fl
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.
Centralized LED chipset timing definitions with nanosecond precision.
shared_ptr< T > make_shared(Args &&... args) FL_NOEXCEPT
Definition shared_ptr.h:414
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
Base definition for an LED controller.
Definition crgb.hpp:179
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
Common RX interfaces and shared types.
#define FL_NOEXCEPT