FastLED 3.10.8
Loading...
Searching...
No Matches
chipsets.h
Go to the documentation of this file.
1#pragma once
2
3#ifndef __INC_CHIPSETS_H
4#define __INC_CHIPSETS_H
5
6// allow-include-after-namespace
7
8#include "pixeltypes.h"
12#include "fl/stl/bit_cast.h"
13#include "fl/stl/unique_ptr.h"
14#include "pixel_iterator.h"
15#include "crgb.h"
16#include "eorder.h"
17#include "fl/math/math.h"
18#include "platforms/is_platform.h"
19
20// Include centralized LED chipset timing definitions
21// These provide unified nanosecond-based T1, T2, T3 timing for all supported chipsets
23
24// Include legacy AVR-specific timing definitions (FMUL-based)
25// Used for backward compatibility with existing AVR clockless drivers
26#ifdef FL_IS_AVR
27#include "platforms/avr/led_timing_legacy_avr.h" // ok platform headers
28#endif
29
30// Platform-specific clockless controller dispatch
31// Includes the appropriate clockless controller implementation for the target platform
32#include "platforms/clockless.h"
33
34// Include UCS7604 controller (works on all platforms with clockless controller support)
35#include "fl/chipsets/ucs7604.h"
37
38// Include platform-independent SPI utilities
39#include "platforms/shared/spi_pixel_writer.h" // ok platform headers
40
41// Platform-specific SPI output template dispatch
42// Includes the appropriate SPIOutput template implementation for the target platform
43// This must be included before any SPI chipset controllers (e.g., APA102, P9813)
44#include "platforms/spi_output_template.h"
45
46// Include SPI chipset controllers
47#include "fl/chipsets/apa102.h"
48#include "fl/chipsets/hd108.h"
49#include "fl/chipsets/lpd880x.h"
50#include "fl/chipsets/ws2801.h"
51#include "fl/chipsets/p9813.h"
52#include "fl/chipsets/sm16716.h"
53#include "fl/chipsets/my9221.h"
54
55// Platform-specific clockless timing configuration
56//
57// IMPORTANT: All platforms use nanosecond-based timing at the API level.
58// Chipset timing values (T1, T2, T3) are specified in nanoseconds (e.g., T1=250ns, T2=625ns, T3=375ns)
59//
60// Platforms that need cycle-based timing internally (e.g., AVR, ARM, ESP8266) perform
61// nanosecond-to-cycle conversion within their clockless driver implementation using F_CPU or equivalent.
62//
63// Platform-specific clockless drivers are defined in:
64// - ESP32/ESP8266: platforms/esp/clockless.h
65// - All ARM platforms: led_sysdefs_arm_*.h + platform-specific clockless headers
66// - AVR platforms: led_sysdefs_avr.h + platforms/avr/clockless_*.h
67// - Other platforms: respective led_sysdefs_*.h files
68
69// ============================================================================
70// PLATFORM-SPECIFIC SPECIALIZED CONTROLLERS (Bottom Includes)
71// ============================================================================
72// The includes below MUST be at this point in the file because:
73//
74// 1. C++ templates require full definition in headers (no .cpp separation)
75// 2. Base templates and type definitions (above) must be defined BEFORE
76// platform-specific specializations (below) can see and use them
77// 3. Platform specializations need to instantiate/specialize the base templates
78//
79// This is intentional C++ template architecture, not a code smell or circular
80// dependency. Template-heavy libraries like FastLED naturally have includes at
81// the bottom to support platform-specific specializations.
82//
83// Example: WS2812 is heavily optimized per-platform because it's the most
84// popular chipset. Each platform provides specialized implementations that
85// fully replace the default template instantiation.
86// ============================================================================
87
88#include "platforms/chipsets_specialized_ws2812.h"
89
90#if defined(ARDUINO) && (defined(SoftwareSerial_h) || defined(__SoftwareSerial_h))
91// IWYU pragma: begin_keep
92#include <SoftwareSerial.h>
93// IWYU pragma: end_keep
94#endif
95
98
99
100
105
106#if defined(ARDUINO) && (defined(SoftwareSerial_h) || defined(__SoftwareSerial_h))
107
108#define HAS_PIXIE
109
110
114template<fl::u8 DATA_PIN, EOrder RGB_ORDER = RGB>
115class PixieController : public CPixelLEDController<RGB_ORDER> {
116 SoftwareSerial Serial;
117 CMinWait<2000> mWait;
118
119public:
120 PixieController() : Serial(-1, DATA_PIN) {}
121
122protected:
124 virtual void init() {
125 Serial.begin(115200);
126 mWait.mark();
127 }
128
130 virtual void showPixels(PixelController<RGB_ORDER> & pixels) {
131 mWait.wait();
132 while(pixels.has(1)) {
133 fl::u8 r = pixels.loadAndScale0();
134 Serial.write(r);
135 fl::u8 g = pixels.loadAndScale1();
136 Serial.write(g);
137 fl::u8 b = pixels.loadAndScale2();
138 Serial.write(b);
139 pixels.advanceData();
140 pixels.stepDithering();
141 }
142 mWait.mark();
143 }
144
145};
146
147// template<SoftwareSerial & STREAM, EOrder RGB_ORDER = RGB>
148// class PixieController : public PixieBaseController<STREAM, RGB_ORDER> {
149// public:
150// virtual void init() {
151// STREAM.begin(115200);
152// }
153// };
154
155#endif
156#endif
157
189
190
191template <
192 typename CONTROLLER,
193 EOrder RGB_ORDER = GRB> // Default on WS2812>
195 : public CPixelLEDController<RGB_ORDER, CONTROLLER::LANES_VALUE,
196 CONTROLLER::MASK_VALUE> {
197 public:
198 // ControllerT is a helper class. It subclasses the device controller class
199 // and has three methods to call the three protected methods we use.
200 // This is janky, but redeclaring public methods protected in a derived class
201 // is janky, too.
202
203 // N.B., byte order must be RGB.
204 typedef CONTROLLER ControllerBaseT;
205 class ControllerT : public CONTROLLER {
206 friend class RGBWEmulatedController<CONTROLLER, RGB_ORDER>;
207 void *callBeginShowLeds(int size) FL_NO_EXCEPT { return ControllerBaseT::beginShowLeds(size); }
208 void callShow(CRGB *data, int nLeds, fl::u8 brightness) FL_NO_EXCEPT {
209 ControllerBaseT::show(data, nLeds, brightness);
210 }
211 void callEndShowLeds(void *data) FL_NO_EXCEPT { ControllerBaseT::endShowLeds(data); }
212 };
213
214
215 static const int LANES = CONTROLLER::LANES_VALUE;
216 static const fl::u32 MASK = CONTROLLER::MASK_VALUE;
217
218 // The delegated controller must do no reordering.
219 FL_STATIC_ASSERT(RGB == CONTROLLER::RGB_ORDER_VALUE, "The delegated controller MUST NOT do reordering");
220
226
229
233
235 return mController.callEndShowLeds(data);
236 }
237
246 // Ensure buffer is large enough
247 ensureBuffer(pixels.size());
248 Rgbw rgbw = this->getRgbw();
250 while (pixels.has(1)) {
251 pixels.stepDithering();
252 pixels.loadAndScaleRGBW(rgbw, data, data + 1, data + 2, data + 3);
253 data += 4;
254 pixels.advanceData();
255 }
256
257 // Force the device controller to a state where it passes data through
258 // unmodified: color correction, color temperature, dither, and brightness
259 // (passed as an argument to show()). Temporarily enable the controller,
260 // show the LEDs, and disable it again.
261 //
262 // The device controller is in the global controller list, so if we
263 // don't keep it disabled, it will refresh again with unknown brightness,
264 // temperature, etc.
265
266 mController.setCorrection(CRGB(255, 255, 255));
267 mController.setTemperature(CRGB(255, 255, 255));
268 mController.setDither(DISABLE_DITHER);
269
270 mController.setEnabled(true);
271 mController.callShow(mRGBWPixels.get(), Rgbw::size_as_rgb(pixels.size()), 255);
272 mController.setEnabled(false);
273 }
274
275 private:
279 void init() FL_NO_EXCEPT override {
280 mController.init();
281 mController.setEnabled(false);
282 }
283
288 void ensureBuffer(fl::i32 num_leds) FL_NO_EXCEPT {
289 if (num_leds != mNumRGBLeds) {
290 mNumRGBLeds = num_leds;
291 // The delegate controller expects the raw pixel byte data in multiples of 3.
292 // In the case of src data not a multiple of 3, then we need to
293 // add pad bytes so that the delegate controller doesn't walk off the end
294 // of the array and invoke a buffer overflow panic.
295 fl::u32 new_size = Rgbw::size_as_rgb(num_leds);
296 mRGBWPixels.reset(new CRGB[new_size]); // ok bare allocation (array new)
297 // showPixels may never clear the last two pixels.
298 for (fl::u32 i = 0; i < new_size; i++) {
299 mRGBWPixels[i] = CRGB(0, 0, 0);
300 }
301
302 mController.setLeds(mRGBWPixels.get(), new_size);
303 }
304 }
305
307 fl::i32 mNumRGBLeds = 0;
308 fl::i32 mNumRGBWLeds = 0;
310};
311
315
324
325
326
328//
329// Clockless template instantiations - see clockless.h for how the timing values are used
330//
331
332#ifdef FL_CLOCKLESS_CONTROLLER_DEFINED
357
358// Allow clock that clockless controller is based on to have different
359// frequency than the CPU.
360#if !defined(CLOCKLESS_FREQUENCY)
361 #define CLOCKLESS_FREQUENCY F_CPU
362#endif
363
364// We want to force all avr's to use the Trinket controller when running at 8Mhz, because even the 328's at 8Mhz
365// need the more tightly defined timeframes.
366// Suppress -Wsubobject-linkage warning for controller template instantiations.
367// In C++11/14, constexpr variables have internal linkage, which causes the compiler
368// to warn when they are used in base classes of externally-linked templates. The macro
369// FL_INLINE_CONSTEXPR adds explicit 'inline' in C++17+ to resolve this, but for C++11
370// compatibility we suppress the warning here.
373
374
375
376
377// Legacy macro for nanoseconds to clock cycles conversion
378// This is no longer used by the core API but kept for backward compatibility
379#define FL_NANOSECONDS_TO_CLOCK_CYCLES(_NS) (((_NS * ((CLOCKLESS_FREQUENCY / 1000000L)) + 999)) / 1000)
380
381
382//
383// Given datasheet timing values T0H, T0L, T1H, T1L (in nanoseconds):
384//
385// duration = max(T0H + T0L, T1H + T1L) # Maximum cycle time
386// T1 = T0H # High time for '0' bit
387// T2 = T1H - T0H # Additional time for '1' bit
388// T3 = duration - T1H # Tail time after '1' bit
389//
390// Example (WS2812B with T0H=400, T0L=850, T1H=850, T1L=400):
391// duration = 1250, T1 = 400, T2 = 450, T3 = 400
392//
393// For interactive conversion or validation, use: uv run ci/tools/led_timing_conversions.py
394// For automated testing of all chipsets: uv run ci/test_led_timing_conversion.py
395// For C++ check out
396// * converter: src/fl/clockless/timing_conversion.h
397// * tests: tests/fl/clockless/timing_conversion.cpp
398
399
402template <int DATA_PIN, EOrder RGB_ORDER = RGB>
403class GE8822Controller800Khz : public fl::ClocklessControllerImpl<DATA_PIN, fl::TIMING_GE8822_800KHZ, RGB_ORDER, 4, false> {};
404
407template <int DATA_PIN, EOrder RGB_ORDER = RGB>
408class GW6205Controller400Khz : public fl::ClocklessControllerImpl<DATA_PIN, fl::TIMING_GW6205_400KHZ, RGB_ORDER, 4, false> {};
409
412template <int DATA_PIN, EOrder RGB_ORDER = RGB>
413class GW6205Controller800Khz : public fl::ClocklessControllerImpl<DATA_PIN, fl::TIMING_GW6205_800KHZ, RGB_ORDER> {};
414
417template <int DATA_PIN, EOrder RGB_ORDER = RGB>
418class UCS1903Controller400Khz : public fl::ClocklessControllerImpl<DATA_PIN, fl::TIMING_UCS1903_400KHZ, RGB_ORDER> {};
419
422template <int DATA_PIN, EOrder RGB_ORDER = RGB>
423class UCS1903BController800Khz : public fl::ClocklessControllerImpl<DATA_PIN, fl::TIMING_UCS1903B_800KHZ, RGB_ORDER> {};
424
427template <int DATA_PIN, EOrder RGB_ORDER = RGB>
428class UCS1904Controller800Khz : public fl::ClocklessControllerImpl<DATA_PIN, fl::TIMING_UCS1904_800KHZ, RGB_ORDER> {};
429
432template <int DATA_PIN, EOrder RGB_ORDER = RGB>
433class UCS2903Controller : public fl::ClocklessControllerImpl<DATA_PIN, fl::TIMING_UCS2903, RGB_ORDER> {};
434
435// Template wrapper to adapt ClocklessControllerImpl (6-param template alias)
436// to the 3-param template template parameter expected by UCS7604ControllerT
437namespace {
438 template<int DATA_PIN, typename TIMING, EOrder RGB_ORDER>
439 class ClocklessControllerWrapper : public fl::ClocklessControllerImpl<DATA_PIN, TIMING, RGB_ORDER> {};
440}
441
444template <int DATA_PIN, EOrder RGB_ORDER = RGB>
446
449template <int DATA_PIN, EOrder RGB_ORDER = RGB>
451
454template <int DATA_PIN, EOrder RGB_ORDER = RGB>
456
459template <int DATA_PIN, EOrder RGB_ORDER = RGB>
460class TM1809Controller800Khz : public fl::ClocklessControllerImpl<DATA_PIN, fl::TIMING_TM1809_800KHZ, RGB_ORDER> {};
461
464template <int DATA_PIN, EOrder RGB_ORDER = RGB>
465class TM1908Controller
466 : public fl::ClocklessControllerImpl<DATA_PIN, fl::TIMING_TM1908,
467 RGB_ORDER, 0, false,
468 fl::TIMING_TM1908::RESET> {};
469
473template <int DATA_PIN, EOrder RGB_ORDER = GRB>
474class WS2811Controller800Khz : public fl::ClocklessControllerImpl<DATA_PIN, fl::TIMING_WS2811_800KHZ_LEGACY, RGB_ORDER> {};
475
478template <int DATA_PIN, EOrder RGB_ORDER = GRB>
479class WS2813Controller : public fl::ClocklessControllerImpl<DATA_PIN, fl::TIMING_WS2813, RGB_ORDER> {};
480
484template <int DATA_PIN, EOrder RGB_ORDER = RGB>
485class WS2814Controller
486 : public fl::ClocklessControllerImpl<DATA_PIN, fl::TIMING_WS2814,
487 RGB_ORDER, 0, false,
488 fl::TIMING_WS2814::RESET> {
489 using Base = fl::ClocklessControllerImpl<
490 DATA_PIN, fl::TIMING_WS2814, RGB_ORDER, 0, false,
492
493 public:
494 WS2814Controller() FL_NO_EXCEPT {
495 this->setFixedRgbw(fl::RgbwDefault::value());
496 }
497
498 void init() FL_NO_EXCEPT override {
499 Base::init();
500 }
501};
502
505template <int DATA_PIN, EOrder RGB_ORDER = GRB>
506class WS2818Controller
507 : public fl::ClocklessControllerImpl<DATA_PIN, fl::TIMING_WS2818,
508 RGB_ORDER, 0, false,
509 fl::TIMING_WS2818::RESET> {};
510
515#if !FASTLED_WS2812_HAS_SPECIAL_DRIVER
516template <int DATA_PIN, EOrder RGB_ORDER = GRB>
517class WS2812Controller800Khz : public fl::ClocklessControllerImpl<DATA_PIN, fl::TIMING_WS2812_800KHZ, RGB_ORDER> {};
518#endif
519
525template <int DATA_PIN, EOrder RGB_ORDER = GRB>
526class OSTW2020C1EController
527 : public fl::ClocklessControllerImpl<DATA_PIN,
528 fl::TIMING_WS2812_800KHZ,
529 RGB_ORDER, 0, false, 300> {};
530
534template <int DATA_PIN, EOrder RGB_ORDER = GRB>
535class WS2812BMiniV3Controller : public fl::ClocklessControllerImpl<DATA_PIN, fl::TIMING_WS2812B_MINI_V3, RGB_ORDER> {};
536
540template <int DATA_PIN, EOrder RGB_ORDER = GRB>
541class WS2812BV5Controller : public fl::ClocklessControllerImpl<DATA_PIN, fl::TIMING_WS2812B_V5, RGB_ORDER> {};
542
546template <int DATA_PIN, EOrder RGB_ORDER = GRB>
547class WS2811Controller400Khz : public fl::ClocklessControllerImpl<DATA_PIN, fl::TIMING_WS2811_400KHZ, RGB_ORDER> {};
548
551template <int DATA_PIN, EOrder RGB_ORDER = GRB>
552class WS2815Controller : public fl::ClocklessControllerImpl<DATA_PIN, fl::TIMING_WS2815, RGB_ORDER> {};
553
556template <int DATA_PIN, EOrder RGB_ORDER = RGB>
557class DP1903Controller800Khz : public fl::ClocklessControllerImpl<DATA_PIN, fl::TIMING_DP1903_800KHZ, RGB_ORDER> {};
558
561template <int DATA_PIN, EOrder RGB_ORDER = RGB>
562class DP1903Controller400Khz : public fl::ClocklessControllerImpl<DATA_PIN, fl::TIMING_DP1903_400KHZ, RGB_ORDER> {};
563
566template <int DATA_PIN, EOrder RGB_ORDER = RGB>
567class TM1803Controller400Khz : public fl::ClocklessControllerImpl<DATA_PIN, fl::TIMING_TM1803_400KHZ, RGB_ORDER> {};
568
575template <int DATA_PIN, EOrder RGB_ORDER = RGB>
576class TM1829Controller800Khz : public fl::ClocklessControllerImpl<DATA_PIN, fl::TIMING_TM1829_800KHZ, RGB_ORDER, 0, true, 500> {};
577
581template <int DATA_PIN, EOrder RGB_ORDER = RGB>
582class TM1829Controller1600Khz : public fl::ClocklessControllerImpl<DATA_PIN, fl::TIMING_TM1829_1600KHZ, RGB_ORDER, 0, true, 500> {};
583
586template <int DATA_PIN, EOrder RGB_ORDER = RGB>
587class LPD1886Controller1250Khz : public fl::ClocklessControllerImpl<DATA_PIN, fl::TIMING_LPD1886_1250KHZ, RGB_ORDER> {};
588
591template <int DATA_PIN, EOrder RGB_ORDER = RGB>
592class LPD1886Controller1250Khz_8bit : public fl::ClocklessControllerImpl<DATA_PIN, fl::TIMING_LPD1886_1250KHZ, RGB_ORDER> {};
593
594
597template <int DATA_PIN, EOrder RGB_ORDER = RGB>
598class SK6822Controller : public fl::ClocklessControllerImpl<DATA_PIN, fl::TIMING_SK6822, RGB_ORDER> {};
599
602template <int DATA_PIN, EOrder RGB_ORDER = RGB>
603class SK6812Controller : public fl::ClocklessControllerImpl<DATA_PIN, fl::TIMING_SK6812, RGB_ORDER> {};
604
608template <int DATA_PIN, EOrder RGB_ORDER = GRB>
609class LC8816EController
610 : public fl::ClocklessControllerImpl<DATA_PIN, fl::TIMING_LC8816E,
611 RGB_ORDER, 0, false,
612 fl::TIMING_LC8816E::RESET> {
613 using Base = fl::ClocklessControllerImpl<
614 DATA_PIN, fl::TIMING_LC8816E, RGB_ORDER, 0, false,
616
617 public:
618 LC8816EController() FL_NO_EXCEPT {
619 this->setFixedRgbw(fl::RgbwDefault::value());
620 }
621
622 void init() FL_NO_EXCEPT override {
623 Base::init();
624 }
625};
626
629template <int DATA_PIN, EOrder RGB_ORDER = RGB>
630class SM16703Controller : public fl::ClocklessControllerImpl<DATA_PIN, fl::TIMING_SM16703, RGB_ORDER> {};
631
634template <int DATA_PIN, EOrder RGB_ORDER = RGB>
635class GS1903Controller : public fl::ClocklessControllerImpl<DATA_PIN, fl::TIMING_GS1903, RGB_ORDER> {};
636
639template <int DATA_PIN, EOrder RGB_ORDER = RGB>
640class PL9823Controller : public fl::ClocklessControllerImpl<DATA_PIN, fl::TIMING_PL9823, RGB_ORDER> {};
641
645template <int DATA_PIN, EOrder RGB_ORDER = RGB>
646class UCS1912Controller : public fl::ClocklessControllerImpl<DATA_PIN, fl::TIMING_UCS1912, RGB_ORDER> {};
647
652template <int DATA_PIN, EOrder RGB_ORDER = RGB>
653class SM16824EController : public fl::ClocklessControllerImpl<DATA_PIN, fl::TIMING_SM16824E, RGB_ORDER> {};
654
657
658
659// WS2816 - is an emulated controller that emits 48 bit pixels by forwarding
660// them to a platform specific WS2812 controller. The WS2812 controller
661// has to output twice as many 24 bit pixels.
662template <int DATA_PIN, EOrder RGB_ORDER = GRB>
663class WS2816Controller
664 : public CPixelLEDController<RGB_ORDER,
665 WS2812Controller800Khz<DATA_PIN, RGB>::LANES_VALUE,
666 WS2812Controller800Khz<DATA_PIN, RGB>::MASK_VALUE> {
667
668public:
669
670 // ControllerT is a helper class. It subclasses the device controller class
671 // and has three methods to call the three protected methods we use.
672 // This is janky, but redeclaring public methods protected in a derived class
673 // is janky, too.
674
675 // N.B., byte order must be RGB.
676 typedef WS2812Controller800Khz<DATA_PIN, RGB> ControllerBaseT;
677 class ControllerT : public ControllerBaseT {
678 friend class WS2816Controller<DATA_PIN, RGB_ORDER>;
679 void *callBeginShowLeds(int size) FL_NO_EXCEPT { return ControllerBaseT::beginShowLeds(size); }
680 void callShow(CRGB *data, int nLeds, fl::u8 brightness) FL_NO_EXCEPT {
681 ControllerBaseT::show(data, nLeds, brightness);
682 }
683 void callEndShowLeds(void *data) FL_NO_EXCEPT { ControllerBaseT::endShowLeds(data); }
684 };
685
686 static const int LANES = ControllerT::LANES_VALUE;
687 static const fl::u32 MASK = ControllerT::MASK_VALUE;
688
689 WS2816Controller() FL_NO_EXCEPT {}
690 ~WS2816Controller() {
691 mController.setLeds(nullptr, 0);
692 }
693
695 mController.setEnabled(true);
696 void *result = mController.callBeginShowLeds(2 * size);
697 mController.setEnabled(false);
698 return result;
699 }
700
702 mController.setEnabled(true);
703 mController.callEndShowLeds(data);
704 mController.setEnabled(false);
705 }
706
707 virtual void showPixels(PixelController<RGB_ORDER, LANES, MASK> &pixels) FL_NO_EXCEPT override {
708 // Ensure buffer is large enough
709 ensureBuffer(pixels.size());
710
711 // Create PixelIterator from PixelController (WS2816 is RGB-only, no W channel)
712 fl::PixelIterator pixel_iter = pixels.as_iterator(fl::RgbwInvalid::value());
713
714 // Create 16-bit RGB iterator range (handles RGB reordering, scaling, brightness)
715 auto rgb16_range = fl::makeScaledPixelRangeRGB16(&pixel_iter);
716
717 // Encode 16-bit RGB pixels to dual 8-bit CRGB format
718 fl::encodeWS2816(rgb16_range.first, rgb16_range.second, mData.get());
719
720 // Ensure device controller won't modify color values
721 mController.setCorrection(CRGB(255, 255, 255));
722 mController.setTemperature(CRGB(255, 255, 255));
723 mController.setDither(DISABLE_DITHER);
724
725 // Output the data stream
726 mController.setEnabled(true);
727 mController.callShow(mData.get(), 2 * pixels.size(), 255);
728 mController.setEnabled(false);
729 }
730
731private:
732 void init() FL_NO_EXCEPT override {
733 mController.init();
734 mController.setEnabled(false);
735 }
736
737 void ensureBuffer(int size_8bit) FL_NO_EXCEPT {
738 int size_16bit = 2 * size_8bit;
739 if (mController.size() != size_16bit) {
740
741 auto new_leds = fl::make_unique<CRGB[]>(size_16bit);
742 mData = fl::move(new_leds);
743 mController.setLeds(mData.get(), size_16bit);
744 }
745 }
746
747 fl::unique_ptr<CRGB[]> mData;
748 ControllerT mController;
749};
750
751
752#endif
753
764
765#if defined(FL_IS_SILABS)
766
767#include "platforms/arm/mgm240/clockless_ezws2812_gpio.h" // ok platform headers
768
780template<fl::u8 DATA_PIN, EOrder RGB_ORDER = GRB>
781using EZWS2812_GPIO = fl::ClocklessController_ezWS2812_GPIO_Auto<DATA_PIN, RGB_ORDER>;
782
783#ifdef FASTLED_USES_EZWS2812_SPI
784
785#include "platforms/arm/mgm240/clockless_ezws2812_spi.h" // ok platform headers
786#include "fl/stl/noexcept.h"
787
805template<EOrder RGB_ORDER = GRB>
806using EZWS2812_SPI = fl::ClocklessController_ezWS2812_SPI<RGB_ORDER>;
807
808#endif // FASTLED_USES_EZWS2812_SPI
809
810#endif // ARDUINO_ARCH_SILABS
811
813
fl::UISlider brightness("Brightness", BRIGHTNESS, 0, 255)
#define DATA_PIN
Definition ClientReal.h:82
#define RGB_ORDER
WS2812< DATA_PIN, RGB > ControllerT
Rgbw rgbw
void mark() FL_NO_EXCEPT
Reset the timestamp that marks the start of the wait period.
void wait() FL_NO_EXCEPT
Blocking delay until WAIT time since mark() has passed.
Class to ensure that a minimum amount of time has kicked since the last time run - and delay if not e...
virtual void showPixels(PixelController< RGB_ORDER, LANES, MASK > &pixels) FL_NO_EXCEPT=0
Send the LED data to the strip.
Template extension of the CLEDController class.
CLEDController & setRgbw(const Rgbw &arg=RgbwDefault::value()) FL_NO_EXCEPT
VIRTUAL_IF_NOT_AVR void * beginShowLeds(int size) 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.
VIRTUAL_IF_NOT_AVR void endShowLeds(void *data) FL_NO_EXCEPT
Rgbw getRgbw() const FL_NO_EXCEPT
virtual void init() FL_NO_EXCEPT=0
Initialize the LED controller.
#define VIRTUAL_IF_NOT_AVR
#define FL_DISABLE_WARNING_PUSH
#define FL_DISABLE_WARNING_POP
#define OVERRIDE_IF_NOT_AVR
#define FL_DISABLE_WARNING_SUBOBJECT_LINKAGE
Legacy header.
#define DISABLE_DITHER
Disable dithering.
Definition dither_mode.h:14
fl::EOrder EOrder
Definition eorder.h:12
constexpr EOrder GRB
Definition eorder.h:19
constexpr EOrder RGB
Definition eorder.h:17
Defines color channel ordering enumerations.
Declares functions for five-bit gamma correction.
virtual void showPixels(PixelController< RGB_ORDER, LANES, MASK > &pixels) FL_NO_EXCEPT override
Main rendering function that converts RGB to RGBW and shows pixels.
Definition chipsets.h:245
fl::i32 mNumRGBLeds
Number of RGB LEDs in the original array.
Definition chipsets.h:307
~RGBWEmulatedController()=default
Destructor - cleans up the internal RGBW buffer.
FL_STATIC_ASSERT(RGB==CONTROLLER::RGB_ORDER_VALUE, "The delegated controller MUST NOT do reordering")
void * callBeginShowLeds(int size) FL_NO_EXCEPT
Definition chipsets.h:207
VIRTUAL_IF_NOT_AVR void endShowLeds(void *data) FL_NO_EXCEPT OVERRIDE_IF_NOT_AVR
Definition chipsets.h:234
VIRTUAL_IF_NOT_AVR void * beginShowLeds(int size) FL_NO_EXCEPT OVERRIDE_IF_NOT_AVR
Definition chipsets.h:230
ControllerT mController
The underlying RGB controller instance.
Definition chipsets.h:309
fl::unique_ptr< CRGB[]> mRGBWPixels
Internal buffer for packed RGBW data.
Definition chipsets.h:306
static const int LANES
Definition chipsets.h:215
void ensureBuffer(fl::i32 num_leds) FL_NO_EXCEPT
Ensures the internal RGBW buffer is large enough for the LED count.
Definition chipsets.h:288
RGBWEmulatedController(const Rgbw &rgbw=RgbwDefault()) FL_NO_EXCEPT
Constructor with optional RGBW configuration.
Definition chipsets.h:223
fl::i32 mNumRGBWLeds
Number of RGBW pixels the buffer can hold.
Definition chipsets.h:308
void init() FL_NO_EXCEPT override
Initialize the controller and disable the base controller.
Definition chipsets.h:279
static const fl::u32 MASK
Definition chipsets.h:216
void callShow(CRGB *data, int nLeds, fl::u8 brightness) FL_NO_EXCEPT
Definition chipsets.h:208
void callEndShowLeds(void *data) FL_NO_EXCEPT
Definition chipsets.h:211
CONTROLLER ControllerBaseT
Definition chipsets.h:204
fl::CRGB CRGB
Definition crgb.h:25
Centralized LED chipset timing definitions with nanosecond precision.
MY9221 12-channel LED driver controller.
constexpr remove_reference< T >::type && move(T &&t) FL_NO_EXCEPT
Definition move.h:30
fl::enable_if<!fl::is_array< T >::value, unique_ptr< T > >::type make_unique(Args &&... args) FL_NO_EXCEPT
Definition unique_ptr.h:263
unsigned char u8
Definition stdint.h:131
void encodeWS2816(InputIterator first, InputIterator last, OutputIterator out) FL_NO_EXCEPT
Encode 16-bit RGB pixel data into dual 8-bit RGB format for WS2816.
Definition ws2816.h:62
UCS7604ControllerT< DATA_PIN, RGB_ORDER, fl::UCS7604Mode::UCS7604_MODE_16BIT_800KHZ, fl::TIMING_UCS7604_800KHZ, CLOCKLESS_CONTROLLER > UCS7604Controller16bitT
Definition ucs7604.h:195
void init(Context &ctx, int w, int h) FL_NO_EXCEPT
Definition engine.h:133
pair< detail::ScaledPixelIteratorRGB16, detail::ScaledPixelIteratorRGB16 > makeScaledPixelRangeRGB16(PixelIterator *pixels) FL_NO_EXCEPT
Create 16-bit RGB input iterator range from PixelIterator.
expected< T, E > result
Alias for expected (Rust-style naming)
Definition result.h:31
UCS7604ControllerT< DATA_PIN, RGB_ORDER, fl::UCS7604Mode::UCS7604_MODE_8BIT_800KHZ, fl::TIMING_UCS7604_800KHZ, CLOCKLESS_CONTROLLER > UCS7604Controller8bitT
Definition ucs7604.h:192
To * bit_cast_ptr(void *storage) FL_NO_EXCEPT
Definition bit_cast.h:60
UCS7604ControllerT< DATA_PIN, RGB_ORDER, fl::UCS7604Mode::UCS7604_MODE_16BIT_1600KHZ, fl::TIMING_UCS7604_1600KHZ, CLOCKLESS_CONTROLLER > UCS7604Controller16bit1600T
Definition ucs7604.h:198
Legacy header.
Includes defintions for RGB and HSV pixels.
#define FL_NO_EXCEPT
Portable compile-time assertion wrapper.
FASTLED_FORCE_INLINE bool has(int n) FL_NO_EXCEPT
Do we have n pixels left to process?
FASTLED_FORCE_INLINE void stepDithering() FL_NO_EXCEPT
Step the dithering forward - creates triangular wave that toggles between pixels.
FASTLED_FORCE_INLINE fl::u8 loadAndScale1(int lane, fl::u8 scale) FL_NO_EXCEPT
non-template alias of loadAndScale<1>()
FASTLED_FORCE_INLINE void advanceData() FL_NO_EXCEPT
Advance the data pointer forward, adjust position counter.
FASTLED_FORCE_INLINE fl::u8 loadAndScale0(int lane, fl::u8 scale) FL_NO_EXCEPT
non-template alias of loadAndScale<0>()
FASTLED_FORCE_INLINE fl::u8 loadAndScale2(int lane, fl::u8 scale) FL_NO_EXCEPT
non-template alias of loadAndScale<2>()
Pixel controller class.
static u32 size_as_rgb(u32 num_of_rgbw_pixels) FL_NO_EXCEPT
Definition rgbw.h:262
static Rgbw value() FL_NO_EXCEPT
Definition rgbw.h:290
static Rgbw value() FL_NO_EXCEPT
Definition rgbw.h:279
#define Serial
Definition serial.h:309
UCS7604 LED chipset controller implementation for FastLED.
WS2816 encoder - converts 16-bit RGB pixels to dual 8-bit RGB format.