FastLED 3.10.9
Loading...
Searching...
No Matches
LegacyClocklessProxy.h
Go to the documentation of this file.
1// LegacyClocklessProxy.h - Runtime-to-template pin dispatch for legacy addLeds API
2//
3// Maps a runtime pin number and chipset name to compile-time clockless template
4// instantiations via a switch statement. This allows AutoResearch testing of the
5// legacy template API path: CHIPSET<PIN> -> ClocklessControllerImpl ->
6// ClocklessIdf5 -> SlimBridgeController -> RMT5 driver.
7
8#pragma once
9
10#include <FastLED.h>
11#include "fl/stl/unique_ptr.h"
12#include "fl/stl/weak_ptr.h"
13
14#if defined(FL_IS_ESP_32DEV) && !FASTLED_RMT5 && !defined(FASTLED_ESP32_USE_CLOCKLESS_SPI) // ok platform specific - only this backend exposes retained frame leases.
15#define AUTORESEARCH_LEGACY_OBSERVES_RMT4_FRAMES 1
16#else
17#define AUTORESEARCH_LEGACY_OBSERVES_RMT4_FRAMES 0
18#endif
19
26
27#if defined(FL_IS_TEENSY_4X)
28#define AUTORESEARCH_LEGACY_SUPPORTS_PIN_22 1
29#else
30#define AUTORESEARCH_LEGACY_SUPPORTS_PIN_22 0
31#endif
32
33// GPIO6/7/8 on the classic ESP32 (esp32dev / WROOM modules) are
34// reserved for SPI flash (SD2/SD3/CMD/CLK/SD0/SD1 — pins 6-11) and
35// FastLED's `FASTLED_UNUSABLE_PIN_MASK` for esp32dev marks pins
36// {6, 7, 8, 9, 10, 11, 20} as `validpin() == false`. Instantiating any
37// clockless driver bound to those pins fails the FastLED static_assert
38// at compile time. Other ESP32 variants (S2/S3/C-series, P4) repurpose
39// GPIO6-8 and accept them as valid output pins, and every non-ESP
40// family treats them as normal digital pins. The classic-ESP32
41// sentinel is `FL_IS_ESP_32DEV` (defined in `src/platforms/esp/is_esp.h`);
42// the prior #3447 attempt used `FL_IS_ESP_32` which is not a real macro,
43// so the gate never fired and esp32dev compile still hit the
44// static_assert. LegacyClocklessProxy iterates pins 0-8 so all three
45// of 6/7/8 must be excluded for the classic ESP32 build. ESP8266 wires
46// GPIO6-11 to the SPI flash too, so it takes the same exclusion.
47#if defined(FL_IS_ESP_32DEV) || defined(FL_IS_ESP8266) // ok platform specific - classic ESP32 and ESP8266 wire GPIO6-11 to SPI flash; safe output pins 18/19 provide five strips on classic ESP32.
48#define AUTORESEARCH_LEGACY_SUPPORTS_PIN_6 0
49#define AUTORESEARCH_LEGACY_SUPPORTS_PIN_7 0
50#define AUTORESEARCH_LEGACY_SUPPORTS_PIN_8 0
51#else
52#define AUTORESEARCH_LEGACY_SUPPORTS_PIN_6 1
53#define AUTORESEARCH_LEGACY_SUPPORTS_PIN_7 1
54#define AUTORESEARCH_LEGACY_SUPPORTS_PIN_8 1
55#endif
56
58 switch (chipset) {
60 return "WS2812B";
62 return "WS2814";
64 return "WS2818";
66 return "SK6812";
67 }
68 return "UNKNOWN";
69}
70
73 if (name == "WS2812B" || name == "WS2812") {
74 if (out) *out = LegacyClocklessChipset::WS2812B;
75 return true;
76 }
77 if (name == "SK6812") {
78 if (out) *out = LegacyClocklessChipset::SK6812;
79 return true;
80 }
81 if (name == "WS2814") {
82 if (out) *out = LegacyClocklessChipset::WS2814;
83 return true;
84 }
85 if (name == "WS2818") {
86 if (out) *out = LegacyClocklessChipset::WS2818;
87 return true;
88 }
89 return false;
90}
91
96
103inline const char* legacyClocklessBoundDriverName() {
104#if defined(FL_IS_ESP32)
105 #if defined(FL_ESP32_LEGACY_CLOCKLESS_USE_RMT) && \
106 FL_ESP32_LEGACY_CLOCKLESS_USE_RMT
107 return "RMT";
108 #elif FASTLED_ESP32_HAS_PARLIO && \
109 (defined(FL_IS_ESP_32P4) || defined(FL_IS_ESP_32C6) || \
110 defined(FL_IS_ESP_32H2) || defined(FL_IS_ESP_32C5))
111 return "PARLIO";
112 #elif FASTLED_ESP32_HAS_RMT && \
113 !defined(FASTLED_ESP32_USE_CLOCKLESS_SPI)
114 return "RMT";
115 #elif FASTLED_ESP32_HAS_CLOCKLESS_SPI
116 return "SPI";
117 #else
118 return "BIT_BANG";
119 #endif
120#elif defined(FL_IS_TEENSY_4X)
121 return "OBJECT_FLED";
122#elif defined(FL_IS_RP)
123 // RP legacy templates are slim bridges onto PIO0
124 // (BusTraits<Bus::FLEX_IO, 0>), or the M0 bit-bang engine when the PIO
125 // path is disabled (#4623).
126 #if FASTLED_RP2040_CLOCKLESS_PIO
127 return "PIO0";
128 #else
129 return "BIT_BANG";
130 #endif
131#else
132 return nullptr;
133#endif
134}
135
152#if AUTORESEARCH_LEGACY_OBSERVES_RMT4_FRAMES
154#endif
155
156 template<typename Controller>
158 bool rgbw) {
160 FastLED.addLeds(c.get(), leds, numLeds);
161#if AUTORESEARCH_LEGACY_OBSERVES_RMT4_FRAMES
162 mFrame = c->channelData();
163#endif
164 if (rgbw) {
165 c->setRgbw(RgbwDefault());
166 }
167 return c;
168 }
169
170 template<int PIN>
173 bool rgbw) {
174 switch (chipset) {
176 return createTyped<WS2812B<PIN, RGB>>(leds, numLeds, rgbw);
178 return createTyped<WS2814<PIN, RGB>>(leds, numLeds, rgbw);
180 return createTyped<WS2818<PIN, RGB>>(leds, numLeds, rgbw);
182 return createTyped<SK6812<PIN, RGB>>(leds, numLeds, rgbw);
183 }
184 return nullptr;
185 }
186
187public:
189 int pin, CRGB* leds, int numLeds,
191 bool rgbw = false) {
192 switch (pin) {
193 case 0: mController = create<0>(leds, numLeds, chipset, rgbw); break;
194 case 1: mController = create<1>(leds, numLeds, chipset, rgbw); break;
195 case 2: mController = create<2>(leds, numLeds, chipset, rgbw); break;
196 case 3: mController = create<3>(leds, numLeds, chipset, rgbw); break;
197 case 4: mController = create<4>(leds, numLeds, chipset, rgbw); break;
198 case 5: mController = create<5>(leds, numLeds, chipset, rgbw); break;
199#if defined(FL_IS_ESP_32DEV) // ok platform specific - five-strip overflow probe needs safe classic ESP32 output pins 18/19
200 case 18: mController = create<18>(leds, numLeds, chipset, rgbw); break;
201 case 19: mController = create<19>(leds, numLeds, chipset, rgbw); break;
202#endif
203#if AUTORESEARCH_LEGACY_SUPPORTS_PIN_6
204 case 6: mController = create<6>(leds, numLeds, chipset, rgbw); break;
205#endif
206#if AUTORESEARCH_LEGACY_SUPPORTS_PIN_7
207 case 7: mController = create<7>(leds, numLeds, chipset, rgbw); break;
208#endif
209#if AUTORESEARCH_LEGACY_SUPPORTS_PIN_8
210 case 8: mController = create<8>(leds, numLeds, chipset, rgbw); break;
211#endif
212#if AUTORESEARCH_LEGACY_SUPPORTS_PIN_22
213 case 22: mController = create<22>(leds, numLeds, chipset, rgbw); break;
214#endif
215 default: break; // mController stays nullptr
216 }
217 }
218
220
221 // Non-copyable (unique_ptr already enforces this, but be explicit)
224
226 bool valid() const { return mController != nullptr; }
227
228 void showLeds(uint8_t brightness = 255) {
229 if (mController) { mController->showLeds(brightness); }
230 }
231
232 void setEnabled(bool enabled) {
233 if (mController) { mController->setEnabled(enabled); }
234 }
235
237 if (mController) { mController->setLeds(leds); }
238 }
239
240#if AUTORESEARCH_LEGACY_OBSERVES_RMT4_FRAMES
241 fl::weak_ptr<fl::ChannelData> frameData() const { return mFrame; }
242#endif
243};
CRGB leds[1]
fl::UISlider brightness("Brightness", BRIGHTNESS, 0, 255)
FL_DISABLE_WARNING_PUSH FL_DISABLE_WARNING_GLOBAL_CONSTRUCTORS CFastLED FastLED
Global LED strip management instance.
LegacyClocklessChipset
bool legacyClocklessChipsetFromName(const fl::string &name, LegacyClocklessChipset *out)
const char * legacyClocklessChipsetName(LegacyClocklessChipset chipset)
const char * legacyClocklessBoundDriverName()
Name of the driver to which public legacy templates are bound.
bool legacyClocklessChipsetHasAutomaticRgbw(LegacyClocklessChipset chipset)
Rgbw rgbw
fl::unique_ptr< CLEDController > create(CRGB *leds, int numLeds, LegacyClocklessChipset chipset, bool rgbw)
LegacyClocklessProxy(int pin, CRGB *leds, int numLeds, LegacyClocklessChipset chipset=LegacyClocklessChipset::WS2812B, bool rgbw=false)
fl::unique_ptr< CLEDController > createTyped(CRGB *leds, int numLeds, bool rgbw)
fl::unique_ptr< CLEDController > mController
void setEnabled(bool enabled)
void setLeds(fl::span< CRGB > leds)
void showLeds(uint8_t brightness=255)
LegacyClocklessProxy(const LegacyClocklessProxy &)=delete
bool valid() const
Check if the proxy was successfully created.
LegacyClocklessProxy & operator=(const LegacyClocklessProxy &)=delete
~LegacyClocklessProxy()=default
fl::CRGB CRGB
Definition crgb.h:25
fl::enable_if<!fl::is_array< T >::value, unique_ptr< T > >::type make_unique(Args &&... args) FL_NO_EXCEPT
Definition unique_ptr.h:263