FastLED 3.9.3
Loading...
Searching...
No Matches
chipsets.h
Go to the documentation of this file.
1#ifndef __INC_CHIPSETS_H
2#define __INC_CHIPSETS_H
3
4#include "FastLED.h"
5#include "pixeltypes.h"
6#include "five_bit_hd_gamma.h"
7#include "force_inline.h"
8#include "pixel_iterator.h"
9#include "crgb.h"
10#include "eorder.h"
11
12
13
14#ifndef FASTLED_CLOCKLESS_USES_NANOSECONDS
15 #if defined(FASTLED_TEENSY4)
16 #define FASTLED_CLOCKLESS_USES_NANOSECONDS 1
17 #elif defined(ESP32)
18 #include "platforms/esp/32/led_strip/enabled.h"
19 // RMT 5.1 driver converts from nanoseconds to RMT ticks.
20 #if FASTLED_RMT5
21 #define FASTLED_CLOCKLESS_USES_NANOSECONDS 1
22 #else
23 #define FASTLED_CLOCKLESS_USES_NANOSECONDS 0
24 #endif
25 #else
26 #define FASTLED_CLOCKLESS_USES_NANOSECONDS 0
27 #endif // FASTLED_TEENSY4
28#endif // FASTLED_CLOCKLESS_USES_NANOSECONDS
29
30
33
34
35
40
41#if defined(ARDUINO) //&& defined(SoftwareSerial_h)
42
43
44#if defined(SoftwareSerial_h) || defined(__SoftwareSerial_h)
45#include <SoftwareSerial.h>
46
47#define HAS_PIXIE
48
49FASTLED_NAMESPACE_BEGIN
50
54template<uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
55class PixieController : public CPixelLEDController<RGB_ORDER> {
56 SoftwareSerial Serial;
57 CMinWait<2000> mWait;
58
59public:
60 PixieController() : Serial(-1, DATA_PIN) {}
61
62protected:
64 virtual void init() {
65 Serial.begin(115200);
66 mWait.mark();
67 }
68
70 virtual void showPixels(PixelController<RGB_ORDER> & pixels) {
71 mWait.wait();
72 while(pixels.has(1)) {
73 uint8_t r = pixels.loadAndScale0();
74 Serial.write(r);
75 uint8_t g = pixels.loadAndScale1();
76 Serial.write(g);
77 uint8_t b = pixels.loadAndScale2();
78 Serial.write(b);
79 pixels.advanceData();
80 pixels.stepDithering();
81 }
82 mWait.mark();
83 }
84
85};
86
87// template<SoftwareSerial & STREAM, EOrder RGB_ORDER = RGB>
88// class PixieController : public PixieBaseController<STREAM, RGB_ORDER> {
89// public:
90// virtual void init() {
91// STREAM.begin(115200);
92// }
93// };
94
95FASTLED_NAMESPACE_END
96#endif
97#endif
98
99// Emulution layer to support RGBW leds on RGB controllers. This works by creating
100// a side buffer dedicated for the RGBW data. The RGB data is then converted to RGBW
101// and sent to the delegate controller for rendering as if it were RGB data.
102FASTLED_NAMESPACE_BEGIN
103template <
104 typename CONTROLLER,
105 EOrder RGB_ORDER = GRB> // Default on WS2812>
107 : public CPixelLEDController<RGB_ORDER, CONTROLLER::LANES_VALUE,
108 CONTROLLER::MASK_VALUE> {
109 public:
110 static const int LANES = CONTROLLER::LANES_VALUE;
111 static const uint32_t MASK = CONTROLLER::MASK_VALUE;
112
113 // The delegated controller must do no reordering.
114 static_assert(RGB == CONTROLLER::RGB_ORDER_VALUE, "The delegated controller MUST NOT do reordering");
115
116 RGBWEmulatedController(const Rgbw& rgbw = RgbwDefault()) {
117 this->setRgbw(rgbw);
118 };
119 ~RGBWEmulatedController() { delete[] mRGBWPixels; }
120
122 // Ensure buffer is large enough
123 ensureBuffer(pixels.size());
124 // This version sent down to the real controller.
125 PixelController<RGB, LANES, MASK> pixels_device(pixels);
126 pixels_device.mColorAdjustment.premixed = CRGB(255, 255, 255); // No scaling because we do that.
127 #if FASTLED_HD_COLOR_MIXING
128 pixels_device.mColorAdjustment.color = CRGB(255, 255, 255);
129 pixels_device.mColorAdjustment.brightness = 255;
130 #endif
131 pixels_device.mData = reinterpret_cast<uint8_t *>(mRGBWPixels);
132 pixels_device.mLen = mNumRGBWLeds;
133 pixels_device.mLenRemaining = mNumRGBWLeds;
134 uint8_t *data = reinterpret_cast<uint8_t *>(mRGBWPixels);
135 PixelIterator iterator = pixels.as_iterator(this->getRgbw());
136 while (iterator.has(1)) {
137 pixels.stepDithering();
138 iterator.loadAndScaleRGBW(data, data + 1, data + 2, data + 3);
139 data += 4;
140 iterator.advanceData();
141 }
142 // cast to base class to get around protected/private access issues
143 CPixelLEDController<RGB, LANES, MASK> &base = mController;
144 base.showPixels(pixels_device);
145 }
146
147 private:
148 // Needed by the interface.
149 void init() override {}
150
151 void ensureBuffer(int32_t num_leds) {
152 if (num_leds != mNumRGBLeds) {
153 mNumRGBLeds = num_leds;
154 // The delegate controller expects the raw pixel byte data in multiples of 3.
155 // In the case of src data not a multiple of 3, then we need to
156 // add pad bytes so that the delegate controller doesn't walk off the end
157 // of the array and invoke a buffer overflow panic.
158 mNumRGBWLeds = (num_leds * 4 + 2) / 3; // Round up to nearest multiple of 3
159 size_t extra = mNumRGBWLeds % 3 ? 1 : 0;
160 delete[] mRGBWPixels;
161 mRGBWPixels = new CRGB[mNumRGBWLeds + extra];
162 }
163 }
164
165 CRGB *mRGBWPixels = nullptr;
166 int32_t mNumRGBLeds = 0;
167 int32_t mNumRGBWLeds = 0;
168 CONTROLLER mController; // Real controller.
169};
170
174
176//
177// LPD8806 controller class - takes data/clock/select pin values (N.B. should take an SPI definition?)
178//
180
186template <uint8_t DATA_PIN, uint8_t CLOCK_PIN, EOrder RGB_ORDER = RGB, uint32_t SPI_SPEED = DATA_RATE_MHZ(12) >
187class LPD8806Controller : public CPixelLEDController<RGB_ORDER> {
189
190 class LPD8806_ADJUST {
191 public:
192 // LPD8806 spec wants the high bit of every rgb data byte sent out to be set.
193 FASTLED_FORCE_INLINE static uint8_t adjust(FASTLED_REGISTER uint8_t data) { return ((data>>1) | 0x80) + ((data && (data<254)) & 0x01); }
194 FASTLED_FORCE_INLINE static void postBlock(int len, void* context = NULL) {
195 SPI* pSPI = static_cast<SPI*>(context);
196 pSPI->writeBytesValueRaw(0, ((len*3+63)>>6));
197 }
198
199 };
200
201 SPI mSPI;
202
203public:
205 virtual void init() {
206 mSPI.init();
207 }
208
209protected:
210
212 virtual void showPixels(PixelController<RGB_ORDER> & pixels) {
213 mSPI.template writePixels<0, LPD8806_ADJUST, RGB_ORDER>(pixels, &mSPI);
214 }
215};
216
217
219//
220// WS2801 definition - takes data/clock/select pin values (N.B. should take an SPI definition?)
221//
223
229template <uint8_t DATA_PIN, uint8_t CLOCK_PIN, EOrder RGB_ORDER = RGB, uint32_t SPI_SPEED = DATA_RATE_MHZ(1)>
230class WS2801Controller : public CPixelLEDController<RGB_ORDER> {
232 SPI mSPI;
233 CMinWait<1000> mWaitDelay;
234
235public:
237
239 virtual void init() {
240 mSPI.init();
241 mWaitDelay.mark();
242 }
243
244protected:
245
247 virtual void showPixels(PixelController<RGB_ORDER> & pixels) {
248 mWaitDelay.wait();
249 mSPI.template writePixels<0, DATA_NOP, RGB_ORDER>(pixels, NULL);
250 mWaitDelay.mark();
251 }
252};
253
256template <uint8_t DATA_PIN, uint8_t CLOCK_PIN, EOrder RGB_ORDER = RGB, uint32_t SPI_SPEED = DATA_RATE_MHZ(25)>
257class WS2803Controller : public WS2801Controller<DATA_PIN, CLOCK_PIN, RGB_ORDER, SPI_SPEED> {};
258
267template <uint8_t DATA_PIN, uint8_t CLOCK_PIN, EOrder RGB_ORDER = RGB, uint32_t SPI_SPEED = DATA_RATE_MHZ(12)>
268class LPD6803Controller : public CPixelLEDController<RGB_ORDER> {
270 SPI mSPI;
271
272 void startBoundary() { mSPI.writeByte(0); mSPI.writeByte(0); mSPI.writeByte(0); mSPI.writeByte(0); }
273 void endBoundary(int nLeds) { int nDWords = (nLeds/32); do { mSPI.writeByte(0xFF); mSPI.writeByte(0x00); mSPI.writeByte(0x00); mSPI.writeByte(0x00); } while(nDWords--); }
274
275public:
277
278 virtual void init() {
279 mSPI.init();
280 }
281
282protected:
284 virtual void showPixels(PixelController<RGB_ORDER> & pixels) {
285 mSPI.select();
286
287 startBoundary();
288 while(pixels.has(1)) {
289 FASTLED_REGISTER uint16_t command;
290 command = 0x8000;
291 command |= (pixels.loadAndScale0() & 0xF8) << 7; // red is the high 5 bits
292 command |= (pixels.loadAndScale1() & 0xF8) << 2; // green is the middle 5 bits
293 mSPI.writeByte((command >> 8) & 0xFF);
294 command |= pixels.loadAndScale2() >> 3 ; // blue is the low 5 bits
295 mSPI.writeByte(command & 0xFF);
296
297 pixels.stepDithering();
298 pixels.advanceData();
299 }
300 endBoundary(pixels.size());
301 mSPI.waitFully();
302 mSPI.release();
303 }
304
305};
306
308//
309// APA102 definition - takes data/clock/select pin values (N.B. should take an SPI definition?)
310//
312
318template <
319 uint8_t DATA_PIN, uint8_t CLOCK_PIN,
320 EOrder RGB_ORDER = RGB,
321 // APA102 has a bug where long strip can't handle full speed due to clock degredation.
322 // This only affects long strips, but then again if you have a short strip does 6 mhz actually slow
323 // you down? Probably not. And you can always bump it up for speed. Therefore we are prioritizing
324 // "just works" over "fastest possible" here.
325 // https://www.pjrc.com/why-apa102-leds-have-trouble-at-24-mhz/
326 uint32_t SPI_SPEED = DATA_RATE_MHZ(6),
327 FiveBitGammaCorrectionMode GAMMA_CORRECTION_MODE = kFiveBitGammaCorrectionMode_Null,
328 uint32_t START_FRAME = 0x00000000,
329 uint32_t END_FRAME = 0xFF000000
330>
331class APA102Controller : public CPixelLEDController<RGB_ORDER> {
333 SPI mSPI;
334
335 void startBoundary() {
336 mSPI.writeWord(START_FRAME >> 16);
337 mSPI.writeWord(START_FRAME & 0xFFFF);
338 }
339 void endBoundary(int nLeds) {
340 int nDWords = (nLeds/32);
341 const uint8_t b0 = uint8_t(END_FRAME >> 24 & 0x000000ff);
342 const uint8_t b1 = uint8_t(END_FRAME >> 16 & 0x000000ff);
343 const uint8_t b2 = uint8_t(END_FRAME >> 8 & 0x000000ff);
344 const uint8_t b3 = uint8_t(END_FRAME >> 0 & 0x000000ff);
345 do {
346 mSPI.writeByte(b0);
347 mSPI.writeByte(b1);
348 mSPI.writeByte(b2);
349 mSPI.writeByte(b3);
350 } while(nDWords--);
351 }
352
353 FASTLED_FORCE_INLINE void writeLed(uint8_t brightness, uint8_t b0, uint8_t b1, uint8_t b2) {
354#ifdef FASTLED_SPI_BYTE_ONLY
355 mSPI.writeByte(0xE0 | brightness);
356 mSPI.writeByte(b0);
357 mSPI.writeByte(b1);
358 mSPI.writeByte(b2);
359#else
360 uint16_t b = 0xE000 | (brightness << 8) | (uint16_t)b0;
361 mSPI.writeWord(b);
362 uint16_t w = b1 << 8;
363 w |= b2;
364 mSPI.writeWord(w);
365#endif
366 }
367
368 FASTLED_FORCE_INLINE void write2Bytes(uint8_t b1, uint8_t b2) {
369#ifdef FASTLED_SPI_BYTE_ONLY
370 mSPI.writeByte(b1);
371 mSPI.writeByte(b2);
372#else
373 mSPI.writeWord(uint16_t(b1) << 8 | b2);
374#endif
375 }
376
377public:
379
380 virtual void init() {
381 mSPI.init();
382 }
383
384protected:
386 virtual void showPixels(PixelController<RGB_ORDER> & pixels) {
387 PixelIterator iterator = pixels.as_iterator(this->getRgbw());
388 switch (GAMMA_CORRECTION_MODE) {
389 case kFiveBitGammaCorrectionMode_Null: {
390 showPixelsDefault(iterator);
391 break;
392 }
393 case kFiveBitGammaCorrectionMode_BitShift: {
394 showPixelsGammaBitShift(iterator);
395 break;
396 }
397 }
398 }
399
400private:
401
402 static inline void getGlobalBrightnessAndScalingFactors(
403 PixelIterator& pixels,
404 uint8_t* out_s0, uint8_t* out_s1, uint8_t* out_s2, uint8_t* out_brightness) {
405#if FASTLED_HD_COLOR_MIXING
406 uint8_t brightness;
407 pixels.getHdScale(out_s0, out_s1, out_s2, &brightness);
408 struct Math {
409 static uint16_t map(uint16_t x, uint16_t in_min, uint16_t in_max, uint16_t out_min, uint16_t out_max) {
410 const uint16_t run = in_max - in_min;
411 const uint16_t rise = out_max - out_min;
412 const uint16_t delta = x - in_min;
413 return (delta * rise) / run + out_min;
414 }
415 };
416 *out_brightness = Math::map(brightness, 0, 255, 0, 31);
417 return;
418#else
419 uint8_t s0, s1, s2;
420 pixels.loadAndScaleRGB(&s0, &s1, &s2);
421#if FASTLED_USE_GLOBAL_BRIGHTNESS == 1
422 // This function is pure magic.
423 const uint16_t maxBrightness = 0x1F;
424 uint16_t brightness = ((((uint16_t)max(max(s0, s1), s2) + 1) * maxBrightness - 1) >> 8) + 1;
425 s0 = (maxBrightness * s0 + (brightness >> 1)) / brightness;
426 s1 = (maxBrightness * s1 + (brightness >> 1)) / brightness;
427 s2 = (maxBrightness * s2 + (brightness >> 1)) / brightness;
428#else
429 const uint8_t brightness = 0x1F;
430#endif // FASTLED_USE_GLOBAL_BRIGHTNESS
431 *out_s0 = s0;
432 *out_s1 = s1;
433 *out_s2 = s2;
434 *out_brightness = static_cast<uint8_t>(brightness);
435#endif // FASTLED_HD_COLOR_MIXING
436 }
437
438 // Legacy showPixels implementation.
439 inline void showPixelsDefault(PixelIterator& pixels) {
440 mSPI.select();
441 uint8_t s0, s1, s2, global_brightness;
442 getGlobalBrightnessAndScalingFactors(pixels, &s0, &s1, &s2, &global_brightness);
443 startBoundary();
444 while (pixels.has(1)) {
445 uint8_t c0, c1, c2;
446 pixels.loadAndScaleRGB(&c0, &c1, &c2);
447 writeLed(global_brightness, c0, c1, c2);
448 pixels.stepDithering();
449 pixels.advanceData();
450 }
451 endBoundary(pixels.size());
452
453 mSPI.waitFully();
454 mSPI.release();
455 }
456
457 inline void showPixelsGammaBitShift(PixelIterator& pixels) {
458 mSPI.select();
459 startBoundary();
460 while (pixels.has(1)) {
461 // Load raw uncorrected r,g,b values.
462 uint8_t brightness, c0, c1, c2; // c0-c2 is the RGB data re-ordered for pixel
463 pixels.loadAndScale_APA102_HD(&c0, &c1, &c2, &brightness);
464 writeLed(brightness, c0, c1, c2);
465 pixels.stepDithering();
466 pixels.advanceData();
467 }
468 endBoundary(pixels.size());
469 mSPI.waitFully();
470 mSPI.release();
471 }
472};
473
479template <
480 uint8_t DATA_PIN,
481 uint8_t CLOCK_PIN,
482 EOrder RGB_ORDER = RGB,
483 // APA102 has a bug where long strip can't handle full speed due to clock degredation.
484 // This only affects long strips, but then again if you have a short strip does 6 mhz actually slow
485 // you down? Probably not. And you can always bump it up for speed. Therefore we are prioritizing
486 // "just works" over "fastest possible" here.
487 // https://www.pjrc.com/why-apa102-leds-have-trouble-at-24-mhz/
488 uint32_t SPI_SPEED = DATA_RATE_MHZ(6)
489>
491 DATA_PIN,
492 CLOCK_PIN,
493 RGB_ORDER,
494 SPI_SPEED,
495 kFiveBitGammaCorrectionMode_BitShift,
496 uint32_t(0x00000000),
497 uint32_t(0x00000000)> {
498public:
499 APA102ControllerHD() = default;
500 APA102ControllerHD(const APA102ControllerHD&) = delete;
501};
502
508template <
509 uint8_t DATA_PIN,
510 uint8_t CLOCK_PIN,
511 EOrder RGB_ORDER = RGB,
512 uint32_t SPI_SPEED = DATA_RATE_MHZ(12)
513>
515 DATA_PIN,
516 CLOCK_PIN,
517 RGB_ORDER,
518 SPI_SPEED,
519 kFiveBitGammaCorrectionMode_Null,
520 0x00000000,
521 0x00000000
522> {
523};
524
530template <
531 uint8_t DATA_PIN,
532 uint8_t CLOCK_PIN,
533 EOrder RGB_ORDER = RGB,
534 uint32_t SPI_SPEED = DATA_RATE_MHZ(12)
535>
537 DATA_PIN,
538 CLOCK_PIN,
539 RGB_ORDER,
540 SPI_SPEED,
541 kFiveBitGammaCorrectionMode_BitShift,
542 0x00000000,
543 0x00000000
544> {
545};
546
547
548
550//
551// P9813 definition - takes data/clock/select pin values (N.B. should take an SPI definition?)
552//
554
560template <uint8_t DATA_PIN, uint8_t CLOCK_PIN, EOrder RGB_ORDER = RGB, uint32_t SPI_SPEED = DATA_RATE_MHZ(10)>
561class P9813Controller : public CPixelLEDController<RGB_ORDER> {
563 SPI mSPI;
564
565 void writeBoundary() { mSPI.writeWord(0); mSPI.writeWord(0); }
566
567 FASTLED_FORCE_INLINE void writeLed(uint8_t r, uint8_t g, uint8_t b) {
568 FASTLED_REGISTER uint8_t top = 0xC0 | ((~b & 0xC0) >> 2) | ((~g & 0xC0) >> 4) | ((~r & 0xC0) >> 6);
569 mSPI.writeByte(top); mSPI.writeByte(b); mSPI.writeByte(g); mSPI.writeByte(r);
570 }
571
572public:
573 P9813Controller() {}
574
575 virtual void init() {
576 mSPI.init();
577 }
578
579protected:
581 virtual void showPixels(PixelController<RGB_ORDER> & pixels) {
582 mSPI.select();
583
584 writeBoundary();
585 while(pixels.has(1)) {
586 writeLed(pixels.loadAndScale0(), pixels.loadAndScale1(), pixels.loadAndScale2());
587 pixels.advanceData();
588 pixels.stepDithering();
589 }
590 writeBoundary();
591 mSPI.waitFully();
592
593 mSPI.release();
594 }
595
596};
597
598
600//
601// SM16716 definition - takes data/clock/select pin values (N.B. should take an SPI definition?)
602//
604
610template <uint8_t DATA_PIN, uint8_t CLOCK_PIN, EOrder RGB_ORDER = RGB, uint32_t SPI_SPEED = DATA_RATE_MHZ(16)>
611class SM16716Controller : public CPixelLEDController<RGB_ORDER> {
613 SPI mSPI;
614
615 void writeHeader() {
616 // Write out 50 zeros to the spi line (6 blocks of 8 followed by two single bit writes)
617 mSPI.select();
618 mSPI.template writeBit<0>(0);
619 mSPI.writeByte(0);
620 mSPI.writeByte(0);
621 mSPI.writeByte(0);
622 mSPI.template writeBit<0>(0);
623 mSPI.writeByte(0);
624 mSPI.writeByte(0);
625 mSPI.writeByte(0);
626 mSPI.waitFully();
627 mSPI.release();
628 }
629
630public:
632
633 virtual void init() {
634 mSPI.init();
635 }
636
637protected:
639 virtual void showPixels(PixelController<RGB_ORDER> & pixels) {
640 // Make sure the FLAG_START_BIT flag is set to ensure that an extra 1 bit is sent at the start
641 // of each triplet of bytes for rgb data
642 // writeHeader();
643 mSPI.template writePixels<FLAG_START_BIT, DATA_NOP, RGB_ORDER>(pixels, NULL);
644 writeHeader();
645 }
646
647};
648
650
651
653//
654// Clockless template instantiations - see clockless.h for how the timing values are used
655//
656
657#ifdef FASTLED_HAS_CLOCKLESS
679
680// Allow clock that clockless controller is based on to have different
681// frequency than the CPU.
682#if !defined(CLOCKLESS_FREQUENCY)
683 #define CLOCKLESS_FREQUENCY F_CPU
684#endif
685
686// We want to force all avr's to use the Trinket controller when running at 8Mhz, because even the 328's at 8Mhz
687// need the more tightly defined timeframes.
688#if defined(__LGT8F__) || (CLOCKLESS_FREQUENCY == 8000000 || CLOCKLESS_FREQUENCY == 16000000 || CLOCKLESS_FREQUENCY == 24000000) || defined(FASTLED_DOXYGEN) // || CLOCKLESS_FREQUENCY == 48000000 || CLOCKLESS_FREQUENCY == 96000000) // 125ns/clock
689
692#define FMUL (CLOCKLESS_FREQUENCY/8000000)
693
696template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
697class GE8822Controller800Khz : public ClocklessController<DATA_PIN, 3 * FMUL, 5 * FMUL, 3 * FMUL, RGB_ORDER, 4> {};
698
701template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
702class LPD1886Controller1250Khz : public ClocklessController<DATA_PIN, 2 * FMUL, 3 * FMUL, 2 * FMUL, RGB_ORDER, 4> {};
703
706template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
707class LPD1886Controller1250Khz_8bit : public ClocklessController<DATA_PIN, 2 * FMUL, 3 * FMUL, 2 * FMUL, RGB_ORDER> {};
708
712template <uint8_t DATA_PIN, EOrder RGB_ORDER = GRB>
713class WS2812Controller800Khz : public ClocklessController<DATA_PIN, 2 * FMUL, 5 * FMUL, 3 * FMUL, RGB_ORDER> {};
714
717template <uint8_t DATA_PIN, EOrder RGB_ORDER = GRB>
718class WS2815Controller : public ClocklessController<DATA_PIN, 2 * FMUL, 9 * FMUL, 4 * FMUL, RGB_ORDER> {};
719
722template <uint8_t DATA_PIN, EOrder RGB_ORDER = GRB>
723class WS2811Controller800Khz : public ClocklessController<DATA_PIN, 3 * FMUL, 4 * FMUL, 3 * FMUL, RGB_ORDER> {};
724
727template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
728class DP1903Controller800Khz : public ClocklessController<DATA_PIN, 2 * FMUL, 8 * FMUL, 2 * FMUL, RGB_ORDER> {};
729
732template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
733class DP1903Controller400Khz : public ClocklessController<DATA_PIN, 4 * FMUL, 16 * FMUL, 4 * FMUL, RGB_ORDER> {};
734
737template <uint8_t DATA_PIN, EOrder RGB_ORDER = GRB> //not tested
738class WS2813Controller : public ClocklessController<DATA_PIN, 3 * FMUL, 4 * FMUL, 3 * FMUL, RGB_ORDER> {};
739
742template <uint8_t DATA_PIN, EOrder RGB_ORDER = GRB>
743class WS2811Controller400Khz : public ClocklessController<DATA_PIN, 4 * FMUL, 10 * FMUL, 6 * FMUL, RGB_ORDER> {};
744
747template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
748class SK6822Controller : public ClocklessController<DATA_PIN, 3 * FMUL, 8 * FMUL, 3 * FMUL, RGB_ORDER> {};
749
752template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
753class SM16703Controller : public ClocklessController<DATA_PIN, 3 * FMUL, 4 * FMUL, 3 * FMUL, RGB_ORDER> {};
754
757template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
758class SK6812Controller : public ClocklessController<DATA_PIN, 3 * FMUL, 3 * FMUL, 4 * FMUL, RGB_ORDER> {};
759
762template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
763class UCS1903Controller400Khz : public ClocklessController<DATA_PIN, 4 * FMUL, 12 * FMUL, 4 * FMUL, RGB_ORDER> {};
764
767template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
768class UCS1903BController800Khz : public ClocklessController<DATA_PIN, 2 * FMUL, 4 * FMUL, 4 * FMUL, RGB_ORDER> {};
769
772template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
773class UCS1904Controller800Khz : public ClocklessController<DATA_PIN, 3 * FMUL, 3 * FMUL, 4 * FMUL, RGB_ORDER> {};
774
777template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
778class UCS2903Controller : public ClocklessController<DATA_PIN, 2 * FMUL, 6 * FMUL, 2 * FMUL, RGB_ORDER> {};
779
782template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
783class TM1809Controller800Khz : public ClocklessController<DATA_PIN, 2 * FMUL, 5 * FMUL, 3 * FMUL, RGB_ORDER> {};
784
787template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
788class TM1803Controller400Khz : public ClocklessController<DATA_PIN, 6 * FMUL, 9 * FMUL, 6 * FMUL, RGB_ORDER> {};
789
792template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
793class TM1829Controller800Khz : public ClocklessController<DATA_PIN, 2 * FMUL, 5 * FMUL, 3 * FMUL, RGB_ORDER, 0, true, 500> {};
794
797template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
798class GW6205Controller400Khz : public ClocklessController<DATA_PIN, 6 * FMUL, 7 * FMUL, 6 * FMUL, RGB_ORDER, 4> {};
799
802template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
803class GW6205Controller800Khz : public ClocklessController<DATA_PIN, 2 * FMUL, 4 * FMUL, 4 * FMUL, RGB_ORDER, 4> {};
804
807template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
808class PL9823Controller : public ClocklessController<DATA_PIN, 3 * FMUL, 8 * FMUL, 3 * FMUL, RGB_ORDER> {};
809
810// UCS1912 - Note, never been tested, this is according to the datasheet
811template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
812class UCS1912Controller : public ClocklessController<DATA_PIN, 2 * FMUL, 8 * FMUL, 3 * FMUL, RGB_ORDER> {};
813
814
815#else
816
817// Allow overclocking of the clockless family of leds. 1.2 would be
818// 20% overclocking. In tests WS2812 can be overclocked at 20%, but
819// various manufacturers may be different. This is a global value
820// which is overridable by each supported chipset.
821#ifndef FASTLED_LED_OVERCLOCK
822#define FASTLED_LED_OVERCLOCK 1.0
823#endif
824
825// WS2812 can be overclocked pretty aggressively, however, there are
826// some excellent articles that you should read about WS2812 overclocking
827// and corruption for a large number of LEDs.
828// https://wp.josh.com/2014/05/16/why-you-should-give-your-neopixel-bits-room-to-breathe/
829// https://wp.josh.com/2014/05/13/ws2812-neopixels-are-not-so-finicky-once-you-get-to-know-them/
830#ifndef FASTLED_LED_OVERCLOCK_WS2812
831#define FASTLED_LED_OVERCLOCK_WS2812 FASTLED_LED_OVERCLOCK
832#endif
833
834#ifndef FASTLED_LED_OVERCLOCK_WS2811
835#define FASTLED_LED_OVERCLOCK_WS2811 FASTLED_LED_OVERCLOCK
836#endif
837
838#ifndef FASTLED_LED_OVERCLOCK_WS2813
839#define FASTLED_LED_OVERCLOCK_WS2813 FASTLED_LED_OVERCLOCK
840#endif
841
842#ifndef FASTLED_LED_OVERCLOCK_WS2815
843#define FASTLED_LED_OVERCLOCK_WS2815 FASTLED_LED_OVERCLOCK
844#endif
845
846#ifndef FASTLED_LED_OVERCLOCK_SK6822
847#define FASTLED_LED_OVERCLOCK_SK6822 FASTLED_LED_OVERCLOCK
848#endif
849
850#ifndef FASTLED_LED_OVERCLOCK_SK6812
851#define FASTLED_LED_OVERCLOCK_SK6812 FASTLED_LED_OVERCLOCK
852#endif
853
856#if FASTLED_CLOCKLESS_USES_NANOSECONDS
857// just use raw nanosecond values for the teensy4
858#define C_NS(_NS) _NS
859#else
860#define C_NS(_NS) (((_NS * ((CLOCKLESS_FREQUENCY / 1000000L)) + 999)) / 1000)
861#endif
862
863// Allow overclocking various LED chipsets in the clockless family.
864// Clocked chips like the APA102 don't need this because they allow
865// you to control the clock speed directly.
866#define C_NS_WS2812(_NS) (C_NS(int(_NS / FASTLED_LED_OVERCLOCK_WS2812)))
867#define C_NS_WS2811(_NS) (C_NS(int(_NS / FASTLED_LED_OVERCLOCK_WS2811)))
868#define C_NS_WS2813(_NS) (C_NS(int(_NS / FASTLED_LED_OVERCLOCK_WS2813)))
869#define C_NS_WS2815(_NS) (C_NS(int(_NS / FASTLED_LED_OVERCLOCK_WS2815)))
870#define C_NS_SK6822(_NS) (C_NS(int(_NS / FASTLED_LED_OVERCLOCK_SK6822)))
871#define C_NS_SK6812(_NS) (C_NS(int(_NS / FASTLED_LED_OVERCLOCK_SK6812)))
872
873// At T=0 : the line is raised hi to start a bit
874// At T=T1 : the line is dropped low to transmit a zero bit
875// At T=T1+T2 : the line is dropped low to transmit a one bit
876// At T=T1+T2+T3 : the cycle is concluded (next bit can be sent)
877//
878// Python script to calculate the values for T1, T2, and T3 for FastLED:
879//
880// print("Enter the values of T0H, T0L, T1H, T1L, in nanoseconds: ")
881// T0H = int(input(" T0H: "))
882// T0L = int(input(" T0L: "))
883// T1H = int(input(" T1H: "))
884// T1L = int(input(" T1L: "))
885//
886// duration = max(T0H + T0L, T1H + T1L)
887//
888// print("The max duration of the signal is: ", duration)
889//
890// T1 = T0H
891// T2 = T1H
892// T3 = duration - T0H - T0L
893//
894// print("T1: ", T1)
895// print("T2: ", T2)
896// print("T3: ", T3)
897
898
899// GE8822 - 350ns 660ns 350ns
900template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
901class GE8822Controller800Khz : public ClocklessController<DATA_PIN, C_NS(350), C_NS(660), C_NS(350), RGB_ORDER, 4> {};
902
903// GW6205@400khz - 800ns, 800ns, 800ns
904template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
905class GW6205Controller400Khz : public ClocklessController<DATA_PIN, C_NS(800), C_NS(800), C_NS(800), RGB_ORDER, 4> {};
906
907// GW6205@400khz - 400ns, 400ns, 400ns
908template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
909class GW6205Controller800Khz : public ClocklessController<DATA_PIN, C_NS(400), C_NS(400), C_NS(400), RGB_ORDER, 4> {};
910
911// UCS1903 - 500ns, 1500ns, 500ns
912template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
913class UCS1903Controller400Khz : public ClocklessController<DATA_PIN, C_NS(500), C_NS(1500), C_NS(500), RGB_ORDER> {};
914
915// UCS1903B - 400ns, 450ns, 450ns
916template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
917class UCS1903BController800Khz : public ClocklessController<DATA_PIN, C_NS(400), C_NS(450), C_NS(450), RGB_ORDER> {};
918
919// UCS1904 - 400ns, 400ns, 450ns
920template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
921class UCS1904Controller800Khz : public ClocklessController<DATA_PIN, C_NS(400), C_NS(400), C_NS(450), RGB_ORDER> {};
922
923// UCS2903 - 250ns, 750ns, 250ns
924template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
925class UCS2903Controller : public ClocklessController<DATA_PIN, C_NS(250), C_NS(750), C_NS(250), RGB_ORDER> {};
926
927// TM1809 - 350ns, 350ns, 550ns
928template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
929class TM1809Controller800Khz : public ClocklessController<DATA_PIN, C_NS(350), C_NS(350), C_NS(450), RGB_ORDER> {};
930
931// WS2811 - 320ns, 320ns, 640ns
932template <uint8_t DATA_PIN, EOrder RGB_ORDER = GRB>
933class WS2811Controller800Khz : public ClocklessController<DATA_PIN, C_NS_WS2811(320), C_NS_WS2811(320), C_NS_WS2811(640), RGB_ORDER> {};
934
935// WS2813 - 320ns, 320ns, 640ns
936template <uint8_t DATA_PIN, EOrder RGB_ORDER = GRB>
937class WS2813Controller : public ClocklessController<DATA_PIN, C_NS_WS2813(320), C_NS_WS2813(320), C_NS_WS2813(640), RGB_ORDER> {};
938
939#ifndef FASTLED_WS2812_T1
940#define FASTLED_WS2812_T1 250
941#endif
942
943#ifndef FASTLED_WS2812_T2
944#define FASTLED_WS2812_T2 625
945#endif
946
947#ifndef FASTLED_WS2812_T3
948#define FASTLED_WS2812_T3 375
949#endif
950
951// WS2812 - 250ns, 625ns, 375ns
952template <uint8_t DATA_PIN, EOrder RGB_ORDER = GRB>
953class WS2812Controller800Khz : public ClocklessController<
954 DATA_PIN,
955 C_NS_WS2812(FASTLED_WS2812_T1),
956 C_NS_WS2812(FASTLED_WS2812_T2),
957 C_NS_WS2812(FASTLED_WS2812_T3),
958 RGB_ORDER> {};
959
960// WS2811@400khz - 800ns, 800ns, 900ns
961template <uint8_t DATA_PIN, EOrder RGB_ORDER = GRB>
962class WS2811Controller400Khz : public ClocklessController<DATA_PIN, C_NS_WS2811(800), C_NS_WS2811(800), C_NS_WS2811(900), RGB_ORDER> {};
963
964
965
966
967template <uint8_t DATA_PIN, EOrder RGB_ORDER = GRB>
968class WS2815Controller : public ClocklessController<DATA_PIN, C_NS_WS2815(250), C_NS_WS2815(1090), C_NS_WS2815(550), RGB_ORDER> {};
969
970// 750NS, 750NS, 750NS
971template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
972class TM1803Controller400Khz : public ClocklessController<DATA_PIN, C_NS(700), C_NS(1100), C_NS(700), RGB_ORDER> {};
973
974template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
975class TM1829Controller800Khz : public ClocklessController<DATA_PIN, C_NS(340), C_NS(340), C_NS(550), RGB_ORDER, 0, true, 500> {};
976
977template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
978class TM1829Controller1600Khz : public ClocklessController<DATA_PIN, C_NS(100), C_NS(300), C_NS(200), RGB_ORDER, 0, true, 500> {};
979
980template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
981class LPD1886Controller1250Khz : public ClocklessController<DATA_PIN, C_NS(200), C_NS(400), C_NS(200), RGB_ORDER, 4> {};
982
983template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
984class LPD1886Controller1250Khz_8bit : public ClocklessController<DATA_PIN, C_NS(200), C_NS(400), C_NS(200), RGB_ORDER> {};
985
986
987template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
988class SK6822Controller : public ClocklessController<DATA_PIN, C_NS_SK6822(375), C_NS_SK6822(1000), C_NS_SK6822(375), RGB_ORDER> {};
989
990template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
991class SK6812Controller : public ClocklessController<DATA_PIN, C_NS_SK6812(300), C_NS_SK6812(300), C_NS_SK6812(600), RGB_ORDER> {};
992
993template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
994class SM16703Controller : public ClocklessController<DATA_PIN, C_NS(300), C_NS(600), C_NS(300), RGB_ORDER> {};
995
996template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
997class PL9823Controller : public ClocklessController<DATA_PIN, C_NS(350), C_NS(1010), C_NS(350), RGB_ORDER> {};
998
999// UCS1912 - Note, never been tested, this is according to the datasheet
1000template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
1001class UCS1912Controller : public ClocklessController<DATA_PIN, C_NS(250), C_NS(1000), C_NS(350), RGB_ORDER> {};
1002#endif
1004
1005#endif
1007
1008FASTLED_NAMESPACE_END
1009
1010#endif
central include file for FastLED, defines the CFastLED class/object
APA102 high definition controller class.
Definition chipsets.h:497
APA102 controller class.
Definition chipsets.h:331
virtual void showPixels(PixelController< RGB_ORDER > &pixels)
Send the LED data to the strip.
Definition chipsets.h:386
virtual void init()
Initialize the LED controller.
Definition chipsets.h:380
void select()
Select the SPI output (chip select)
static void writeWord(uint16_t w)
Write a word (two bytes) over SPI.
static void writeByte(uint8_t b)
Write a single byte over SPI.
void release()
Release the SPI chip select line.
static void writeBytesValueRaw(uint8_t value, int len)
Write multiple bytes of the given value over SPI, without selecting the interface.
static void waitFully()
Wait until the SPI subsystem is ready for more data to write.
void init()
Set the clock/data pins to output and make sure the chip select is released.
virtual void init()=0
Initialize the LED controller.
Class to ensure that a minimum amount of time has kicked since the last time run - and delay if not e...
void mark()
Reset the timestamp that marks the start of the wait period.
void wait()
Blocking delay until WAIT time since mark() has passed.
Template extension of the CLEDController class.
virtual void showPixels(PixelController< RGB_ORDER, LANES, MASK > &pixels)=0
Send the LED data to the strip.
DP1903 controller class @ 400 KHz.
Definition chipsets.h:733
DP1903 controller class @ 800 KHz.
Definition chipsets.h:728
GE8822 controller class.
Definition chipsets.h:697
GW6205 controller class @ 400 KHz.
Definition chipsets.h:798
UCS1904 controller class @ 800 KHz.
Definition chipsets.h:803
LPD1886 controller class.
Definition chipsets.h:707
LPD1886 controller class.
Definition chipsets.h:702
LPD6803 controller class (LPD1101).
Definition chipsets.h:268
virtual void showPixels(PixelController< RGB_ORDER > &pixels)
Send the LED data to the strip.
Definition chipsets.h:284
virtual void init()
Initialize the LED controller.
Definition chipsets.h:278
LPD8806 controller class.
Definition chipsets.h:187
virtual void showPixels(PixelController< RGB_ORDER > &pixels)
Send the LED data to the strip.
Definition chipsets.h:212
virtual void init()
Initialize the LED controller.
Definition chipsets.h:205
P9813 controller class.
Definition chipsets.h:561
virtual void showPixels(PixelController< RGB_ORDER > &pixels)
Send the LED data to the strip.
Definition chipsets.h:581
virtual void init()
Initialize the LED controller.
Definition chipsets.h:575
PL9823 controller class.
Definition chipsets.h:808
virtual void showPixels(PixelController< RGB_ORDER, LANES, MASK > &pixels)
Send the LED data to the strip.
Definition chipsets.h:121
SK6812 controller class.
Definition chipsets.h:758
SK6822 controller class.
Definition chipsets.h:748
SK9822 controller class.
Definition chipsets.h:544
SK9822 controller class.
Definition chipsets.h:522
SM16703 controller class.
Definition chipsets.h:753
SM16716 controller class.
Definition chipsets.h:611
virtual void init()
Initialize the LED controller.
Definition chipsets.h:633
virtual void showPixels(PixelController< RGB_ORDER > &pixels)
Send the LED data to the strip.
Definition chipsets.h:639
Hardware SPI output.
Definition fastspi.h:51
TM1803 controller class.
Definition chipsets.h:788
TM1809 controller class.
Definition chipsets.h:783
TM1829 controller class.
Definition chipsets.h:793
UCS1903B controller class.
Definition chipsets.h:768
UCS1903 controller class @ 400 KHz.
Definition chipsets.h:763
UCS1904 controller class.
Definition chipsets.h:773
UCS2903 controller class.
Definition chipsets.h:778
WS2801 controller class.
Definition chipsets.h:230
virtual void showPixels(PixelController< RGB_ORDER > &pixels)
Send the LED data to the strip.
Definition chipsets.h:247
virtual void init()
Initialize the controller.
Definition chipsets.h:239
WS2803 controller class.
Definition chipsets.h:257
WS2811 controller class @ 400 KHz.
Definition chipsets.h:743
WS2811 controller class @ 800 KHz.
Definition chipsets.h:723
WS2812 controller class @ 800 KHz.
Definition chipsets.h:713
WS2813 controller class.
Definition chipsets.h:738
WS2815 controller class @ 400 KHz.
Definition chipsets.h:718
#define DATA_RATE_MHZ(X)
Convert data rate from megahertz (MHz) to clock cycles per bit.
Definition fastspi.h:25
Representation of an RGB pixel (Red, Green, Blue)
Definition crgb.h:39
Pixel controller class.
FASTLED_FORCE_INLINE uint8_t loadAndScale1(int lane, uint8_t scale)
non-template alias of loadAndScale<1>()
int mLenRemaining
counter for the number of LEDs left to process
FASTLED_FORCE_INLINE uint8_t loadAndScale2(int lane, uint8_t scale)
non-template alias of loadAndScale<2>()
FASTLED_FORCE_INLINE uint8_t loadAndScale0(int lane, uint8_t scale)
non-template alias of loadAndScale<0>()
const uint8_t * mData
pointer to the underlying LED data
int mLen
number of LEDs in the data for one lane
FASTLED_FORCE_INLINE int size()
Get the length of the LED strip.
FASTLED_FORCE_INLINE void advanceData()
Advance the data pointer forward, adjust position counter.
FASTLED_FORCE_INLINE bool has(int n)
Do we have n pixels left to process?
FASTLED_FORCE_INLINE void stepDithering()
Step the dithering forward.
Definition rgbw.h:25