FastLED 3.9.15
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
54// Platform-specific clockless timing configuration
55//
56// IMPORTANT: All platforms use nanosecond-based timing at the API level.
57// Chipset timing values (T1, T2, T3) are specified in nanoseconds (e.g., T1=250ns, T2=625ns, T3=375ns)
58//
59// Platforms that need cycle-based timing internally (e.g., AVR, ARM, ESP8266) perform
60// nanosecond-to-cycle conversion within their clockless driver implementation using F_CPU or equivalent.
61//
62// Platform-specific clockless drivers are defined in:
63// - ESP32/ESP8266: platforms/esp/clockless.h
64// - All ARM platforms: led_sysdefs_arm_*.h + platform-specific clockless headers
65// - AVR platforms: led_sysdefs_avr.h + platforms/avr/clockless_*.h
66// - Other platforms: respective led_sysdefs_*.h files
67
68// ============================================================================
69// PLATFORM-SPECIFIC SPECIALIZED CONTROLLERS (Bottom Includes)
70// ============================================================================
71// The includes below MUST be at this point in the file because:
72//
73// 1. C++ templates require full definition in headers (no .cpp separation)
74// 2. Base templates and type definitions (above) must be defined BEFORE
75// platform-specific specializations (below) can see and use them
76// 3. Platform specializations need to instantiate/specialize the base templates
77//
78// This is intentional C++ template architecture, not a code smell or circular
79// dependency. Template-heavy libraries like FastLED naturally have includes at
80// the bottom to support platform-specific specializations.
81//
82// Example: WS2812 is heavily optimized per-platform because it's the most
83// popular chipset. Each platform provides specialized implementations that
84// fully replace the default template instantiation.
85// ============================================================================
86
87#include "platforms/chipsets_specialized_ws2812.h"
88
89#if defined(ARDUINO) && (defined(SoftwareSerial_h) || defined(__SoftwareSerial_h))
90// IWYU pragma: begin_keep
91#include <SoftwareSerial.h>
92// IWYU pragma: end_keep
93#endif
94
97
98
99
104
105#if defined(ARDUINO) && (defined(SoftwareSerial_h) || defined(__SoftwareSerial_h))
106
107#define HAS_PIXIE
108
109
113template<fl::u8 DATA_PIN, EOrder RGB_ORDER = RGB>
114class PixieController : public CPixelLEDController<RGB_ORDER> {
115 SoftwareSerial Serial;
116 CMinWait<2000> mWait;
117
118public:
119 PixieController() : Serial(-1, DATA_PIN) {}
120
121protected:
123 virtual void init() {
124 Serial.begin(115200);
125 mWait.mark();
126 }
127
129 virtual void showPixels(PixelController<RGB_ORDER> & pixels) {
130 mWait.wait();
131 while(pixels.has(1)) {
132 fl::u8 r = pixels.loadAndScale0();
133 Serial.write(r);
134 fl::u8 g = pixels.loadAndScale1();
135 Serial.write(g);
136 fl::u8 b = pixels.loadAndScale2();
137 Serial.write(b);
138 pixels.advanceData();
139 pixels.stepDithering();
140 }
141 mWait.mark();
142 }
143
144};
145
146// template<SoftwareSerial & STREAM, EOrder RGB_ORDER = RGB>
147// class PixieController : public PixieBaseController<STREAM, RGB_ORDER> {
148// public:
149// virtual void init() {
150// STREAM.begin(115200);
151// }
152// };
153
154#endif
155#endif
156
188
189
190template <
191 typename CONTROLLER,
192 EOrder RGB_ORDER = GRB> // Default on WS2812>
194 : public CPixelLEDController<RGB_ORDER, CONTROLLER::LANES_VALUE,
195 CONTROLLER::MASK_VALUE> {
196 public:
197 // ControllerT is a helper class. It subclasses the device controller class
198 // and has three methods to call the three protected methods we use.
199 // This is janky, but redeclaring public methods protected in a derived class
200 // is janky, too.
201
202 // N.B., byte order must be RGB.
203 typedef CONTROLLER ControllerBaseT;
204 class ControllerT : public CONTROLLER {
205 friend class RGBWEmulatedController<CONTROLLER, RGB_ORDER>;
206 void *callBeginShowLeds(int size) { return ControllerBaseT::beginShowLeds(size); }
207 void callShow(CRGB *data, int nLeds, fl::u8 brightness) {
208 ControllerBaseT::show(data, nLeds, brightness);
209 }
210 void callEndShowLeds(void *data) { ControllerBaseT::endShowLeds(data); }
211 };
212
213
214 static const int LANES = CONTROLLER::LANES_VALUE;
215 static const fl::u32 MASK = CONTROLLER::MASK_VALUE;
216
217 // The delegated controller must do no reordering.
218 FL_STATIC_ASSERT(RGB == CONTROLLER::RGB_ORDER_VALUE, "The delegated controller MUST NOT do reordering");
219
223 this->setRgbw(rgbw);
224 };
225
228
229 virtual void *beginShowLeds(int size) override {
230 return mController.callBeginShowLeds(Rgbw::size_as_rgb(size));
231 }
232
233 virtual void endShowLeds(void *data) override {
234 return mController.callEndShowLeds(data);
235 }
236
245 // Ensure buffer is large enough
246 ensureBuffer(pixels.size());
247 Rgbw rgbw = this->getRgbw();
249 while (pixels.has(1)) {
250 pixels.stepDithering();
251 pixels.loadAndScaleRGBW(rgbw, data, data + 1, data + 2, data + 3);
252 data += 4;
253 pixels.advanceData();
254 }
255
256 // Force the device controller to a state where it passes data through
257 // unmodified: color correction, color temperature, dither, and brightness
258 // (passed as an argument to show()). Temporarily enable the controller,
259 // show the LEDs, and disable it again.
260 //
261 // The device controller is in the global controller list, so if we
262 // don't keep it disabled, it will refresh again with unknown brightness,
263 // temperature, etc.
264
265 mController.setCorrection(CRGB(255, 255, 255));
266 mController.setTemperature(CRGB(255, 255, 255));
267 mController.setDither(DISABLE_DITHER);
268
269 mController.setEnabled(true);
270 mController.callShow(mRGBWPixels.get(), Rgbw::size_as_rgb(pixels.size()), 255);
271 mController.setEnabled(false);
272 }
273
274 private:
278 void init() override {
279 mController.init();
280 mController.setEnabled(false);
281 }
282
287 void ensureBuffer(fl::i32 num_leds) {
288 if (num_leds != mNumRGBLeds) {
289 mNumRGBLeds = num_leds;
290 // The delegate controller expects the raw pixel byte data in multiples of 3.
291 // In the case of src data not a multiple of 3, then we need to
292 // add pad bytes so that the delegate controller doesn't walk off the end
293 // of the array and invoke a buffer overflow panic.
294 fl::u32 new_size = Rgbw::size_as_rgb(num_leds);
295 mRGBWPixels.reset(new CRGB[new_size]); // ok bare allocation (array new)
296 // showPixels may never clear the last two pixels.
297 for (fl::u32 i = 0; i < new_size; i++) {
298 mRGBWPixels[i] = CRGB(0, 0, 0);
299 }
300
301 mController.setLeds(mRGBWPixels.get(), new_size);
302 }
303 }
304
306 fl::i32 mNumRGBLeds = 0;
307 fl::i32 mNumRGBWLeds = 0;
309};
310
314
322
323
324
326//
327// Clockless template instantiations - see clockless.h for how the timing values are used
328//
329
330#ifdef FL_CLOCKLESS_CONTROLLER_DEFINED
355
356// Allow clock that clockless controller is based on to have different
357// frequency than the CPU.
358#if !defined(CLOCKLESS_FREQUENCY)
359 #define CLOCKLESS_FREQUENCY F_CPU
360#endif
361
362// We want to force all avr's to use the Trinket controller when running at 8Mhz, because even the 328's at 8Mhz
363// need the more tightly defined timeframes.
364// Suppress -Wsubobject-linkage warning for controller template instantiations.
365// In C++11/14, constexpr variables have internal linkage, which causes the compiler
366// to warn when they are used in base classes of externally-linked templates. The macro
367// FL_INLINE_CONSTEXPR adds explicit 'inline' in C++17+ to resolve this, but for C++11
368// compatibility we suppress the warning here.
371
372
373
374
375// Legacy macro for nanoseconds to clock cycles conversion
376// This is no longer used by the core API but kept for backward compatibility
377#define FL_NANOSECONDS_TO_CLOCK_CYCLES(_NS) (((_NS * ((CLOCKLESS_FREQUENCY / 1000000L)) + 999)) / 1000)
378
379
380//
381// Given datasheet timing values T0H, T0L, T1H, T1L (in nanoseconds):
382//
383// duration = max(T0H + T0L, T1H + T1L) # Maximum cycle time
384// T1 = T0H # High time for '0' bit
385// T2 = T1H - T0H # Additional time for '1' bit
386// T3 = duration - T1H # Tail time after '1' bit
387//
388// Example (WS2812B with T0H=400, T0L=850, T1H=850, T1L=400):
389// duration = 1250, T1 = 400, T2 = 450, T3 = 400
390//
391// For interactive conversion or validation, use: uv run ci/tools/led_timing_conversions.py
392// For automated testing of all chipsets: uv run ci/test_led_timing_conversion.py
393// For C++ check out
394// * converter: src/fl/clockless/timing_conversion.h
395// * tests: tests/fl/clockless/timing_conversion.cpp
396
397
400template <int DATA_PIN, EOrder RGB_ORDER = RGB>
401class GE8822Controller800Khz : public fl::ClocklessControllerImpl<DATA_PIN, fl::TIMING_GE8822_800KHZ, RGB_ORDER, 4, false> {};
402
405template <int DATA_PIN, EOrder RGB_ORDER = RGB>
406class GW6205Controller400Khz : public fl::ClocklessControllerImpl<DATA_PIN, fl::TIMING_GW6205_400KHZ, RGB_ORDER, 4, false> {};
407
410template <int DATA_PIN, EOrder RGB_ORDER = RGB>
411class GW6205Controller800Khz : public fl::ClocklessControllerImpl<DATA_PIN, fl::TIMING_GW6205_800KHZ, RGB_ORDER> {};
412
415template <int DATA_PIN, EOrder RGB_ORDER = RGB>
416class UCS1903Controller400Khz : public fl::ClocklessControllerImpl<DATA_PIN, fl::TIMING_UCS1903_400KHZ, RGB_ORDER> {};
417
420template <int DATA_PIN, EOrder RGB_ORDER = RGB>
421class UCS1903BController800Khz : public fl::ClocklessControllerImpl<DATA_PIN, fl::TIMING_UCS1903B_800KHZ, RGB_ORDER> {};
422
425template <int DATA_PIN, EOrder RGB_ORDER = RGB>
426class UCS1904Controller800Khz : public fl::ClocklessControllerImpl<DATA_PIN, fl::TIMING_UCS1904_800KHZ, RGB_ORDER> {};
427
430template <int DATA_PIN, EOrder RGB_ORDER = RGB>
431class UCS2903Controller : public fl::ClocklessControllerImpl<DATA_PIN, fl::TIMING_UCS2903, RGB_ORDER> {};
432
433// Template wrapper to adapt ClocklessControllerImpl (6-param template alias)
434// to the 3-param template template parameter expected by UCS7604ControllerT
435namespace {
436 template<int DATA_PIN, typename TIMING, EOrder RGB_ORDER>
437 class ClocklessControllerWrapper : public fl::ClocklessControllerImpl<DATA_PIN, TIMING, RGB_ORDER> {};
438}
439
442template <int DATA_PIN, EOrder RGB_ORDER = RGB>
444
447template <int DATA_PIN, EOrder RGB_ORDER = RGB>
449
452template <int DATA_PIN, EOrder RGB_ORDER = RGB>
454
457template <int DATA_PIN, EOrder RGB_ORDER = RGB>
458class TM1809Controller800Khz : public fl::ClocklessControllerImpl<DATA_PIN, fl::TIMING_TM1809_800KHZ, RGB_ORDER> {};
459
463template <int DATA_PIN, EOrder RGB_ORDER = GRB>
464class WS2811Controller800Khz : public fl::ClocklessControllerImpl<DATA_PIN, fl::TIMING_WS2811_800KHZ_LEGACY, RGB_ORDER> {};
465
468template <int DATA_PIN, EOrder RGB_ORDER = GRB>
469class WS2813Controller : public fl::ClocklessControllerImpl<DATA_PIN, fl::TIMING_WS2813, RGB_ORDER> {};
470
475#if !FASTLED_WS2812_HAS_SPECIAL_DRIVER
476template <int DATA_PIN, EOrder RGB_ORDER = GRB>
477class WS2812Controller800Khz : public fl::ClocklessControllerImpl<DATA_PIN, fl::TIMING_WS2812_800KHZ, RGB_ORDER> {};
478#endif
479
483template <int DATA_PIN, EOrder RGB_ORDER = GRB>
484class WS2812BMiniV3Controller : public fl::ClocklessControllerImpl<DATA_PIN, fl::TIMING_WS2812B_MINI_V3, RGB_ORDER> {};
485
489template <int DATA_PIN, EOrder RGB_ORDER = GRB>
490class WS2812BV5Controller : public fl::ClocklessControllerImpl<DATA_PIN, fl::TIMING_WS2812B_V5, RGB_ORDER> {};
491
495template <int DATA_PIN, EOrder RGB_ORDER = GRB>
496class WS2811Controller400Khz : public fl::ClocklessControllerImpl<DATA_PIN, fl::TIMING_WS2811_400KHZ, RGB_ORDER> {};
497
500template <int DATA_PIN, EOrder RGB_ORDER = GRB>
501class WS2815Controller : public fl::ClocklessControllerImpl<DATA_PIN, fl::TIMING_WS2815, RGB_ORDER> {};
502
505template <int DATA_PIN, EOrder RGB_ORDER = RGB>
506class DP1903Controller800Khz : public fl::ClocklessControllerImpl<DATA_PIN, fl::TIMING_DP1903_800KHZ, RGB_ORDER> {};
507
510template <int DATA_PIN, EOrder RGB_ORDER = RGB>
511class DP1903Controller400Khz : public fl::ClocklessControllerImpl<DATA_PIN, fl::TIMING_DP1903_400KHZ, RGB_ORDER> {};
512
515template <int DATA_PIN, EOrder RGB_ORDER = RGB>
516class TM1803Controller400Khz : public fl::ClocklessControllerImpl<DATA_PIN, fl::TIMING_TM1803_400KHZ, RGB_ORDER> {};
517
520template <int DATA_PIN, EOrder RGB_ORDER = RGB>
521class TM1829Controller800Khz : public fl::ClocklessControllerImpl<DATA_PIN, fl::TIMING_TM1829_800KHZ, RGB_ORDER> {};
522
525template <int DATA_PIN, EOrder RGB_ORDER = RGB>
526class TM1829Controller1600Khz : public fl::ClocklessControllerImpl<DATA_PIN, fl::TIMING_TM1829_1600KHZ, RGB_ORDER> {};
527
530template <int DATA_PIN, EOrder RGB_ORDER = RGB>
531class LPD1886Controller1250Khz : public fl::ClocklessControllerImpl<DATA_PIN, fl::TIMING_LPD1886_1250KHZ, RGB_ORDER> {};
532
535template <int DATA_PIN, EOrder RGB_ORDER = RGB>
536class LPD1886Controller1250Khz_8bit : public fl::ClocklessControllerImpl<DATA_PIN, fl::TIMING_LPD1886_1250KHZ, RGB_ORDER> {};
537
538
541template <int DATA_PIN, EOrder RGB_ORDER = RGB>
542class SK6822Controller : public fl::ClocklessControllerImpl<DATA_PIN, fl::TIMING_SK6822, RGB_ORDER> {};
543
546template <int DATA_PIN, EOrder RGB_ORDER = RGB>
547class SK6812Controller : public fl::ClocklessControllerImpl<DATA_PIN, fl::TIMING_SK6812, RGB_ORDER> {};
548
551template <int DATA_PIN, EOrder RGB_ORDER = RGB>
552class SM16703Controller : public fl::ClocklessControllerImpl<DATA_PIN, fl::TIMING_SM16703, RGB_ORDER> {};
553
556template <int DATA_PIN, EOrder RGB_ORDER = RGB>
557class PL9823Controller : public fl::ClocklessControllerImpl<DATA_PIN, fl::TIMING_PL9823, RGB_ORDER> {};
558
562template <int DATA_PIN, EOrder RGB_ORDER = RGB>
563class UCS1912Controller : public fl::ClocklessControllerImpl<DATA_PIN, fl::TIMING_UCS1912, RGB_ORDER> {};
564
569template <int DATA_PIN, EOrder RGB_ORDER = RGB>
570class SM16824EController : public fl::ClocklessControllerImpl<DATA_PIN, fl::TIMING_SM16824E, RGB_ORDER> {};
571
574
575
576// WS2816 - is an emulated controller that emits 48 bit pixels by forwarding
577// them to a platform specific WS2812 controller. The WS2812 controller
578// has to output twice as many 24 bit pixels.
579template <int DATA_PIN, EOrder RGB_ORDER = GRB>
580class WS2816Controller
581 : public CPixelLEDController<RGB_ORDER,
582 WS2812Controller800Khz<DATA_PIN, RGB>::LANES_VALUE,
583 WS2812Controller800Khz<DATA_PIN, RGB>::MASK_VALUE> {
584
585public:
586
587 // ControllerT is a helper class. It subclasses the device controller class
588 // and has three methods to call the three protected methods we use.
589 // This is janky, but redeclaring public methods protected in a derived class
590 // is janky, too.
591
592 // N.B., byte order must be RGB.
593 typedef WS2812Controller800Khz<DATA_PIN, RGB> ControllerBaseT;
594 class ControllerT : public ControllerBaseT {
595 friend class WS2816Controller<DATA_PIN, RGB_ORDER>;
596 void *callBeginShowLeds(int size) { return ControllerBaseT::beginShowLeds(size); }
597 void callShow(CRGB *data, int nLeds, fl::u8 brightness) {
598 ControllerBaseT::show(data, nLeds, brightness);
599 }
600 void callEndShowLeds(void *data) { ControllerBaseT::endShowLeds(data); }
601 };
602
603 static const int LANES = ControllerT::LANES_VALUE;
604 static const fl::u32 MASK = ControllerT::MASK_VALUE;
605
606 WS2816Controller() {}
607 ~WS2816Controller() {
608 mController.setLeds(nullptr, 0);
609 }
610
611 virtual void *beginShowLeds(int size) override {
612 mController.setEnabled(true);
613 void *result = mController.callBeginShowLeds(2 * size);
614 mController.setEnabled(false);
615 return result;
616 }
617
618 virtual void endShowLeds(void *data) override {
619 mController.setEnabled(true);
620 mController.callEndShowLeds(data);
621 mController.setEnabled(false);
622 }
623
624 virtual void showPixels(PixelController<RGB_ORDER, LANES, MASK> &pixels) override {
625 // Ensure buffer is large enough
626 ensureBuffer(pixels.size());
627
628 // Create PixelIterator from PixelController (WS2816 is RGB-only, no W channel)
629 fl::PixelIterator pixel_iter = pixels.as_iterator(fl::Rgbw());
630
631 // Create 16-bit RGB iterator range (handles RGB reordering, scaling, brightness)
632 auto rgb16_range = fl::makeScaledPixelRangeRGB16(&pixel_iter);
633
634 // Encode 16-bit RGB pixels to dual 8-bit CRGB format
635 fl::encodeWS2816(rgb16_range.first, rgb16_range.second, mData.get());
636
637 // Ensure device controller won't modify color values
638 mController.setCorrection(CRGB(255, 255, 255));
639 mController.setTemperature(CRGB(255, 255, 255));
640 mController.setDither(DISABLE_DITHER);
641
642 // Output the data stream
643 mController.setEnabled(true);
644 mController.callShow(mData.get(), 2 * pixels.size(), 255);
645 mController.setEnabled(false);
646 }
647
648private:
649 void init() override {
650 mController.init();
651 mController.setEnabled(false);
652 }
653
654 void ensureBuffer(int size_8bit) {
655 int size_16bit = 2 * size_8bit;
656 if (mController.size() != size_16bit) {
657
658 auto new_leds = fl::make_unique<CRGB[]>(size_16bit);
659 mData = fl::move(new_leds);
660 mController.setLeds(mData.get(), size_16bit);
661 }
662 }
663
664 fl::unique_ptr<CRGB[]> mData;
665 ControllerT mController;
666};
667
668
669#endif
670
681
682#if defined(FL_IS_SILABS)
683
684#include "platforms/arm/mgm240/clockless_ezws2812_gpio.h" // ok platform headers
685
697template<fl::u8 DATA_PIN, EOrder RGB_ORDER = GRB>
698using EZWS2812_GPIO = fl::ClocklessController_ezWS2812_GPIO_Auto<DATA_PIN, RGB_ORDER>;
699
700#ifdef FASTLED_USES_EZWS2812_SPI
701
702#include "platforms/arm/mgm240/clockless_ezws2812_spi.h" // ok platform headers
703
721template<EOrder RGB_ORDER = GRB>
722using EZWS2812_SPI = fl::ClocklessController_ezWS2812_SPI<RGB_ORDER>;
723
724#endif // FASTLED_USES_EZWS2812_SPI
725
726#endif // ARDUINO_ARCH_SILABS
727
729
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()
Reset the timestamp that marks the start of the wait period.
void wait()
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)=0
Send the LED data to the strip.
Template extension of the CLEDController class.
virtual void * beginShowLeds(int size) FL_NOEXCEPT
CLEDController & setRgbw(const Rgbw &arg=RgbwDefault::value()) FL_NOEXCEPT
virtual void endShowLeds(void *data) FL_NOEXCEPT
virtual void init() FL_NOEXCEPT=0
Initialize the LED controller.
Rgbw getRgbw() const FL_NOEXCEPT
virtual int size() const FL_NOEXCEPT
How many LEDs does this controller manage?
Legacy header.
#define DISABLE_DITHER
Disable dithering.
Definition dither_mode.h:10
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.
fl::i32 mNumRGBLeds
Number of RGB LEDs in the original array.
Definition chipsets.h:306
void ensureBuffer(fl::i32 num_leds)
Ensures the internal RGBW buffer is large enough for the LED count.
Definition chipsets.h:287
~RGBWEmulatedController()=default
Destructor - cleans up the internal RGBW buffer.
FL_STATIC_ASSERT(RGB==CONTROLLER::RGB_ORDER_VALUE, "The delegated controller MUST NOT do reordering")
virtual void * beginShowLeds(int size) override
Definition chipsets.h:229
ControllerT mController
The underlying RGB controller instance.
Definition chipsets.h:308
fl::unique_ptr< CRGB[]> mRGBWPixels
Internal buffer for packed RGBW data.
Definition chipsets.h:305
void init() override
Initialize the controller and disable the base controller.
Definition chipsets.h:278
static const int LANES
Definition chipsets.h:214
virtual void endShowLeds(void *data) override
Definition chipsets.h:233
fl::i32 mNumRGBWLeds
Number of RGBW pixels the buffer can hold.
Definition chipsets.h:307
static const fl::u32 MASK
Definition chipsets.h:215
virtual void showPixels(PixelController< RGB_ORDER, LANES, MASK > &pixels) override
Main rendering function that converts RGB to RGBW and shows pixels.
Definition chipsets.h:244
void callShow(CRGB *data, int nLeds, fl::u8 brightness)
Definition chipsets.h:207
RGBWEmulatedController(const Rgbw &rgbw=RgbwDefault())
Constructor with optional RGBW configuration.
Definition chipsets.h:222
CONTROLLER ControllerBaseT
Definition chipsets.h:203
fl::CRGB CRGB
Definition crgb.h:25
Centralized LED chipset timing definitions with nanosecond precision.
pair< detail::ScaledPixelIteratorRGB16, detail::ScaledPixelIteratorRGB16 > makeScaledPixelRangeRGB16(PixelIterator *pixels) FL_NOEXCEPT
Create 16-bit RGB input iterator range from PixelIterator.
constexpr remove_reference< T >::type && move(T &&t) FL_NOEXCEPT
Definition move.h:28
unsigned char u8
Definition stdint.h:131
void encodeWS2816(InputIterator first, InputIterator last, OutputIterator out)
Encode 16-bit RGB pixel data into dual 8-bit RGB format for WS2816.
Definition ws2816.h:61
fl::enable_if<!fl::is_array< T >::value, unique_ptr< T > >::type make_unique(Args &&... args) FL_NOEXCEPT
Definition unique_ptr.h:261
UCS7604ControllerT< DATA_PIN, RGB_ORDER, fl::UCS7604Mode::UCS7604_MODE_16BIT_800KHZ, fl::TIMING_UCS7604_800KHZ, CLOCKLESS_CONTROLLER > UCS7604Controller16bitT
Definition ucs7604.h:191
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:188
To * bit_cast_ptr(void *storage) FL_NOEXCEPT
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:194
Legacy header.
Includes defintions for RGB and HSV pixels.
#define FL_DISABLE_WARNING_PUSH
#define FL_DISABLE_WARNING_POP
#define FL_DISABLE_WARNING_SUBOBJECT_LINKAGE
Portable compile-time assertion wrapper.
FASTLED_FORCE_INLINE int size() const
Get the length of the LED strip.
FASTLED_FORCE_INLINE void loadAndScaleRGBW(Rgbw rgbw, fl::u8 *b0_out, fl::u8 *b1_out, fl::u8 *b2_out, fl::u8 *b3_out)
FASTLED_FORCE_INLINE fl::u8 loadAndScale0(int lane, fl::u8 scale)
non-template alias of loadAndScale<0>()
FASTLED_FORCE_INLINE void advanceData()
Advance the data pointer forward, adjust position counter.
FASTLED_FORCE_INLINE fl::u8 loadAndScale1(int lane, fl::u8 scale)
non-template alias of loadAndScale<1>()
FASTLED_FORCE_INLINE bool has(int n)
Do we have n pixels left to process?
FASTLED_FORCE_INLINE void stepDithering()
Step the dithering forward - creates triangular wave that toggles between pixels.
FASTLED_FORCE_INLINE fl::u8 loadAndScale2(int lane, fl::u8 scale)
non-template alias of loadAndScale<2>()
FASTLED_FORCE_INLINE fl::PixelIterator as_iterator(const Rgbw &rgbw)
Pixel controller class.
static u32 size_as_rgb(u32 num_of_rgbw_pixels) FL_NOEXCEPT
Definition rgbw.h:186
#define Serial
Definition serial.h:304
UCS7604 LED chipset controller implementation for FastLED.
WS2816 encoder - converts 16-bit RGB pixels to dual 8-bit RGB format.