FastLED  3.1
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 
9 
10 FASTLED_NAMESPACE_BEGIN
15 
16 #if defined(ARDUINO) //&& defined(SoftwareSerial_h)
17 
18 
19 #if defined(SoftwareSerial_h)
20 #include "SoftwareSerial.h"
21 
22 #define HAS_PIXIE
23 
27 template<uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
28 class PixieController : public CPixelLEDController<RGB_ORDER> {
29  SoftwareSerial Serial;
30  CMinWait<2000> mWait;
31 public:
32  PixieController() : Serial(-1, DATA_PIN) {}
33 
34 protected:
35  virtual void init() {
36  Serial.begin(115200);
37  mWait.mark();
38  }
39 
40  virtual void showPixels(PixelController<RGB_ORDER> & pixels) {
41  mWait.wait();
42  while(pixels.has(1)) {
43  uint8_t r = pixels.loadAndScale0();
44  Serial.write(r);
45  uint8_t g = pixels.loadAndScale1();
46  Serial.write(g);
47  uint8_t b = pixels.loadAndScale2();
48  Serial.write(b);
49  pixels.advanceData();
50  pixels.stepDithering();
51  }
52  mWait.mark();
53  }
54 
55 };
56 
57 // template<SoftwareSerial & STREAM, EOrder RGB_ORDER = RGB>
58 // class PixieController : public PixieBaseController<STREAM, RGB_ORDER> {
59 // public:
60 // virtual void init() {
61 // STREAM.begin(115200);
62 // }
63 // };
64 #endif
65 #endif
66 
70 //
71 // LPD8806 controller class - takes data/clock/select pin values (N.B. should take an SPI definition?)
72 //
74 
80 template <uint8_t DATA_PIN, uint8_t CLOCK_PIN, EOrder RGB_ORDER = RGB, uint8_t SPI_SPEED = DATA_RATE_MHZ(12) >
81 class LPD8806Controller : public CPixelLEDController<RGB_ORDER> {
83 
84  class LPD8806_ADJUST {
85  public:
86  // LPD8806 spec wants the high bit of every rgb data byte sent out to be set.
87  __attribute__((always_inline)) inline static uint8_t adjust(register uint8_t data) { return ((data>>1) | 0x80) + ((data && (data<254)) & 0x01); }
88  __attribute__((always_inline)) inline static void postBlock(int len) {
89  SPI::writeBytesValueRaw(0, ((len*3+63)>>6));
90  }
91 
92  };
93 
94  SPI mSPI;
95 public:
96 
98  virtual void init() {
99  mSPI.init();
100  }
101 
102 protected:
103 
104  virtual void showPixels(PixelController<RGB_ORDER> & pixels) {
105  mSPI.template writePixels<0, LPD8806_ADJUST, RGB_ORDER>(pixels);
106  }
107 };
108 
109 
111 //
112 // WS2801 definition - takes data/clock/select pin values (N.B. should take an SPI definition?)
113 //
115 
121 template <uint8_t DATA_PIN, uint8_t CLOCK_PIN, EOrder RGB_ORDER = RGB, uint8_t SPI_SPEED = DATA_RATE_MHZ(1)>
122 class WS2801Controller : public CPixelLEDController<RGB_ORDER> {
124  SPI mSPI;
125  CMinWait<1000> mWaitDelay;
126 public:
127  WS2801Controller() {}
128 
129  virtual void init() {
130  mSPI.init();
131  mWaitDelay.mark();
132  }
133 
134 protected:
135 
136  virtual void showPixels(PixelController<RGB_ORDER> & pixels) {
137  mWaitDelay.wait();
138  mSPI.template writePixels<0, DATA_NOP, RGB_ORDER>(pixels);
139  mWaitDelay.mark();
140  }
141 };
142 
143 template <uint8_t DATA_PIN, uint8_t CLOCK_PIN, EOrder RGB_ORDER = RGB, uint8_t SPI_SPEED = DATA_RATE_MHZ(25)>
144 class WS2803Controller : public WS2801Controller<DATA_PIN, CLOCK_PIN, RGB_ORDER, SPI_SPEED> {};
145 
147 //
148 // APA102 definition - takes data/clock/select pin values (N.B. should take an SPI definition?)
149 //
151 
157 template <uint8_t DATA_PIN, uint8_t CLOCK_PIN, EOrder RGB_ORDER = RGB, uint8_t SPI_SPEED = DATA_RATE_MHZ(24)>
158 class APA102Controller : public CPixelLEDController<RGB_ORDER> {
160  SPI mSPI;
161 
162  void startBoundary() { mSPI.writeWord(0); mSPI.writeWord(0); }
163  void endBoundary(int nLeds) { int nDWords = (nLeds/32); do { mSPI.writeByte(0xFF); mSPI.writeByte(0x00); mSPI.writeByte(0x00); mSPI.writeByte(0x00); } while(nDWords--); }
164 
165  inline void writeLed(uint8_t b0, uint8_t b1, uint8_t b2) __attribute__((always_inline)) {
166  mSPI.writeByte(0xFF); mSPI.writeByte(b0); mSPI.writeByte(b1); mSPI.writeByte(b2);
167  }
168 
169 public:
170  APA102Controller() {}
171 
172  virtual void init() {
173  mSPI.init();
174  }
175 
176 protected:
177 
178  virtual void showPixels(PixelController<RGB_ORDER> & pixels) {
179  mSPI.select();
180 
181  startBoundary();
182  while(pixels.has(1)) {
183 #ifdef FASTLED_SPI_BYTE_ONLY
184  mSPI.writeByte(0xFF);
185  mSPI.writeByte(pixels.loadAndScale0());
186  mSPI.writeByte(pixels.loadAndScale1());
187  mSPI.writeByte(pixels.loadAndScale2());
188 #else
189  uint16_t b = 0xFF00 | (uint16_t)pixels.loadAndScale0();
190  mSPI.writeWord(b);
191  uint16_t w = pixels.loadAndScale1() << 8;
192  w |= pixels.loadAndScale2();
193  mSPI.writeWord(w);
194 #endif
195  pixels.stepDithering();
196  pixels.advanceData();
197  }
198  endBoundary(pixels.size());
199  mSPI.waitFully();
200  mSPI.release();
201  }
202 
203 };
204 
210 template <uint8_t DATA_PIN, uint8_t CLOCK_PIN, EOrder RGB_ORDER = RGB, uint8_t SPI_SPEED = DATA_RATE_MHZ(24)>
211 class SK9822Controller : public CPixelLEDController<RGB_ORDER> {
213  SPI mSPI;
214 
215  void startBoundary() { mSPI.writeWord(0); mSPI.writeWord(0); }
216  void endBoundary(int nLeds) { int nLongWords = (nLeds/32); do { mSPI.writeByte(0x00); mSPI.writeByte(0x00); mSPI.writeByte(0x00); mSPI.writeByte(0x00); } while(nLongWords--); }
217 
218  inline void writeLed(uint8_t b0, uint8_t b1, uint8_t b2) __attribute__((always_inline)) {
219  mSPI.writeByte(0xFF); mSPI.writeByte(b0); mSPI.writeByte(b1); mSPI.writeByte(b2);
220  }
221 
222 public:
223  SK9822Controller() {}
224 
225  virtual void init() {
226  mSPI.init();
227  }
228 
229 protected:
230 
231  virtual void showPixels(PixelController<RGB_ORDER> & pixels) {
232  mSPI.select();
233 
234  startBoundary();
235  while(pixels.has(1)) {
236 #ifdef FASTLED_SPI_BYTE_ONLY
237  mSPI.writeByte(0xFF);
238  mSPI.writeByte(pixels.loadAndScale0());
239  mSPI.writeByte(pixels.loadAndScale1());
240  mSPI.writeByte(pixels.loadAndScale2());
241 #else
242  uint16_t b = 0xFF00 | (uint16_t)pixels.loadAndScale0();
243  mSPI.writeWord(b);
244  uint16_t w = pixels.loadAndScale1() << 8;
245  w |= pixels.loadAndScale2();
246  mSPI.writeWord(w);
247 #endif
248  pixels.stepDithering();
249  pixels.advanceData();
250  }
251 
252  endBoundary(pixels.size());
253 
254  mSPI.waitFully();
255  mSPI.release();
256  }
257 
258 };
259 
260 
261 
263 //
264 // P9813 definition - takes data/clock/select pin values (N.B. should take an SPI definition?)
265 //
267 
273 template <uint8_t DATA_PIN, uint8_t CLOCK_PIN, EOrder RGB_ORDER = RGB, uint8_t SPI_SPEED = DATA_RATE_MHZ(10)>
274 class P9813Controller : public CPixelLEDController<RGB_ORDER> {
276  SPI mSPI;
277 
278  void writeBoundary() { mSPI.writeWord(0); mSPI.writeWord(0); }
279 
280  inline void writeLed(uint8_t r, uint8_t g, uint8_t b) __attribute__((always_inline)) {
281  register uint8_t top = 0xC0 | ((~b & 0xC0) >> 2) | ((~g & 0xC0) >> 4) | ((~r & 0xC0) >> 6);
282  mSPI.writeByte(top); mSPI.writeByte(b); mSPI.writeByte(g); mSPI.writeByte(r);
283  }
284 
285 public:
286  P9813Controller() {}
287 
288  virtual void init() {
289  mSPI.init();
290  }
291 
292 protected:
293 
294  virtual void showPixels(PixelController<RGB_ORDER> & pixels) {
295  mSPI.select();
296 
297  writeBoundary();
298  while(pixels.has(1)) {
299  writeLed(pixels.loadAndScale0(), pixels.loadAndScale1(), pixels.loadAndScale2());
300  pixels.advanceData();
301  pixels.stepDithering();
302  }
303  writeBoundary();
304  mSPI.waitFully();
305 
306  mSPI.release();
307  }
308 
309 };
310 
311 
313 //
314 // SM16716 definition - takes data/clock/select pin values (N.B. should take an SPI definition?)
315 //
317 
323 template <uint8_t DATA_PIN, uint8_t CLOCK_PIN, EOrder RGB_ORDER = RGB, uint8_t SPI_SPEED = DATA_RATE_MHZ(16)>
324 class SM16716Controller : public CPixelLEDController<RGB_ORDER> {
326  SPI mSPI;
327 
328  void writeHeader() {
329  // Write out 50 zeros to the spi line (6 blocks of 8 followed by two single bit writes)
330  mSPI.select();
331  mSPI.writeBytesValueRaw(0, 6);
332  mSPI.waitFully();
333  mSPI.template writeBit<0>(0);
334  mSPI.template writeBit<0>(0);
335  mSPI.release();
336  }
337 
338 public:
339  SM16716Controller() {}
340 
341  virtual void init() {
342  mSPI.init();
343  }
344 
345 protected:
346 
347  virtual void showPixels(PixelController<RGB_ORDER> & pixels) {
348  // Make sure the FLAG_START_BIT flag is set to ensure that an extra 1 bit is sent at the start
349  // of each triplet of bytes for rgb data
350  // writeHeader();
351  mSPI.template writePixels<FLAG_START_BIT, DATA_NOP, RGB_ORDER>( pixels );
352  writeHeader();
353  }
354 
355 };
358 //
359 // Clockless template instantiations - see clockless.h for how the timing values are used
360 //
362 
363 #ifdef FASTLED_HAS_CLOCKLESS
364 
368 // We want to force all avr's to use the Trinket controller when running at 8Mhz, because even the 328's at 8Mhz
369 // need the more tightly defined timeframes.
370 #if (F_CPU == 8000000 || F_CPU == 16000000 || F_CPU == 24000000) // || F_CPU == 48000000 || F_CPU == 96000000) // 125ns/clock
371 #define FMUL (F_CPU/8000000)
372 // LPD1886
373 template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
374 class LPD1886Controller1250Khz : public ClocklessController<DATA_PIN, 2 * FMUL, 3 * FMUL, 2 * FMUL, RGB_ORDER, 4> {};
375 
376 // LPD1886
377 template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
378 class LPD1886Controller1250Khz_8bit : public ClocklessController<DATA_PIN, 2 * FMUL, 3 * FMUL, 2 * FMUL, RGB_ORDER> {};
379 
380 // WS2811@800khz 2 clocks, 5 clocks, 3 clocks
381 template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
382 class WS2812Controller800Khz : public ClocklessController<DATA_PIN, 2 * FMUL, 5 * FMUL, 3 * FMUL, RGB_ORDER> {};
383 
384 template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
385 class WS2811Controller800Khz : public ClocklessController<DATA_PIN, 3 * FMUL, 4 * FMUL, 3 * FMUL, RGB_ORDER> {};
386 
387 template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
388 class WS2811Controller400Khz : public ClocklessController<DATA_PIN, 4 * FMUL, 10 * FMUL, 6 * FMUL, RGB_ORDER> {};
389 
390 template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
391 class SK6822Controller : public ClocklessController<DATA_PIN, 3 * FMUL, 8 * FMUL, 3 * FMUL, RGB_ORDER> {};
392 
393 template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
394 class SK6812Controller : public ClocklessController<DATA_PIN, 3 * FMUL, 3 * FMUL, 4 * FMUL, RGB_ORDER> {};
395 
396 template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
397 class UCS1903Controller400Khz : public ClocklessController<DATA_PIN, 4 * FMUL, 12 * FMUL, 4 * FMUL, RGB_ORDER> {};
398 
399 template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
400 class UCS1903BController800Khz : public ClocklessController<DATA_PIN, 2 * FMUL, 4 * FMUL, 4 * FMUL, RGB_ORDER> {};
401 
402 template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
403 class UCS1904Controller800Khz : public ClocklessController<DATA_PIN, 3 * FMUL, 3 * FMUL, 4 * FMUL, RGB_ORDER> {};
404 
405 template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
406 class UCS2903Controller : public ClocklessController<DATA_PIN, 2 * FMUL, 6 * FMUL, 2 * FMUL, RGB_ORDER> {};
407 
408 template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
409 class TM1809Controller800Khz : public ClocklessController<DATA_PIN, 2 * FMUL, 5 * FMUL, 3 * FMUL, RGB_ORDER> {};
410 
411 template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
412 class TM1803Controller400Khz : public ClocklessController<DATA_PIN, 6 * FMUL, 9 * FMUL, 6 * FMUL, RGB_ORDER> {};
413 
414 template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
415 class TM1829Controller800Khz : public ClocklessController<DATA_PIN, 2 * FMUL, 5 * FMUL, 3 * FMUL, RGB_ORDER> {};
416 
417 template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
418 class GW6205Controller400Khz : public ClocklessController<DATA_PIN, 6 * FMUL, 7 * FMUL, 6 * FMUL, RGB_ORDER, 4> {};
419 
420 template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
421 class GW6205Controller800Khz : public ClocklessController<DATA_PIN, 2 * FMUL, 4 * FMUL, 4 * FMUL, RGB_ORDER, 4> {};
422 
423 template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
424 class PL9823Controller : public ClocklessController<DATA_PIN, 3 * FMUL, 8 * FMUL, 3 * FMUL, RGB_ORDER> {};
425 
426 #else
427 // GW6205@400khz - 800ns, 800ns, 800ns
428 template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
429 class GW6205Controller400Khz : public ClocklessController<DATA_PIN, NS(800), NS(800), NS(800), RGB_ORDER, 4> {};
430 
431 // GW6205@400khz - 400ns, 400ns, 400ns
432 template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
433 class GW6205Controller800Khz : public ClocklessController<DATA_PIN, NS(400), NS(400), NS(400), RGB_ORDER, 4> {};
434 
435 // UCS1903 - 500ns, 1500ns, 500ns
436 template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
437 class UCS1903Controller400Khz : public ClocklessController<DATA_PIN, NS(500), NS(1500), NS(500), RGB_ORDER> {};
438 
439 // UCS1903B - 400ns, 450ns, 450ns
440 template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
441 class UCS1903BController800Khz : public ClocklessController<DATA_PIN, NS(400), NS(450), NS(450), RGB_ORDER> {};
442 
443 // UCS1904 - 400ns, 400ns, 450ns
444 template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
445 class UCS1904Controller800Khz : public ClocklessController<DATA_PIN, NS(400), NS(400), NS(450), RGB_ORDER> {};
446 
447 // UCS2903 - 250ns, 750ns, 250ns
448 template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
449 class UCS2903Controller : public ClocklessController<DATA_PIN, NS(250), NS(750), NS(250), RGB_ORDER> {};
450 
451 // TM1809 - 350ns, 350ns, 550ns
452 template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
453 class TM1809Controller800Khz : public ClocklessController<DATA_PIN, NS(350), NS(350), NS(450), RGB_ORDER> {};
454 
455 // WS2811 - 320ns, 320ns, 640ns
456 template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
457 class WS2811Controller800Khz : public ClocklessController<DATA_PIN, NS(320), NS(320), NS(640), RGB_ORDER> {};
458 
459 // WS2812 - 250ns, 625ns, 375ns
460 template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
461 class WS2812Controller800Khz : public ClocklessController<DATA_PIN, NS(250), NS(625), NS(375), RGB_ORDER> {};
462 
463 // WS2811@400khz - 800ns, 800ns, 900ns
464 template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
465 class WS2811Controller400Khz : public ClocklessController<DATA_PIN, NS(800), NS(800), NS(900), RGB_ORDER> {};
466 
467 // 750NS, 750NS, 750NS
468 template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
469 class TM1803Controller400Khz : public ClocklessController<DATA_PIN, NS(700), NS(1100), NS(700), RGB_ORDER> {};
470 
471 template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
472 class TM1829Controller800Khz : public ClocklessController<DATA_PIN, NS(340), NS(340), NS(550), RGB_ORDER, 0, true, 500> {};
473 
474 template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
475 class TM1829Controller1600Khz : public ClocklessController<DATA_PIN, NS(100), NS(300), NS(200), RGB_ORDER, 0, true, 500> {};
476 
477 template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
478 class LPD1886Controller1250Khz : public ClocklessController<DATA_PIN, NS(200), NS(400), NS(200), RGB_ORDER, 4> {};
479 
480 template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
481 class LPD1886Controller1250Khz_8bit : public ClocklessController<DATA_PIN, NS(200), NS(400), NS(200), RGB_ORDER, 4> {};
482 
483 
484 template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
485 class SK6822Controller : public ClocklessController<DATA_PIN, NS(375), NS(1000), NS(375), RGB_ORDER> {};
486 
487 template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
488 class SK6812Controller : public ClocklessController<DATA_PIN, NS(300), NS(300), NS(600), RGB_ORDER> {};
489 
490 template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
491 class PL9823Controller : public ClocklessController<DATA_PIN, NS(350), NS(1010), NS(350), RGB_ORDER> {};
492 #endif
493 
495 #endif
496 FASTLED_NAMESPACE_END
498 
499 #endif
virtual void init()
initialize the LED controller
Definition: chipsets.h:129
LPD8806 controller class.
Definition: chipsets.h:81
Adafruit Pixie controller class.
Definition: chipsets.h:28
virtual void init()
initialize the LED controller
Definition: chipsets.h:288
virtual void init()
initialize the LED controller
Definition: chipsets.h:341
virtual void init()
initialize the LED controller
Definition: chipsets.h:172
virtual void init()
initialize the LED controller
Definition: chipsets.h:98
WS2801 controller class.
Definition: chipsets.h:122
SK9822 controller class.
Definition: chipsets.h:211
central include file for FastLED, defines the CFastLED class/object
P9813 controller class.
Definition: chipsets.h:274
virtual void init()
initialize the LED controller
Definition: chipsets.h:225
virtual void init()
initialize the LED controller
Definition: chipsets.h:35
APA102 controller class.
Definition: chipsets.h:158
__attribute__((always_inline)) inline void swapbits8(bitswap_type in
Do an 8byte by 8bit rotation.
Definition: fastled_delay.h:92
SM16716 controller class.
Definition: chipsets.h:324