PlatformIO package of the Teensy core framework compatible with GCC 10 & C++20
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

chipsets.h 23KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623
  1. #ifndef __INC_CHIPSETS_H
  2. #define __INC_CHIPSETS_H
  3. #include "FastLED.h"
  4. #include "pixeltypes.h"
  5. ///@file chipsets.h
  6. /// contains the bulk of the definitions for the various LED chipsets supported.
  7. FASTLED_NAMESPACE_BEGIN
  8. ///@defgroup chipsets
  9. /// Implementations of CLEDController classes for various led chipsets.
  10. ///
  11. ///@{
  12. #if defined(ARDUINO) //&& defined(SoftwareSerial_h)
  13. #if defined(SoftwareSerial_h)
  14. #include <SoftwareSerial.h>
  15. #define HAS_PIXIE
  16. /// Adafruit Pixie controller class
  17. /// @tparam DATAPIN the pin to write data out on
  18. /// @tparam RGB_ORDER the RGB ordering for the led data
  19. template<uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
  20. class PixieController : public CPixelLEDController<RGB_ORDER> {
  21. SoftwareSerial Serial;
  22. CMinWait<2000> mWait;
  23. public:
  24. PixieController() : Serial(-1, DATA_PIN) {}
  25. protected:
  26. virtual void init() {
  27. Serial.begin(115200);
  28. mWait.mark();
  29. }
  30. virtual void showPixels(PixelController<RGB_ORDER> & pixels) {
  31. mWait.wait();
  32. while(pixels.has(1)) {
  33. uint8_t r = pixels.loadAndScale0();
  34. Serial.write(r);
  35. uint8_t g = pixels.loadAndScale1();
  36. Serial.write(g);
  37. uint8_t b = pixels.loadAndScale2();
  38. Serial.write(b);
  39. pixels.advanceData();
  40. pixels.stepDithering();
  41. }
  42. mWait.mark();
  43. }
  44. };
  45. // template<SoftwareSerial & STREAM, EOrder RGB_ORDER = RGB>
  46. // class PixieController : public PixieBaseController<STREAM, RGB_ORDER> {
  47. // public:
  48. // virtual void init() {
  49. // STREAM.begin(115200);
  50. // }
  51. // };
  52. #endif
  53. #endif
  54. ///@name Clocked chipsets - nominally SPI based these chipsets have a data and a clock line.
  55. ///@{
  56. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  57. //
  58. // LPD8806 controller class - takes data/clock/select pin values (N.B. should take an SPI definition?)
  59. //
  60. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  61. /// LPD8806 controller class.
  62. /// @tparam DATA_PIN the data pin for these leds
  63. /// @tparam CLOCK_PIN the clock pin for these leds
  64. /// @tparam RGB_ORDER the RGB ordering for these leds
  65. /// @tparam SPI_SPEED the clock divider used for these leds. Set using the DATA_RATE_MHZ/DATA_RATE_KHZ macros. Defaults to DATA_RATE_MHZ(12)
  66. template <uint8_t DATA_PIN, uint8_t CLOCK_PIN, EOrder RGB_ORDER = RGB, uint32_t SPI_SPEED = DATA_RATE_MHZ(12) >
  67. class LPD8806Controller : public CPixelLEDController<RGB_ORDER> {
  68. typedef SPIOutput<DATA_PIN, CLOCK_PIN, SPI_SPEED> SPI;
  69. class LPD8806_ADJUST {
  70. public:
  71. // LPD8806 spec wants the high bit of every rgb data byte sent out to be set.
  72. __attribute__((always_inline)) inline static uint8_t adjust(register uint8_t data) { return ((data>>1) | 0x80) + ((data && (data<254)) & 0x01); }
  73. __attribute__((always_inline)) inline static void postBlock(int len) {
  74. SPI::writeBytesValueRaw(0, ((len*3+63)>>6));
  75. }
  76. };
  77. SPI mSPI;
  78. public:
  79. LPD8806Controller() {}
  80. virtual void init() {
  81. mSPI.init();
  82. }
  83. protected:
  84. virtual void showPixels(PixelController<RGB_ORDER> & pixels) {
  85. mSPI.template writePixels<0, LPD8806_ADJUST, RGB_ORDER>(pixels);
  86. }
  87. };
  88. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  89. //
  90. // WS2801 definition - takes data/clock/select pin values (N.B. should take an SPI definition?)
  91. //
  92. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  93. /// WS2801 controller class.
  94. /// @tparam DATA_PIN the data pin for these leds
  95. /// @tparam CLOCK_PIN the clock pin for these leds
  96. /// @tparam RGB_ORDER the RGB ordering for these leds
  97. /// @tparam SPI_SPEED the clock divider used for these leds. Set using the DATA_RATE_MHZ/DATA_RATE_KHZ macros. Defaults to DATA_RATE_MHZ(1)
  98. template <uint8_t DATA_PIN, uint8_t CLOCK_PIN, EOrder RGB_ORDER = RGB, uint32_t SPI_SPEED = DATA_RATE_MHZ(1)>
  99. class WS2801Controller : public CPixelLEDController<RGB_ORDER> {
  100. typedef SPIOutput<DATA_PIN, CLOCK_PIN, SPI_SPEED> SPI;
  101. SPI mSPI;
  102. CMinWait<1000> mWaitDelay;
  103. public:
  104. WS2801Controller() {}
  105. virtual void init() {
  106. mSPI.init();
  107. mWaitDelay.mark();
  108. }
  109. protected:
  110. virtual void showPixels(PixelController<RGB_ORDER> & pixels) {
  111. mWaitDelay.wait();
  112. mSPI.template writePixels<0, DATA_NOP, RGB_ORDER>(pixels);
  113. mWaitDelay.mark();
  114. }
  115. };
  116. template <uint8_t DATA_PIN, uint8_t CLOCK_PIN, EOrder RGB_ORDER = RGB, uint32_t SPI_SPEED = DATA_RATE_MHZ(25)>
  117. class WS2803Controller : public WS2801Controller<DATA_PIN, CLOCK_PIN, RGB_ORDER, SPI_SPEED> {};
  118. /// LPD6803 controller class (LPD1101).
  119. /// 16 bit (1 bit - const "1", 5 bit - red, 5 bit - green, 5 bit blue).
  120. /// In chip CMODE pin must be set to 1 (inside oscillator mode).
  121. /// Datasheet: https://cdn-shop.adafruit.com/datasheets/LPD6803.pdf
  122. /// @tparam DATA_PIN the data pin for these leds
  123. /// @tparam CLOCK_PIN the clock pin for these leds
  124. /// @tparam RGB_ORDER the RGB ordering for these leds
  125. /// @tparam SPI_SPEED the clock divider used for these leds. Set using the DATA_RATE_MHZ/DATA_RATE_KHZ macros. Defaults to DATA_RATE_MHZ(12)
  126. template <uint8_t DATA_PIN, uint8_t CLOCK_PIN, EOrder RGB_ORDER = RGB, uint32_t SPI_SPEED = DATA_RATE_MHZ(12)>
  127. class LPD6803Controller : public CPixelLEDController<RGB_ORDER> {
  128. typedef SPIOutput<DATA_PIN, CLOCK_PIN, SPI_SPEED> SPI;
  129. SPI mSPI;
  130. void startBoundary() { mSPI.writeByte(0); mSPI.writeByte(0); mSPI.writeByte(0); mSPI.writeByte(0); }
  131. public:
  132. LPD6803Controller() {}
  133. virtual void init() {
  134. mSPI.init();
  135. }
  136. protected:
  137. virtual void showPixels(PixelController<RGB_ORDER> & pixels) {
  138. mSPI.select();
  139. startBoundary();
  140. while(pixels.has(1)) {
  141. register uint16_t command;
  142. command = 0x8000;
  143. command |= (pixels.loadAndScale0() & 0xF8) << 7; // red is the high 5 bits
  144. command |= (pixels.loadAndScale1() & 0xF8) << 2; // green is the middle 5 bits
  145. mSPI.writeByte((command >> 8) & 0xFF);
  146. command |= pixels.loadAndScale2() >> 3 ; // blue is the low 5 bits
  147. mSPI.writeByte(command & 0xFF);
  148. pixels.stepDithering();
  149. pixels.advanceData();
  150. }
  151. //endBoundary(pixels.size());
  152. mSPI.waitFully();
  153. mSPI.release();
  154. }
  155. };
  156. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  157. //
  158. // APA102 definition - takes data/clock/select pin values (N.B. should take an SPI definition?)
  159. //
  160. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  161. /// APA102 controller class.
  162. /// @tparam DATA_PIN the data pin for these leds
  163. /// @tparam CLOCK_PIN the clock pin for these leds
  164. /// @tparam RGB_ORDER the RGB ordering for these leds
  165. /// @tparam SPI_SPEED the clock divider used for these leds. Set using the DATA_RATE_MHZ/DATA_RATE_KHZ macros. Defaults to DATA_RATE_MHZ(12)
  166. template <uint8_t DATA_PIN, uint8_t CLOCK_PIN, EOrder RGB_ORDER = RGB, uint32_t SPI_SPEED = DATA_RATE_MHZ(12)>
  167. class APA102Controller : public CPixelLEDController<RGB_ORDER> {
  168. typedef SPIOutput<DATA_PIN, CLOCK_PIN, SPI_SPEED> SPI;
  169. SPI mSPI;
  170. void startBoundary() { mSPI.writeWord(0); mSPI.writeWord(0); }
  171. void endBoundary(int nLeds) { int nDWords = (nLeds/32); do { mSPI.writeByte(0xFF); mSPI.writeByte(0x00); mSPI.writeByte(0x00); mSPI.writeByte(0x00); } while(nDWords--); }
  172. inline void writeLed(uint8_t brightness, uint8_t b0, uint8_t b1, uint8_t b2) __attribute__((always_inline)) {
  173. #ifdef FASTLED_SPI_BYTE_ONLY
  174. mSPI.writeByte(0xE0 | brightness);
  175. mSPI.writeByte(b0);
  176. mSPI.writeByte(b1);
  177. mSPI.writeByte(b2);
  178. #else
  179. uint16_t b = 0xE000 | (brightness << 8) | (uint16_t)b0;
  180. mSPI.writeWord(b);
  181. uint16_t w = b1 << 8;
  182. w |= b2;
  183. mSPI.writeWord(w);
  184. #endif
  185. }
  186. public:
  187. APA102Controller() {}
  188. virtual void init() {
  189. mSPI.init();
  190. }
  191. protected:
  192. virtual void showPixels(PixelController<RGB_ORDER> & pixels) {
  193. mSPI.select();
  194. uint8_t s0 = pixels.getScale0(), s1 = pixels.getScale1(), s2 = pixels.getScale2();
  195. #if FASTLED_USE_GLOBAL_BRIGHTNESS == 1
  196. const uint16_t maxBrightness = 0x1F;
  197. uint16_t brightness = ((((uint16_t)max(max(s0, s1), s2) + 1) * maxBrightness - 1) >> 8) + 1;
  198. s0 = (maxBrightness * s0 + (brightness >> 1)) / brightness;
  199. s1 = (maxBrightness * s1 + (brightness >> 1)) / brightness;
  200. s2 = (maxBrightness * s2 + (brightness >> 1)) / brightness;
  201. #else
  202. const uint8_t brightness = 0x1F;
  203. #endif
  204. startBoundary();
  205. while (pixels.has(1)) {
  206. writeLed(brightness, pixels.loadAndScale0(0, s0), pixels.loadAndScale1(0, s1), pixels.loadAndScale2(0, s2));
  207. pixels.stepDithering();
  208. pixels.advanceData();
  209. }
  210. endBoundary(pixels.size());
  211. mSPI.waitFully();
  212. mSPI.release();
  213. }
  214. };
  215. /// SK9822 controller class.
  216. /// @tparam DATA_PIN the data pin for these leds
  217. /// @tparam CLOCK_PIN the clock pin for these leds
  218. /// @tparam RGB_ORDER the RGB ordering for these leds
  219. /// @tparam SPI_SPEED the clock divider used for these leds. Set using the DATA_RATE_MHZ/DATA_RATE_KHZ macros. Defaults to DATA_RATE_MHZ(24)
  220. template <uint8_t DATA_PIN, uint8_t CLOCK_PIN, EOrder RGB_ORDER = RGB, uint32_t SPI_SPEED = DATA_RATE_MHZ(24)>
  221. class SK9822Controller : public CPixelLEDController<RGB_ORDER> {
  222. typedef SPIOutput<DATA_PIN, CLOCK_PIN, SPI_SPEED> SPI;
  223. SPI mSPI;
  224. void startBoundary() { mSPI.writeWord(0); mSPI.writeWord(0); }
  225. void endBoundary(int nLeds) { int nLongWords = (nLeds/32); do { mSPI.writeByte(0x00); mSPI.writeByte(0x00); mSPI.writeByte(0x00); mSPI.writeByte(0x00); } while(nLongWords--); }
  226. inline void writeLed(uint8_t brightness, uint8_t b0, uint8_t b1, uint8_t b2) __attribute__((always_inline)) {
  227. #ifdef FASTLED_SPI_BYTE_ONLY
  228. mSPI.writeByte(0xE0 | brightness);
  229. mSPI.writeByte(b0);
  230. mSPI.writeByte(b1);
  231. mSPI.writeByte(b2);
  232. #else
  233. uint16_t b = 0xE000 | (brightness << 8) | (uint16_t)b0;
  234. mSPI.writeWord(b);
  235. uint16_t w = b1 << 8;
  236. w |= b2;
  237. mSPI.writeWord(w);
  238. #endif
  239. }
  240. public:
  241. SK9822Controller() {}
  242. virtual void init() {
  243. mSPI.init();
  244. }
  245. protected:
  246. virtual void showPixels(PixelController<RGB_ORDER> & pixels) {
  247. mSPI.select();
  248. uint8_t s0 = pixels.getScale0(), s1 = pixels.getScale1(), s2 = pixels.getScale2();
  249. #if FASTLED_USE_GLOBAL_BRIGHTNESS == 1
  250. const uint16_t maxBrightness = 0x1F;
  251. uint16_t brightness = ((((uint16_t)max(max(s0, s1), s2) + 1) * maxBrightness - 1) >> 8) + 1;
  252. s0 = (maxBrightness * s0 + (brightness >> 1)) / brightness;
  253. s1 = (maxBrightness * s1 + (brightness >> 1)) / brightness;
  254. s2 = (maxBrightness * s2 + (brightness >> 1)) / brightness;
  255. #else
  256. const uint8_t brightness = 0x1F;
  257. #endif
  258. startBoundary();
  259. while (pixels.has(1)) {
  260. writeLed(brightness, pixels.loadAndScale0(0, s0), pixels.loadAndScale1(0, s1), pixels.loadAndScale2(0, s2));
  261. pixels.stepDithering();
  262. pixels.advanceData();
  263. }
  264. endBoundary(pixels.size());
  265. mSPI.waitFully();
  266. mSPI.release();
  267. }
  268. };
  269. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  270. //
  271. // P9813 definition - takes data/clock/select pin values (N.B. should take an SPI definition?)
  272. //
  273. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  274. /// P9813 controller class.
  275. /// @tparam DATA_PIN the data pin for these leds
  276. /// @tparam CLOCK_PIN the clock pin for these leds
  277. /// @tparam RGB_ORDER the RGB ordering for these leds
  278. /// @tparam SPI_SPEED the clock divider used for these leds. Set using the DATA_RATE_MHZ/DATA_RATE_KHZ macros. Defaults to DATA_RATE_MHZ(10)
  279. template <uint8_t DATA_PIN, uint8_t CLOCK_PIN, EOrder RGB_ORDER = RGB, uint32_t SPI_SPEED = DATA_RATE_MHZ(10)>
  280. class P9813Controller : public CPixelLEDController<RGB_ORDER> {
  281. typedef SPIOutput<DATA_PIN, CLOCK_PIN, SPI_SPEED> SPI;
  282. SPI mSPI;
  283. void writeBoundary() { mSPI.writeWord(0); mSPI.writeWord(0); }
  284. inline void writeLed(uint8_t r, uint8_t g, uint8_t b) __attribute__((always_inline)) {
  285. register uint8_t top = 0xC0 | ((~b & 0xC0) >> 2) | ((~g & 0xC0) >> 4) | ((~r & 0xC0) >> 6);
  286. mSPI.writeByte(top); mSPI.writeByte(b); mSPI.writeByte(g); mSPI.writeByte(r);
  287. }
  288. public:
  289. P9813Controller() {}
  290. virtual void init() {
  291. mSPI.init();
  292. }
  293. protected:
  294. virtual void showPixels(PixelController<RGB_ORDER> & pixels) {
  295. mSPI.select();
  296. writeBoundary();
  297. while(pixels.has(1)) {
  298. writeLed(pixels.loadAndScale0(), pixels.loadAndScale1(), pixels.loadAndScale2());
  299. pixels.advanceData();
  300. pixels.stepDithering();
  301. }
  302. writeBoundary();
  303. mSPI.waitFully();
  304. mSPI.release();
  305. }
  306. };
  307. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  308. //
  309. // SM16716 definition - takes data/clock/select pin values (N.B. should take an SPI definition?)
  310. //
  311. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  312. /// SM16716 controller class.
  313. /// @tparam DATA_PIN the data pin for these leds
  314. /// @tparam CLOCK_PIN the clock pin for these leds
  315. /// @tparam RGB_ORDER the RGB ordering for these leds
  316. /// @tparam SPI_SPEED the clock divider used for these leds. Set using the DATA_RATE_MHZ/DATA_RATE_KHZ macros. Defaults to DATA_RATE_MHZ(16)
  317. template <uint8_t DATA_PIN, uint8_t CLOCK_PIN, EOrder RGB_ORDER = RGB, uint32_t SPI_SPEED = DATA_RATE_MHZ(16)>
  318. class SM16716Controller : public CPixelLEDController<RGB_ORDER> {
  319. typedef SPIOutput<DATA_PIN, CLOCK_PIN, SPI_SPEED> SPI;
  320. SPI mSPI;
  321. void writeHeader() {
  322. // Write out 50 zeros to the spi line (6 blocks of 8 followed by two single bit writes)
  323. mSPI.select();
  324. mSPI.template writeBit<0>(0);
  325. mSPI.writeByte(0);
  326. mSPI.writeByte(0);
  327. mSPI.writeByte(0);
  328. mSPI.template writeBit<0>(0);
  329. mSPI.writeByte(0);
  330. mSPI.writeByte(0);
  331. mSPI.writeByte(0);
  332. mSPI.waitFully();
  333. mSPI.release();
  334. }
  335. public:
  336. SM16716Controller() {}
  337. virtual void init() {
  338. mSPI.init();
  339. }
  340. protected:
  341. virtual void showPixels(PixelController<RGB_ORDER> & pixels) {
  342. // Make sure the FLAG_START_BIT flag is set to ensure that an extra 1 bit is sent at the start
  343. // of each triplet of bytes for rgb data
  344. // writeHeader();
  345. mSPI.template writePixels<FLAG_START_BIT, DATA_NOP, RGB_ORDER>( pixels );
  346. writeHeader();
  347. }
  348. };
  349. /// @}
  350. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  351. //
  352. // Clockless template instantiations - see clockless.h for how the timing values are used
  353. //
  354. // Base template for clockless controllers. These controllers have 3 control points in their cycle for each bit.
  355. // At T=0 : the line is raised hi to start a bit
  356. // At T=T1 : the line is dropped low to transmit a zero bit
  357. // At T=T1+T2 : the line is dropped low to transmit a one bit
  358. // At T=T1+T2+T3 : the cycle is concluded (next bit can be sent)
  359. //
  360. // The units used for T1, T2, and T3 is nanoseconds.
  361. // For 8MHz/16MHz/24MHz frequencies, these values are also guaranteed
  362. // to be integral multiples of an 8MHz clock (125ns increments).
  363. //
  364. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  365. #ifdef FASTLED_HAS_CLOCKLESS
  366. /// @name clockless controllers
  367. /// Provides timing definitions for the variety of clockless controllers supplied by the library.
  368. /// @{
  369. // Allow clock that clockless controller is based on to have different
  370. // frequency than the CPU.
  371. #if !defined(CLOCKLESS_FREQUENCY)
  372. #define CLOCKLESS_FREQUENCY F_CPU
  373. #endif
  374. // We want to force all avr's to use the Trinket controller when running at 8Mhz, because even the 328's at 8Mhz
  375. // need the more tightly defined timeframes.
  376. #if (CLOCKLESS_FREQUENCY == 8000000 || CLOCKLESS_FREQUENCY == 16000000 || CLOCKLESS_FREQUENCY == 24000000) // || CLOCKLESS_FREQUENCY == 48000000 || CLOCKLESS_FREQUENCY == 96000000) // 125ns/clock
  377. #define FMUL (CLOCKLESS_FREQUENCY/8000000)
  378. // GE8822
  379. template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
  380. class GE8822Controller800Khz : public ClocklessController<DATA_PIN, 3 * FMUL, 5 * FMUL, 3 * FMUL, RGB_ORDER, 4> {};
  381. // LPD1886
  382. template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
  383. class LPD1886Controller1250Khz : public ClocklessController<DATA_PIN, 2 * FMUL, 3 * FMUL, 2 * FMUL, RGB_ORDER, 4> {};
  384. // LPD1886
  385. template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
  386. class LPD1886Controller1250Khz_8bit : public ClocklessController<DATA_PIN, 2 * FMUL, 3 * FMUL, 2 * FMUL, RGB_ORDER> {};
  387. // WS2811@800khz 2 clocks, 5 clocks, 3 clocks
  388. template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
  389. class WS2812Controller800Khz : public ClocklessController<DATA_PIN, 2 * FMUL, 5 * FMUL, 3 * FMUL, RGB_ORDER> {};
  390. template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
  391. class WS2811Controller800Khz : public ClocklessController<DATA_PIN, 3 * FMUL, 4 * FMUL, 3 * FMUL, RGB_ORDER> {};
  392. template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB> //not tested
  393. class WS2813Controller : public ClocklessController<DATA_PIN, 3 * FMUL, 4 * FMUL, 3 * FMUL, RGB_ORDER> {};
  394. template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
  395. class WS2811Controller400Khz : public ClocklessController<DATA_PIN, 4 * FMUL, 10 * FMUL, 6 * FMUL, RGB_ORDER> {};
  396. template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
  397. class SK6822Controller : public ClocklessController<DATA_PIN, 3 * FMUL, 8 * FMUL, 3 * FMUL, RGB_ORDER> {};
  398. template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
  399. class SM16703Controller : public ClocklessController<DATA_PIN, 3 * FMUL, 4 * FMUL, 3 * FMUL, RGB_ORDER> {};
  400. template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
  401. class SK6812Controller : public ClocklessController<DATA_PIN, 3 * FMUL, 3 * FMUL, 4 * FMUL, RGB_ORDER> {};
  402. template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
  403. class UCS1903Controller400Khz : public ClocklessController<DATA_PIN, 4 * FMUL, 12 * FMUL, 4 * FMUL, RGB_ORDER> {};
  404. template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
  405. class UCS1903BController800Khz : public ClocklessController<DATA_PIN, 2 * FMUL, 4 * FMUL, 4 * FMUL, RGB_ORDER> {};
  406. template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
  407. class UCS1904Controller800Khz : public ClocklessController<DATA_PIN, 3 * FMUL, 3 * FMUL, 4 * FMUL, RGB_ORDER> {};
  408. template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
  409. class UCS2903Controller : public ClocklessController<DATA_PIN, 2 * FMUL, 6 * FMUL, 2 * FMUL, RGB_ORDER> {};
  410. template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
  411. class TM1809Controller800Khz : public ClocklessController<DATA_PIN, 2 * FMUL, 5 * FMUL, 3 * FMUL, RGB_ORDER> {};
  412. template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
  413. class TM1803Controller400Khz : public ClocklessController<DATA_PIN, 6 * FMUL, 9 * FMUL, 6 * FMUL, RGB_ORDER> {};
  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, 0, true, 500> {};
  416. template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
  417. class GW6205Controller400Khz : public ClocklessController<DATA_PIN, 6 * FMUL, 7 * FMUL, 6 * FMUL, RGB_ORDER, 4> {};
  418. template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
  419. class GW6205Controller800Khz : public ClocklessController<DATA_PIN, 2 * FMUL, 4 * FMUL, 4 * FMUL, RGB_ORDER, 4> {};
  420. template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
  421. class PL9823Controller : public ClocklessController<DATA_PIN, 3 * FMUL, 8 * FMUL, 3 * FMUL, RGB_ORDER> {};
  422. #else
  423. // Similar to NS() macro, this calculates the number of cycles for
  424. // the clockless chipset (which may differ from CPU cycles)
  425. #ifdef FASTLED_TEENSY4
  426. // just use raw nanosecond values for the teensy4
  427. #define C_NS(_NS) _NS
  428. #else
  429. #define C_NS(_NS) (((_NS * ((CLOCKLESS_FREQUENCY / 1000000L)) + 999)) / 1000)
  430. #endif
  431. // GE8822 - 350ns 660ns 350ns
  432. template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
  433. class GE8822Controller800Khz : public ClocklessController<DATA_PIN, C_NS(350), C_NS(660), C_NS(350), RGB_ORDER, 4> {};
  434. // GW6205@400khz - 800ns, 800ns, 800ns
  435. template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
  436. class GW6205Controller400Khz : public ClocklessController<DATA_PIN, C_NS(800), C_NS(800), C_NS(800), RGB_ORDER, 4> {};
  437. // GW6205@400khz - 400ns, 400ns, 400ns
  438. template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
  439. class GW6205Controller800Khz : public ClocklessController<DATA_PIN, C_NS(400), C_NS(400), C_NS(400), RGB_ORDER, 4> {};
  440. // UCS1903 - 500ns, 1500ns, 500ns
  441. template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
  442. class UCS1903Controller400Khz : public ClocklessController<DATA_PIN, C_NS(500), C_NS(1500), C_NS(500), RGB_ORDER> {};
  443. // UCS1903B - 400ns, 450ns, 450ns
  444. template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
  445. class UCS1903BController800Khz : public ClocklessController<DATA_PIN, C_NS(400), C_NS(450), C_NS(450), RGB_ORDER> {};
  446. // UCS1904 - 400ns, 400ns, 450ns
  447. template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
  448. class UCS1904Controller800Khz : public ClocklessController<DATA_PIN, C_NS(400), C_NS(400), C_NS(450), RGB_ORDER> {};
  449. // UCS2903 - 250ns, 750ns, 250ns
  450. template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
  451. class UCS2903Controller : public ClocklessController<DATA_PIN, C_NS(250), C_NS(750), C_NS(250), RGB_ORDER> {};
  452. // TM1809 - 350ns, 350ns, 550ns
  453. template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
  454. class TM1809Controller800Khz : public ClocklessController<DATA_PIN, C_NS(350), C_NS(350), C_NS(450), RGB_ORDER> {};
  455. // WS2811 - 320ns, 320ns, 640ns
  456. template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
  457. class WS2811Controller800Khz : public ClocklessController<DATA_PIN, C_NS(320), C_NS(320), C_NS(640), RGB_ORDER> {};
  458. // WS2813 - 320ns, 320ns, 640ns
  459. template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
  460. class WS2813Controller : public ClocklessController<DATA_PIN, C_NS(320), C_NS(320), C_NS(640), RGB_ORDER> {};
  461. // WS2812 - 250ns, 625ns, 375ns
  462. template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
  463. class WS2812Controller800Khz : public ClocklessController<DATA_PIN, C_NS(250), C_NS(625), C_NS(375), RGB_ORDER> {};
  464. // WS2811@400khz - 800ns, 800ns, 900ns
  465. template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
  466. class WS2811Controller400Khz : public ClocklessController<DATA_PIN, C_NS(800), C_NS(800), C_NS(900), RGB_ORDER> {};
  467. // 750NS, 750NS, 750NS
  468. template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
  469. class TM1803Controller400Khz : public ClocklessController<DATA_PIN, C_NS(700), C_NS(1100), C_NS(700), RGB_ORDER> {};
  470. template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
  471. class TM1829Controller800Khz : public ClocklessController<DATA_PIN, C_NS(340), C_NS(340), C_NS(550), RGB_ORDER, 0, true, 500> {};
  472. template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
  473. class TM1829Controller1600Khz : public ClocklessController<DATA_PIN, C_NS(100), C_NS(300), C_NS(200), RGB_ORDER, 0, true, 500> {};
  474. template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
  475. class LPD1886Controller1250Khz : public ClocklessController<DATA_PIN, C_NS(200), C_NS(400), C_NS(200), RGB_ORDER, 4> {};
  476. template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
  477. class LPD1886Controller1250Khz_8bit : public ClocklessController<DATA_PIN, C_NS(200), C_NS(400), C_NS(200), RGB_ORDER> {};
  478. template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
  479. class SK6822Controller : public ClocklessController<DATA_PIN, C_NS(375), C_NS(1000), C_NS(375), RGB_ORDER> {};
  480. template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
  481. class SK6812Controller : public ClocklessController<DATA_PIN, C_NS(300), C_NS(300), C_NS(600), RGB_ORDER> {};
  482. template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
  483. class SM16703Controller : public ClocklessController<DATA_PIN, C_NS(300), C_NS(600), C_NS(300), RGB_ORDER> {};
  484. template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
  485. class PL9823Controller : public ClocklessController<DATA_PIN, C_NS(350), C_NS(1010), C_NS(350), RGB_ORDER> {};
  486. #endif
  487. ///@}
  488. #endif
  489. ///@}
  490. FASTLED_NAMESPACE_END
  491. #endif