FastLED 3.10.8
Loading...
Searching...
No Matches
cled_controller.h
Go to the documentation of this file.
1#pragma once
2
5
6#include "color.h"
7#include "pixel_controller.h" // IWYU pragma: keep (ColorAdjustment)
8
10#include "dither_mode.h"
12#include "fl/math/screenmap.h"
13#include "fl/stl/int.h"
14#include "fl/stl/bit_cast.h"
16#include "fl/log/log.h"
17#include "platforms/is_platform.h" // for FL_IS_ESP32, FL_IS_AVR
18#include "fl/stl/span.h"
19#include "fl/stl/noexcept.h"
20#include "fl/spi_bus.h"
21
23//
24// LED Controller interface definition
25//
27
33
34namespace fl {
35
36class Channel;
37
38namespace detail {
45} // namespace detail
46
48protected:
49 friend class CFastLED;
53 // Bit-fields share one byte; a fixed-white flag costs no RAM and no
54 // vtable slot on AVR (#4788).
55 bool mEnabled : 1;
57
59#ifndef FL_IS_AVR
60 // Derived APIs can react to settings changed through a base reference.
61 // AVR has neither this slot nor a notification call.
63 FL_UNUSED(change);
64 }
65#endif
67#ifndef FL_IS_AVR
68 onSettingsChanged(change);
69#else
70 FL_UNUSED(change);
71#endif
72 }
74
80
86 CLEDController(RegistrationMode mode) FL_NO_EXCEPT;
87
88 void applyRgbw(const Rgbw& arg) FL_NO_EXCEPT {
89 if (!arg.active()) {
90 mLegacySettings.mWhiteCfg.reset();
91 } else {
94 mLegacySettings.mWhiteCfg = arg;
95 }
96 }
97
100 void setFixedRgbw(const Rgbw& arg) FL_NO_EXCEPT {
101 applyRgbw(arg);
102 mFixedWhiteChannel = true;
103 }
104
105 bool rejectFixedWhiteChannelChange(const char* operation) const FL_NO_EXCEPT {
106 FL_UNUSED(operation); // only consumed by FL_WARN, a no-op on small platforms
107 if (!mFixedWhiteChannel) {
108 return false;
109 }
110 FL_WARN("Chipset has fixed R,G,B,W output; " << operation << " is unsupported and was ignored");
111 return true;
112 }
113
114public:
115#ifndef FL_IS_AVR
116 // Identify Channels without retaining Channels configuration in this base.
117 // Standalone Channels need the same integration as registered Channels.
118 virtual const Channel* asChannel() const FL_NO_EXCEPT { return nullptr; }
119#endif
123#if defined(FL_IS_ESP32)
124 virtual
125#endif
127 (void)bus;
128 return *this;
129 }
130
134 void addToList() FL_NO_EXCEPT;
135
138 bool isInList() const FL_NO_EXCEPT;
139
144 virtual void showColor(const CRGB & data, int nLeds, fl::u8 brightness) FL_NO_EXCEPT = 0;
145
150 virtual void show(const CRGB *data, int nLeds, fl::u8 brightness) FL_NO_EXCEPT = 0;
151
153 if (rejectFixedWhiteChannelChange("setRgbw()")) {
154 return *this;
155 }
156 // (#2558) mLegacySettings.mWhiteCfg is now a fl::variant<Empty, Rgbw, Rgbww>;
157 // assigning Rgbw selects the 4-channel alternative. The legacy
158 // "setRgbw(RgbwInvalid::value()) → disable" semantics are preserved
159 // by translating an inactive Rgbw into Empty so observers see the
160 // same "no white channel" state they did before the variant migration.
161 if (arg.active()) {
162 // Covers an Rgbw made active by assigning rgbw_mode (#4795).
163 detail::enable_rgbw_conversion();
164 }
165 applyRgbw(arg);
167 return *this; // builder pattern.
168 }
169
176 if (rejectFixedWhiteChannelChange("setRgbww()")) {
177 return *this;
178 }
179 if (!arg.active()) {
180 mLegacySettings.mWhiteCfg.reset();
181 } else {
182 detail::enable_rgbww_conversion(); // see setRgbw (#4795)
183 mLegacySettings.mWhiteCfg = arg;
184 }
186 return *this;
187 }
188
192 if (rejectFixedWhiteChannelChange("clearWhiteChannel()")) {
193 return *this;
194 }
195 mLegacySettings.mWhiteCfg.reset();
197 return *this;
198 }
199
200 void setEnabled(bool enabled) FL_NO_EXCEPT { mEnabled = enabled; }
202
204 // If we added virtual to the AVR boards then we are going to add 600 bytes of memory to the binary
205 // flash size. This is because the virtual destructor pulls in malloc and free, which are the largest
206 // Testing shows that this virtual destructor adds a 600 bytes to the binary on
207 // attiny85 and about 1k for the teensy 4.X series.
208 // Attiny85:
209 // With CLEDController destructor virtual: 11018 bytes to binary.
210 // Without CLEDController destructor virtual: 10666 bytes to binary.
212
216 Rgbw getRgbw() const FL_NO_EXCEPT { return mLegacySettings.rgbw(); }
217
223 const Rgbw* rgbwConfig() const FL_NO_EXCEPT {
224 return mLegacySettings.mWhiteCfg.ptr<Rgbw>();
225 }
226
229 Rgbww getRgbww() const FL_NO_EXCEPT { return mLegacySettings.rgbww(); }
230
232 virtual void init() FL_NO_EXCEPT = 0;
233
238 showLeds(0);
239 }
240
241 // Compatibility with the 3.8.x codebase.
244 void* data = beginShowLeds(mLeds.size());
246 endShowLeds(data);
248#if FASTLED_HAS_ENGINE_EVENTS
250#endif
251 }
252
254
262 void showInternal(const CRGB *data, int nLeds, fl::u8 brightness) FL_NO_EXCEPT {
263 if (getEnabled()) {
264 show(data, nLeds,brightness);
265 }
266 }
267
275 void showColorInternal(const CRGB &data, int nLeds, fl::u8 brightness) FL_NO_EXCEPT {
276 if (getEnabled()) {
277 showColor(data, nLeds, brightness);
278 }
279 }
280
285 if (getEnabled()) {
286 show(mLeds.data(), mLeds.size(), brightness);
287 }
288 }
289
296 if (getEnabled()) {
297 showColor(data, mLeds.size(), brightness);
298 }
299 }
300
304
308
313 template<typename Visitor>
314 static void visitControllers(Visitor&& visitor) FL_NO_EXCEPT {
315 const CLEDController *pCur = head();
316 while(pCur) {
317 visitor(pCur, fl::span<const CRGB>(pCur->leds(), pCur->size()));
318 pCur = pCur->next();
319 }
320 }
321
324 const CLEDController *next() const FL_NO_EXCEPT { return mPNext; }
325
330 mLeds = fl::span<CRGB>(data, nLeds);
331 return *this;
332 }
333
337 mLeds = leds;
338 return *this;
339 }
340
342 void clearLedDataInternal(int nLeds = -1) FL_NO_EXCEPT;
343
349
353 static void removeFromList(CLEDController* controller) FL_NO_EXCEPT;
354
357 // Not virtual on AVR: no AVR controller overrides it (#4788).
358 VIRTUAL_IF_NOT_AVR int size() const FL_NO_EXCEPT { return mLeds.size(); }
359
362 virtual int lanes() FL_NO_EXCEPT { return 1; }
363
366 CRGB* leds() FL_NO_EXCEPT { return mLeds.data(); }
367
370 const CRGB* leds() const FL_NO_EXCEPT { return mLeds.data(); }
371
375
379 CRGB &operator[](int x) FL_NO_EXCEPT { return mLeds[x]; }
380
384 inline CLEDController & setDither(fl::u8 ditherMode = BINARY_DITHER) FL_NO_EXCEPT { mLegacySettings.mDitherMode = ditherMode; settingsChanged(SettingsChange::Dither); return *this; }
385
386 CLEDController& setScreenMap(const fl::XYMap& map, float diameter = -1.f) FL_NO_EXCEPT {
387 // EngineEvents::onCanvasUiSet(this, map);
388 fl::ScreenMap screenmap = map.toScreenMap();
389 if (diameter <= 0.0f) {
390 screenmap.setDiameter(.15f); // Assume small matrix is being used.
391 }
393 return *this;
394 }
395
400
401 CLEDController& setScreenMap(fl::u16 width, fl::u16 height, float diameter = -1.f) FL_NO_EXCEPT {
403 return setScreenMap(xymap, diameter);
404 }
405
408 inline fl::u8 getDither() const FL_NO_EXCEPT { return mLegacySettings.mDitherMode; }
409
410 // Not virtual on AVR (#4788). Its only overrides are the RGBW/WS2816
411 // wrappers, which forward to a disabled inner controller; on AVR the base
412 // version saves and restores the wrapper's own dither instead. Custom AVR
413 // controllers cannot hook these, or size().
416 // By default, emit an integer. This integer will, by default, be passed back.
417 // If you override beginShowLeds() then
418 // you should also override endShowLeds() to match the return state.
419 //
420 // For async led controllers this should be used as a sync point to block
421 // the caller until the leds from the last draw frame have completed drawing.
422 // for each controller:
423 // beginShowLeds();
424 // for each controller:
425 // showLeds();
426 // for each controller:
427 // endShowLeds();
428 uintptr_t d = getDither();
429 void* out = fl::int_to_ptr<void>(d);
430 return out;
431 }
432
434 // By default recieves the integer that beginShowLeds() emitted.
435 //For async controllers this should be used to signal the controller
436 // to begin transmitting the current frame to the leds.
437 uintptr_t d = fl::ptr_to_int(data);
438 setDither(static_cast<fl::u8>(d));
439 }
440
445 mLegacySettings.mCorrection = correction;
447 return *this;
448 }
449
452 mLegacySettings.mCorrection = correction;
454 return *this;
455 }
456
460
465 mLegacySettings.mTemperature = temperature;
467 return *this;
468 }
469
472 mLegacySettings.mTemperature = temperature;
474 return *this;
475 }
476
480
487
490 virtual fl::u16 getMaxRefreshRate() const FL_NO_EXCEPT { return 0; }
491};
492
493#ifdef FL_IS_AVR
494// Legacy controllers must stay compact even when Channels gains new options.
495FL_STATIC_ASSERT(sizeof(CLEDController) <= 32, "Legacy AVR controller grew beyond its settings budget");
496#endif
497
498} // namespace fl
fl::UISlider brightness("Brightness", BRIGHTNESS, 0, 255)
XYMap xymap
fl::ScreenMap screenmap
FastLED show()
CLEDController * controller
fl::UISlider scale("Scale", 4,.1, 4,.1)
void showColorInternal(const CRGB &data, int nLeds, fl::u8 brightness) FL_NO_EXCEPT
Rgbww getRgbww() const FL_NO_EXCEPT
const Rgbw * rgbwConfig() const FL_NO_EXCEPT
virtual int lanes() FL_NO_EXCEPT
How many Lanes does this controller manage?
void showLedsInternal(fl::u8 brightness) FL_NO_EXCEPT
Write the data to the LEDs managed by this controller.
static void visitControllers(Visitor &&visitor) FL_NO_EXCEPT
Visit all controllers in the linked list with a visitor The visitor must be a callable that accepts (...
CLEDController & setRgbw(const Rgbw &arg=RgbwDefault::value()) FL_NO_EXCEPT
void applyRgbw(const Rgbw &arg) FL_NO_EXCEPT
RegistrationMode
Registration mode for constructor.
@ AutoRegister
Automatically add to linked list (default, backward compatible)
@ DeferRegister
Defer registration until addToList() is called.
CLEDController & setTemperature(CRGB temperature) FL_NO_EXCEPT
Set the color temperature, aka white point, for this controller.
void clearLedDataInternal(int nLeds=-1) FL_NO_EXCEPT
Zero out the LED data managed by this controller.
static CLEDController * head() FL_NO_EXCEPT
Get the first LED controller in the linked list of controllers.
bool getEnabled() FL_NO_EXCEPT
void settingsChanged(SettingsChange change) FL_NO_EXCEPT
CLEDController & setRgbww(const Rgbww &arg=RgbwwDefault::value()) FL_NO_EXCEPT
Configure this channel for 5-channel RGBWW (RGB + warm-W + cool-W) output.
VIRTUAL_IF_NOT_AVR void * beginShowLeds(int size) FL_NO_EXCEPT
fl::span< CRGB > ledsSpan() FL_NO_EXCEPT
Span of LEDs managed by this controller.
void setFixedRgbw(const Rgbw &arg) FL_NO_EXCEPT
Configure a chipset-owned RGBW policy that public white-channel setters cannot replace.
virtual void onSettingsChanged(SettingsChange change) FL_NO_EXCEPT
const CRGB * leds() const FL_NO_EXCEPT
Const pointer to the CRGB array for this controller.
virtual const Channel * asChannel() const FL_NO_EXCEPT
VIRTUAL_IF_NOT_AVR void clearLeds(int nLeds=-1) FL_NO_EXCEPT
Clear out/zero out the given number of LEDs.
LegacySettings mLegacySettings
virtual void show(const CRGB *data, int nLeds, fl::u8 brightness) FL_NO_EXCEPT=0
Write the passed in RGB data out to the LEDs managed by this controller.
void setEnabled(bool enabled) FL_NO_EXCEPT
CLEDController & setScreenMap(const fl::XYMap &map, float diameter=-1.f) FL_NO_EXCEPT
CLEDController & setScreenMap(fl::u16 width, fl::u16 height, float diameter=-1.f) FL_NO_EXCEPT
VIRTUAL_IF_NOT_AVR int size() const FL_NO_EXCEPT
How many LEDs does this controller manage?
CLEDController & setLeds(CRGB *data, int nLeds) FL_NO_EXCEPT
Set the default array of LEDs to be used by this controller.
CRGB getCorrection() FL_NO_EXCEPT
Get the correction value used by this controller.
fl::u8 getDither() const FL_NO_EXCEPT
Get the dithering option currently set for this controller.
VIRTUAL_IF_NOT_AVR void endShowLeds(void *data) FL_NO_EXCEPT
void showColorInternal(const CRGB &data, fl::u8 brightness) FL_NO_EXCEPT
CRGB getTemperature() FL_NO_EXCEPT
Get the color temperature, aka white point, for this controller.
bool mFixedWhiteChannel
chipset wire format owns the white policy
void removeFromDrawList() FL_NO_EXCEPT
Remove this controller from the draw list.
void showInternal(const CRGB *data, int nLeds, fl::u8 brightness) FL_NO_EXCEPT
bool rejectFixedWhiteChannelChange(const char *operation) const FL_NO_EXCEPT
CLEDController & setLeds(fl::span< CRGB > leds) FL_NO_EXCEPT
Set the default array of LEDs to be used by this controller (span version)
CRGB * leds() FL_NO_EXCEPT
Pointer to the CRGB array for this controller.
static void removeFromList(CLEDController *controller) FL_NO_EXCEPT
Remove a controller from the linked list.
CLEDController & clearWhiteChannel() FL_NO_EXCEPT
Reset this channel to plain 3-channel RGB (clears any RGBW/RGBWW configuration).
virtual fl::u16 getMaxRefreshRate() const FL_NO_EXCEPT
Gets the maximum possible refresh rate of the strip.
const CLEDController * next() const FL_NO_EXCEPT
Get the next controller in the linked list after this one (const version).
CLEDController * mPNext
pointer to the next LED controller in the linked list
CLEDController & setDither(fl::u8 ditherMode=BINARY_DITHER) FL_NO_EXCEPT
Set the dithering mode for this controller to use.
static CLEDController * mPHead
pointer to the first LED controller in the linked list
friend class CFastLED
CLEDController & setCorrection(LEDColorCorrection correction) FL_NO_EXCEPT
The color corrction to use for this controller, expressed as a CRGB object.
CLEDController * next() FL_NO_EXCEPT
Get the next controller in the linked list after this one.
CRGB & operator[](int x) FL_NO_EXCEPT
Reference to the n'th LED managed by the controller.
CLEDController(RegistrationMode mode) FL_NO_EXCEPT
Protected constructor with registration mode.
virtual void showColor(const CRGB &data, int nLeds, fl::u8 brightness) FL_NO_EXCEPT=0
Set all the LEDs to a given color.
Rgbw getRgbw() const FL_NO_EXCEPT
CLEDController & setSpiBus(Esp32SpiBus bus) FL_NO_EXCEPT
Select an ESP-IDF SPI host for this clocked controller before init().
VIRTUAL_IF_NOT_AVR void showLeds(fl::u8 brightness) FL_NO_EXCEPT
CLEDController & setCorrection(CRGB correction) FL_NO_EXCEPT
The color corrction to use for this controller, expressed as a CRGB object.
CLEDController & setTemperature(ColorTemperature temperature) FL_NO_EXCEPT
Set the color temperature, aka white point, for this controller.
CRGB getAdjustment(fl::u8 scale) FL_NO_EXCEPT
Get the combined brightness/color adjustment for this controller.
virtual void init() FL_NO_EXCEPT=0
Initialize the LED controller.
fl::span< CRGB > mLeds
span of LED data used by this controller
CLEDController & setScreenMap(const fl::ScreenMap &map) FL_NO_EXCEPT
LED channel for parallel output, pretty much a CPixelLEDController but with timing and pin informatio...
Definition channel.h:60
static void onBeginFrame() FL_NO_EXCEPT
static void onEndShowLeds() FL_NO_EXCEPT
static void onEndFrame() FL_NO_EXCEPT
static void onCanvasUiSet(CLEDController *strip, const ScreenMap &xymap) FL_NO_EXCEPT
static XYMap constructRectangularGrid(u16 width, u16 height, u16 offset=0) FL_NO_EXCEPT
Definition xymap.cpp.hpp:36
fl::CLEDController CLEDController
#define VIRTUAL_IF_NOT_AVR
#define FL_UNUSED(x)
#define FASTLED_UNUSED(x)
#define BINARY_DITHER
Enable dithering using binary dithering (only option)
Definition dither_mode.h:16
Declares dithering options and types.
ColorTemperature
Color temperature values.
Definition color.h:42
LEDColorCorrection
Color correction starting points.
Definition color.h:11
#define FL_WARN(...)
Definition log.h:437
Centralized logging categories for FastLED hardware interfaces and subsystems.
void enable_rgbww_conversion() FL_NO_EXCEPT
Installs the RGBWW pixel conversion (see enable_rgbw_conversion, #4795).
void enable_rgbw_power_estimate() FL_NO_EXCEPT
Lets the power limiter charge a controller's RGBW conversion.
Compile-time linker keep-alive hook for a single fl::Bus.
Definition bus_info.h:57
unsigned char u8
Definition stdint.h:131
Esp32SpiBus
ESP-IDF SPI host selection for an individual clocked LED controller.
Definition spi_bus.h:18
u8 u8 fract8 blur_amount FL_NO_EXCEPT
Definition blur.h:186
constexpr int type_rank< T >::value
MapRedBlackTree< Key, T, Compare, fl::allocator_slab< char > > map
Definition map.h:283
u8 u8 height
Definition blur.h:186
void prepare_rgbw_colorimetric(const Rgbw &) FL_NO_EXCEPT
Definition rgbw.cpp.hpp:626
u8 width
Definition blur.h:186
uptr ptr_to_int(T *ptr) FL_NO_EXCEPT
Definition bit_cast.h:71
T * int_to_ptr(uptr value) FL_NO_EXCEPT
Definition bit_cast.h:76
Base definition for an LED controller.
Definition crgb.hpp:179
Low level pixel data writing class.
#define FL_STATIC_ASSERT(...)
fl::uptr uintptr_t
Definition stdint.h:223
Color adjustment structure for pixel output.
static CRGB computeAdjustment(u8 scale, const CRGB &colorCorrection, const CRGB &colorTemperature) FL_NO_EXCEPT
Calculates the combined color adjustment to the LEDs at a given scale, color correction,...
Definition crgb.cpp.hpp:29
Representation of an 8-bit RGB pixel (Red, Green, Blue)
Definition crgb.h:38
static Rgbww value() FL_NO_EXCEPT
Definition rgbww.h:118