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.

593 lines
31KB

  1. #ifndef __INC_FASTSPI_LED2_H
  2. #define __INC_FASTSPI_LED2_H
  3. ///@file FastLED.h
  4. /// central include file for FastLED, defines the CFastLED class/object
  5. #if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)
  6. #define FASTLED_HAS_PRAGMA_MESSAGE
  7. #endif
  8. #define FASTLED_VERSION 3003002
  9. #ifndef FASTLED_INTERNAL
  10. # ifdef FASTLED_HAS_PRAGMA_MESSAGE
  11. # pragma message "FastLED version 3.003.003"
  12. # else
  13. # warning FastLED version 3.003.003 (Not really a warning, just telling you here.)
  14. # endif
  15. #endif
  16. #ifndef __PROG_TYPES_COMPAT__
  17. #define __PROG_TYPES_COMPAT__
  18. #endif
  19. #ifdef SmartMatrix_h
  20. #include <SmartMatrix.h>
  21. #endif
  22. #ifdef DmxSimple_h
  23. #include <DmxSimple.h>
  24. #endif
  25. #ifdef DmxSerial_h
  26. #include <DMXSerial.h>
  27. #endif
  28. #include <stdint.h>
  29. #include "cpp_compat.h"
  30. #include "fastled_config.h"
  31. #include "led_sysdefs.h"
  32. // Utility functions
  33. #include "fastled_delay.h"
  34. #include "bitswap.h"
  35. #include "controller.h"
  36. #include "fastpin.h"
  37. #include "fastspi_types.h"
  38. #include "dmx.h"
  39. #include "platforms.h"
  40. #include "fastled_progmem.h"
  41. #include "lib8tion.h"
  42. #include "pixeltypes.h"
  43. #include "hsv2rgb.h"
  44. #include "colorutils.h"
  45. #include "pixelset.h"
  46. #include "colorpalettes.h"
  47. #include "noise.h"
  48. #include "power_mgt.h"
  49. #include "fastspi.h"
  50. #include "chipsets.h"
  51. FASTLED_NAMESPACE_BEGIN
  52. /// definitions for the spi chipset constants
  53. enum ESPIChipsets {
  54. LPD6803,
  55. LPD8806,
  56. WS2801,
  57. WS2803,
  58. SM16716,
  59. P9813,
  60. APA102,
  61. SK9822,
  62. DOTSTAR
  63. };
  64. enum ESM { SMART_MATRIX };
  65. enum OWS2811 { OCTOWS2811,OCTOWS2811_400, OCTOWS2813};
  66. enum SWS2812 { WS2812SERIAL };
  67. #ifdef HAS_PIXIE
  68. template<uint8_t DATA_PIN, EOrder RGB_ORDER> class PIXIE : public PixieController<DATA_PIN, RGB_ORDER> {};
  69. #endif
  70. #ifdef FASTLED_HAS_CLOCKLESS
  71. template<uint8_t DATA_PIN> class NEOPIXEL : public WS2812Controller800Khz<DATA_PIN, GRB> {};
  72. template<uint8_t DATA_PIN, EOrder RGB_ORDER> class SM16703 : public SM16703Controller<DATA_PIN, RGB_ORDER> {};
  73. template<uint8_t DATA_PIN, EOrder RGB_ORDER> class TM1829 : public TM1829Controller800Khz<DATA_PIN, RGB_ORDER> {};
  74. template<uint8_t DATA_PIN, EOrder RGB_ORDER> class TM1812 : public TM1809Controller800Khz<DATA_PIN, RGB_ORDER> {};
  75. template<uint8_t DATA_PIN, EOrder RGB_ORDER> class TM1809 : public TM1809Controller800Khz<DATA_PIN, RGB_ORDER> {};
  76. template<uint8_t DATA_PIN, EOrder RGB_ORDER> class TM1804 : public TM1809Controller800Khz<DATA_PIN, RGB_ORDER> {};
  77. template<uint8_t DATA_PIN, EOrder RGB_ORDER> class TM1803 : public TM1803Controller400Khz<DATA_PIN, RGB_ORDER> {};
  78. template<uint8_t DATA_PIN, EOrder RGB_ORDER> class UCS1903 : public UCS1903Controller400Khz<DATA_PIN, RGB_ORDER> {};
  79. template<uint8_t DATA_PIN, EOrder RGB_ORDER> class UCS1903B : public UCS1903BController800Khz<DATA_PIN, RGB_ORDER> {};
  80. template<uint8_t DATA_PIN, EOrder RGB_ORDER> class UCS1904 : public UCS1904Controller800Khz<DATA_PIN, RGB_ORDER> {};
  81. template<uint8_t DATA_PIN, EOrder RGB_ORDER> class UCS2903 : public UCS2903Controller<DATA_PIN, RGB_ORDER> {};
  82. template<uint8_t DATA_PIN, EOrder RGB_ORDER> class WS2812 : public WS2812Controller800Khz<DATA_PIN, RGB_ORDER> {};
  83. template<uint8_t DATA_PIN, EOrder RGB_ORDER> class WS2852 : public WS2812Controller800Khz<DATA_PIN, RGB_ORDER> {};
  84. template<uint8_t DATA_PIN, EOrder RGB_ORDER> class WS2812B : public WS2812Controller800Khz<DATA_PIN, RGB_ORDER> {};
  85. template<uint8_t DATA_PIN, EOrder RGB_ORDER> class GS1903 : public WS2812Controller800Khz<DATA_PIN, RGB_ORDER> {};
  86. template<uint8_t DATA_PIN, EOrder RGB_ORDER> class SK6812 : public SK6812Controller<DATA_PIN, RGB_ORDER> {};
  87. template<uint8_t DATA_PIN, EOrder RGB_ORDER> class SK6822 : public SK6822Controller<DATA_PIN, RGB_ORDER> {};
  88. template<uint8_t DATA_PIN, EOrder RGB_ORDER> class APA106 : public SK6822Controller<DATA_PIN, RGB_ORDER> {};
  89. template<uint8_t DATA_PIN, EOrder RGB_ORDER> class PL9823 : public PL9823Controller<DATA_PIN, RGB_ORDER> {};
  90. template<uint8_t DATA_PIN, EOrder RGB_ORDER> class WS2811 : public WS2811Controller800Khz<DATA_PIN, RGB_ORDER> {};
  91. template<uint8_t DATA_PIN, EOrder RGB_ORDER> class WS2813 : public WS2813Controller<DATA_PIN, RGB_ORDER> {};
  92. template<uint8_t DATA_PIN, EOrder RGB_ORDER> class APA104 : public WS2811Controller800Khz<DATA_PIN, RGB_ORDER> {};
  93. template<uint8_t DATA_PIN, EOrder RGB_ORDER> class WS2811_400 : public WS2811Controller400Khz<DATA_PIN, RGB_ORDER> {};
  94. template<uint8_t DATA_PIN, EOrder RGB_ORDER> class GE8822 : public GE8822Controller800Khz<DATA_PIN, RGB_ORDER> {};
  95. template<uint8_t DATA_PIN, EOrder RGB_ORDER> class GW6205 : public GW6205Controller800Khz<DATA_PIN, RGB_ORDER> {};
  96. template<uint8_t DATA_PIN, EOrder RGB_ORDER> class GW6205_400 : public GW6205Controller400Khz<DATA_PIN, RGB_ORDER> {};
  97. template<uint8_t DATA_PIN, EOrder RGB_ORDER> class LPD1886 : public LPD1886Controller1250Khz<DATA_PIN, RGB_ORDER> {};
  98. template<uint8_t DATA_PIN, EOrder RGB_ORDER> class LPD1886_8BIT : public LPD1886Controller1250Khz_8bit<DATA_PIN, RGB_ORDER> {};
  99. #ifdef DmxSimple_h
  100. template<uint8_t DATA_PIN, EOrder RGB_ORDER> class DMXSIMPLE : public DMXSimpleController<DATA_PIN, RGB_ORDER> {};
  101. #endif
  102. #ifdef DmxSerial_h
  103. template<EOrder RGB_ORDER> class DMXSERIAL : public DMXSerialController<RGB_ORDER> {};
  104. #endif
  105. #endif
  106. enum EBlockChipsets {
  107. #ifdef PORTA_FIRST_PIN
  108. WS2811_PORTA,
  109. WS2813_PORTA,
  110. WS2811_400_PORTA,
  111. TM1803_PORTA,
  112. UCS1903_PORTA,
  113. #endif
  114. #ifdef PORTB_FIRST_PIN
  115. WS2811_PORTB,
  116. WS2813_PORTB,
  117. WS2811_400_PORTB,
  118. TM1803_PORTB,
  119. UCS1903_PORTB,
  120. #endif
  121. #ifdef PORTC_FIRST_PIN
  122. WS2811_PORTC,
  123. WS2813_PORTC,
  124. WS2811_400_PORTC,
  125. TM1803_PORTC,
  126. UCS1903_PORTC,
  127. #endif
  128. #ifdef PORTD_FIRST_PIN
  129. WS2811_PORTD,
  130. WS2813_PORTD,
  131. WS2811_400_PORTD,
  132. TM1803_PORTD,
  133. UCS1903_PORTD,
  134. #endif
  135. #ifdef HAS_PORTDC
  136. WS2811_PORTDC,
  137. WS2813_PORTDC,
  138. WS2811_400_PORTDC,
  139. TM1803_PORTDC,
  140. UCS1903_PORTDC,
  141. #endif
  142. };
  143. #if defined(LIB8_ATTINY)
  144. #define NUM_CONTROLLERS 2
  145. #else
  146. #define NUM_CONTROLLERS 8
  147. #endif
  148. typedef uint8_t (*power_func)(uint8_t scale, uint32_t data);
  149. /// High level controller interface for FastLED. This class manages controllers, global settings and trackings
  150. /// such as brightness, and refresh rates, and provides access functions for driving led data to controllers
  151. /// via the show/showColor/clear methods.
  152. /// @nosubgrouping
  153. class CFastLED {
  154. // int m_nControllers;
  155. uint8_t m_Scale; ///< The current global brightness scale setting
  156. uint16_t m_nFPS; ///< Tracking for current FPS value
  157. uint32_t m_nMinMicros; ///< minimum µs between frames, used for capping frame rates.
  158. uint32_t m_nPowerData; ///< max power use parameter
  159. power_func m_pPowerFunc; ///< function for overriding brightness when using FastLED.show();
  160. public:
  161. CFastLED();
  162. /// Add a CLEDController instance to the world. Exposed to the public to allow people to implement their own
  163. /// CLEDController objects or instances. There are two ways to call this method (as well as the other addLeds)
  164. /// variations. The first is with 3 arguments, in which case the arguments are the controller, a pointer to
  165. /// led data, and the number of leds used by this controller. The second is with 4 arguments, in which case
  166. /// the first two arguments are the same, the third argument is an offset into the CRGB data where this controller's
  167. /// CRGB data begins, and the fourth argument is the number of leds for this controller object.
  168. /// @param pLed - the led controller being added
  169. /// @param data - base point to an array of CRGB data structures
  170. /// @param nLedsOrOffset - number of leds (3 argument version) or offset into the data array
  171. /// @param nLedsIfOffset - number of leds (4 argument version)
  172. /// @returns a reference to the added controller
  173. static CLEDController &addLeds(CLEDController *pLed, struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0);
  174. /// @name Adding SPI based controllers
  175. //@{
  176. /// Add an SPI based CLEDController instance to the world.
  177. /// There are two ways to call this method (as well as the other addLeds)
  178. /// variations. The first is with 2 arguments, in which case the arguments are a pointer to
  179. /// led data, and the number of leds used by this controller. The second is with 3 arguments, in which case
  180. /// the first argument is the same, the second argument is an offset into the CRGB data where this controller's
  181. /// CRGB data begins, and the third argument is the number of leds for this controller object.
  182. ///
  183. /// This method also takes a 1 to 5 template parameters for identifying the specific chipset, data and clock pins,
  184. /// RGB ordering, and SPI data rate
  185. /// @param data - base point to an array of CRGB data structures
  186. /// @param nLedsOrOffset - number of leds (3 argument version) or offset into the data array
  187. /// @param nLedsIfOffset - number of leds (4 argument version)
  188. /// @tparam CHIPSET - the chipset type
  189. /// @tparam DATA_PIN - the optional data pin for the leds (if omitted, will default to the first hardware SPI MOSI pin)
  190. /// @tparam CLOCK_PIN - the optional clock pin for the leds (if omitted, will default to the first hardware SPI clock pin)
  191. /// @tparam RGB_ORDER - the rgb ordering for the leds (e.g. what order red, green, and blue data is written out in)
  192. /// @tparam SPI_DATA_RATE - the data rate to drive the SPI clock at, defined using DATA_RATE_MHZ or DATA_RATE_KHZ macros
  193. /// @returns a reference to the added controller
  194. template<ESPIChipsets CHIPSET, uint8_t DATA_PIN, uint8_t CLOCK_PIN, EOrder RGB_ORDER, uint32_t SPI_DATA_RATE > CLEDController &addLeds(struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) {
  195. switch(CHIPSET) {
  196. case LPD6803: { static LPD6803Controller<DATA_PIN, CLOCK_PIN, RGB_ORDER, SPI_DATA_RATE> c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); }
  197. case LPD8806: { static LPD8806Controller<DATA_PIN, CLOCK_PIN, RGB_ORDER, SPI_DATA_RATE> c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); }
  198. case WS2801: { static WS2801Controller<DATA_PIN, CLOCK_PIN, RGB_ORDER, SPI_DATA_RATE> c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); }
  199. case WS2803: { static WS2803Controller<DATA_PIN, CLOCK_PIN, RGB_ORDER, SPI_DATA_RATE> c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); }
  200. case SM16716: { static SM16716Controller<DATA_PIN, CLOCK_PIN, RGB_ORDER, SPI_DATA_RATE> c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); }
  201. case P9813: { static P9813Controller<DATA_PIN, CLOCK_PIN, RGB_ORDER, SPI_DATA_RATE> c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); }
  202. case DOTSTAR:
  203. case APA102: { static APA102Controller<DATA_PIN, CLOCK_PIN, RGB_ORDER, SPI_DATA_RATE> c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); }
  204. case SK9822: { static SK9822Controller<DATA_PIN, CLOCK_PIN, RGB_ORDER, SPI_DATA_RATE> c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); }
  205. }
  206. }
  207. template<ESPIChipsets CHIPSET, uint8_t DATA_PIN, uint8_t CLOCK_PIN > static CLEDController &addLeds(struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) {
  208. switch(CHIPSET) {
  209. case LPD6803: { static LPD6803Controller<DATA_PIN, CLOCK_PIN> c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); }
  210. case LPD8806: { static LPD8806Controller<DATA_PIN, CLOCK_PIN> c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); }
  211. case WS2801: { static WS2801Controller<DATA_PIN, CLOCK_PIN> c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); }
  212. case WS2803: { static WS2803Controller<DATA_PIN, CLOCK_PIN> c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); }
  213. case SM16716: { static SM16716Controller<DATA_PIN, CLOCK_PIN> c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); }
  214. case P9813: { static P9813Controller<DATA_PIN, CLOCK_PIN> c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); }
  215. case DOTSTAR:
  216. case APA102: { static APA102Controller<DATA_PIN, CLOCK_PIN> c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); }
  217. case SK9822: { static SK9822Controller<DATA_PIN, CLOCK_PIN> c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); }
  218. }
  219. }
  220. template<ESPIChipsets CHIPSET, uint8_t DATA_PIN, uint8_t CLOCK_PIN, EOrder RGB_ORDER > static CLEDController &addLeds(struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) {
  221. switch(CHIPSET) {
  222. case LPD6803: { static LPD6803Controller<DATA_PIN, CLOCK_PIN, RGB_ORDER> c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); }
  223. case LPD8806: { static LPD8806Controller<DATA_PIN, CLOCK_PIN, RGB_ORDER> c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); }
  224. case WS2801: { static WS2801Controller<DATA_PIN, CLOCK_PIN, RGB_ORDER> c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); }
  225. case WS2803: { static WS2803Controller<DATA_PIN, CLOCK_PIN, RGB_ORDER> c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); }
  226. case SM16716: { static SM16716Controller<DATA_PIN, CLOCK_PIN, RGB_ORDER> c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); }
  227. case P9813: { static P9813Controller<DATA_PIN, CLOCK_PIN, RGB_ORDER> c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); }
  228. case DOTSTAR:
  229. case APA102: { static APA102Controller<DATA_PIN, CLOCK_PIN, RGB_ORDER> c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); }
  230. case SK9822: { static SK9822Controller<DATA_PIN, CLOCK_PIN, RGB_ORDER> c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); }
  231. }
  232. }
  233. #ifdef SPI_DATA
  234. template<ESPIChipsets CHIPSET> static CLEDController &addLeds(struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) {
  235. return addLeds<CHIPSET, SPI_DATA, SPI_CLOCK, RGB>(data, nLedsOrOffset, nLedsIfOffset);
  236. }
  237. template<ESPIChipsets CHIPSET, EOrder RGB_ORDER> static CLEDController &addLeds(struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) {
  238. return addLeds<CHIPSET, SPI_DATA, SPI_CLOCK, RGB_ORDER>(data, nLedsOrOffset, nLedsIfOffset);
  239. }
  240. template<ESPIChipsets CHIPSET, EOrder RGB_ORDER, uint32_t SPI_DATA_RATE> static CLEDController &addLeds(struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) {
  241. return addLeds<CHIPSET, SPI_DATA, SPI_CLOCK, RGB_ORDER, SPI_DATA_RATE>(data, nLedsOrOffset, nLedsIfOffset);
  242. }
  243. #endif
  244. //@}
  245. #ifdef FASTLED_HAS_CLOCKLESS
  246. /// @name Adding 3-wire led controllers
  247. //@{
  248. /// Add a clockless (aka 3wire, also DMX) based CLEDController instance to the world.
  249. /// There are two ways to call this method (as well as the other addLeds)
  250. /// variations. The first is with 2 arguments, in which case the arguments are a pointer to
  251. /// led data, and the number of leds used by this controller. The second is with 3 arguments, in which case
  252. /// the first argument is the same, the second argument is an offset into the CRGB data where this controller's
  253. /// CRGB data begins, and the third argument is the number of leds for this controller object.
  254. ///
  255. /// This method also takes a 2 to 3 template parameters for identifying the specific chipset, data pin, and rgb ordering
  256. /// RGB ordering, and SPI data rate
  257. /// @param data - base point to an array of CRGB data structures
  258. /// @param nLedsOrOffset - number of leds (3 argument version) or offset into the data array
  259. /// @param nLedsIfOffset - number of leds (4 argument version)
  260. /// @tparam CHIPSET - the chipset type (required)
  261. /// @tparam DATA_PIN - the optional data pin for the leds (required)
  262. /// @tparam RGB_ORDER - the rgb ordering for the leds (e.g. what order red, green, and blue data is written out in)
  263. /// @returns a reference to the added controller
  264. template<template<uint8_t DATA_PIN, EOrder RGB_ORDER> class CHIPSET, uint8_t DATA_PIN, EOrder RGB_ORDER>
  265. static CLEDController &addLeds(struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) {
  266. static CHIPSET<DATA_PIN, RGB_ORDER> c;
  267. return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset);
  268. }
  269. template<template<uint8_t DATA_PIN, EOrder RGB_ORDER> class CHIPSET, uint8_t DATA_PIN>
  270. static CLEDController &addLeds(struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) {
  271. static CHIPSET<DATA_PIN, RGB> c;
  272. return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset);
  273. }
  274. template<template<uint8_t DATA_PIN> class CHIPSET, uint8_t DATA_PIN>
  275. static CLEDController &addLeds(struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) {
  276. static CHIPSET<DATA_PIN> c;
  277. return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset);
  278. }
  279. #if defined(__FASTLED_HAS_FIBCC) && (__FASTLED_HAS_FIBCC == 1)
  280. template<uint8_t NUM_LANES, template<uint8_t DATA_PIN, EOrder RGB_ORDER> class CHIPSET, uint8_t DATA_PIN, EOrder RGB_ORDER=RGB>
  281. static CLEDController &addLeds(struct CRGB *data, int nLeds) {
  282. static __FIBCC<CHIPSET, DATA_PIN, NUM_LANES, RGB_ORDER> c;
  283. return addLeds(&c, data, nLeds);
  284. }
  285. #endif
  286. #ifdef FASTSPI_USE_DMX_SIMPLE
  287. template<EClocklessChipsets CHIPSET, uint8_t DATA_PIN, EOrder RGB_ORDER=RGB>
  288. static CLEDController &addLeds(struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0)
  289. {
  290. switch(CHIPSET) {
  291. case DMX: { static DMXController<DATA_PIN> controller; return addLeds(&controller, data, nLedsOrOffset, nLedsIfOffset); }
  292. }
  293. }
  294. #endif
  295. //@}
  296. #endif
  297. /// @name Adding 3rd party library controllers
  298. //@{
  299. /// Add a 3rd party library based CLEDController instance to the world.
  300. /// There are two ways to call this method (as well as the other addLeds)
  301. /// variations. The first is with 2 arguments, in which case the arguments are a pointer to
  302. /// led data, and the number of leds used by this controller. The second is with 3 arguments, in which case
  303. /// the first argument is the same, the second argument is an offset into the CRGB data where this controller's
  304. /// CRGB data begins, and the third argument is the number of leds for this controller object. This class includes the SmartMatrix
  305. /// and OctoWS2811 based controllers
  306. ///
  307. /// This method also takes a 1 to 2 template parameters for identifying the specific chipset and rgb ordering
  308. /// RGB ordering, and SPI data rate
  309. /// @param data - base point to an array of CRGB data structures
  310. /// @param nLedsOrOffset - number of leds (3 argument version) or offset into the data array
  311. /// @param nLedsIfOffset - number of leds (4 argument version)
  312. /// @tparam CHIPSET - the chipset type (required)
  313. /// @tparam RGB_ORDER - the rgb ordering for the leds (e.g. what order red, green, and blue data is written out in)
  314. /// @returns a reference to the added controller
  315. template<template<EOrder RGB_ORDER> class CHIPSET, EOrder RGB_ORDER>
  316. static CLEDController &addLeds(struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) {
  317. static CHIPSET<RGB_ORDER> c;
  318. return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset);
  319. }
  320. template<template<EOrder RGB_ORDER> class CHIPSET>
  321. static CLEDController &addLeds(struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) {
  322. static CHIPSET<RGB> c;
  323. return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset);
  324. }
  325. #ifdef USE_OCTOWS2811
  326. template<OWS2811 CHIPSET, EOrder RGB_ORDER>
  327. static CLEDController &addLeds(struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0)
  328. {
  329. switch(CHIPSET) {
  330. case OCTOWS2811: { static COctoWS2811Controller<RGB_ORDER,WS2811_800kHz> controller; return addLeds(&controller, data, nLedsOrOffset, nLedsIfOffset); }
  331. case OCTOWS2811_400: { static COctoWS2811Controller<RGB_ORDER,WS2811_400kHz> controller; return addLeds(&controller, data, nLedsOrOffset, nLedsIfOffset); }
  332. #ifdef WS2813_800kHz
  333. case OCTOWS2813: { static COctoWS2811Controller<RGB_ORDER,WS2813_800kHz> controller; return addLeds(&controller, data, nLedsOrOffset, nLedsIfOffset); }
  334. #endif
  335. }
  336. }
  337. template<OWS2811 CHIPSET>
  338. static CLEDController &addLeds(struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0)
  339. {
  340. return addLeds<CHIPSET,GRB>(data,nLedsOrOffset,nLedsIfOffset);
  341. }
  342. #endif
  343. #ifdef USE_WS2812SERIAL
  344. template<SWS2812 CHIPSET, int DATA_PIN, EOrder RGB_ORDER>
  345. static CLEDController &addLeds(struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0)
  346. {
  347. static CWS2812SerialController<DATA_PIN,RGB_ORDER> controller;
  348. return addLeds(&controller, data, nLedsOrOffset, nLedsIfOffset);
  349. }
  350. #endif
  351. #ifdef SmartMatrix_h
  352. template<ESM CHIPSET>
  353. static CLEDController &addLeds(struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0)
  354. {
  355. switch(CHIPSET) {
  356. case SMART_MATRIX: { static CSmartMatrixController controller; return addLeds(&controller, data, nLedsOrOffset, nLedsIfOffset); }
  357. }
  358. }
  359. #endif
  360. //@}
  361. #ifdef FASTLED_HAS_BLOCKLESS
  362. /// @name adding parallel output controllers
  363. //@{
  364. /// Add a block based CLEDController instance to the world.
  365. /// There are two ways to call this method (as well as the other addLeds)
  366. /// variations. The first is with 2 arguments, in which case the arguments are a pointer to
  367. /// led data, and the number of leds used by this controller. The second is with 3 arguments, in which case
  368. /// the first argument is the same, the second argument is an offset into the CRGB data where this controller's
  369. /// CRGB data begins, and the third argument is the number of leds for this controller object.
  370. ///
  371. /// This method also takes a 2 to 3 template parameters for identifying the specific chipset and rgb ordering
  372. /// RGB ordering, and SPI data rate
  373. /// @param data - base point to an array of CRGB data structures
  374. /// @param nLedsOrOffset - number of leds (3 argument version) or offset into the data array
  375. /// @param nLedsIfOffset - number of leds (4 argument version)
  376. /// @tparam CHIPSET - the chipset/port type (required)
  377. /// @tparam NUM_LANES - how many parallel lanes of output to write
  378. /// @tparam RGB_ORDER - the rgb ordering for the leds (e.g. what order red, green, and blue data is written out in)
  379. /// @returns a reference to the added controller
  380. template<EBlockChipsets CHIPSET, int NUM_LANES, EOrder RGB_ORDER>
  381. static CLEDController &addLeds(struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) {
  382. switch(CHIPSET) {
  383. #ifdef PORTA_FIRST_PIN
  384. case WS2811_PORTA: return addLeds(new InlineBlockClocklessController<NUM_LANES, PORTA_FIRST_PIN, NS(320), NS(320), NS(640), RGB_ORDER>(), data, nLedsOrOffset, nLedsIfOffset);
  385. case WS2811_400_PORTA: return addLeds(new InlineBlockClocklessController<NUM_LANES, PORTA_FIRST_PIN, NS(800), NS(800), NS(900), RGB_ORDER>(), data, nLedsOrOffset, nLedsIfOffset);
  386. case WS2813_PORTA: return addLeds(new InlineBlockClocklessController<NUM_LANES, PORTA_FIRST_PIN, NS(320), NS(320), NS(640), RGB_ORDER, 0, false, 300>(), data, nLedsOrOffset, nLedsIfOffset);
  387. case TM1803_PORTA: return addLeds(new InlineBlockClocklessController<NUM_LANES, PORTA_FIRST_PIN, NS(700), NS(1100), NS(700), RGB_ORDER>(), data, nLedsOrOffset, nLedsIfOffset);
  388. case UCS1903_PORTA: return addLeds(new InlineBlockClocklessController<NUM_LANES, PORTA_FIRST_PIN, NS(500), NS(1500), NS(500), RGB_ORDER>(), data, nLedsOrOffset, nLedsIfOffset);
  389. #endif
  390. #ifdef PORTB_FIRST_PIN
  391. case WS2811_PORTB: return addLeds(new InlineBlockClocklessController<NUM_LANES, PORTB_FIRST_PIN, NS(320), NS(320), NS(640), RGB_ORDER>(), data, nLedsOrOffset, nLedsIfOffset);
  392. case WS2811_400_PORTB: return addLeds(new InlineBlockClocklessController<NUM_LANES, PORTB_FIRST_PIN, NS(800), NS(800), NS(900), RGB_ORDER>(), data, nLedsOrOffset, nLedsIfOffset);
  393. case WS2813_PORTB: return addLeds(new InlineBlockClocklessController<NUM_LANES, PORTB_FIRST_PIN, NS(320), NS(320), NS(640), RGB_ORDER, 0, false, 300>(), data, nLedsOrOffset, nLedsIfOffset);
  394. case TM1803_PORTB: return addLeds(new InlineBlockClocklessController<NUM_LANES, PORTB_FIRST_PIN, NS(700), NS(1100), NS(700), RGB_ORDER>(), data, nLedsOrOffset, nLedsIfOffset);
  395. case UCS1903_PORTB: return addLeds(new InlineBlockClocklessController<NUM_LANES, PORTB_FIRST_PIN, NS(500), NS(1500), NS(500), RGB_ORDER>(), data, nLedsOrOffset, nLedsIfOffset);
  396. #endif
  397. #ifdef PORTC_FIRST_PIN
  398. case WS2811_PORTC: return addLeds(new InlineBlockClocklessController<NUM_LANES, PORTC_FIRST_PIN, NS(320), NS(320), NS(640), RGB_ORDER>(), data, nLedsOrOffset, nLedsIfOffset);
  399. case WS2811_400_PORTC: return addLeds(new InlineBlockClocklessController<NUM_LANES, PORTC_FIRST_PIN, NS(800), NS(800), NS(900), RGB_ORDER>(), data, nLedsOrOffset, nLedsIfOffset);
  400. case WS2813_PORTC: return addLeds(new InlineBlockClocklessController<NUM_LANES, PORTC_FIRST_PIN, NS(320), NS(320), NS(640), RGB_ORDER, 0, false, 300>(), data, nLedsOrOffset, nLedsIfOffset);
  401. case TM1803_PORTC: return addLeds(new InlineBlockClocklessController<NUM_LANES, PORTC_FIRST_PIN, NS(700), NS(1100), NS(700), RGB_ORDER>(), data, nLedsOrOffset, nLedsIfOffset);
  402. case UCS1903_PORTC: return addLeds(new InlineBlockClocklessController<NUM_LANES, PORTC_FIRST_PIN, NS(500), NS(1500), NS(500), RGB_ORDER>(), data, nLedsOrOffset, nLedsIfOffset);
  403. #endif
  404. #ifdef PORTD_FIRST_PIN
  405. case WS2811_PORTD: return addLeds(new InlineBlockClocklessController<NUM_LANES, PORTD_FIRST_PIN, NS(320), NS(320), NS(640), RGB_ORDER>(), data, nLedsOrOffset, nLedsIfOffset);
  406. case WS2811_400_PORTD: return addLeds(new InlineBlockClocklessController<NUM_LANES, PORTD_FIRST_PIN, NS(800), NS(800), NS(900), RGB_ORDER>(), data, nLedsOrOffset, nLedsIfOffset);
  407. case WS2813_PORTD: return addLeds(new InlineBlockClocklessController<NUM_LANES, PORTD_FIRST_PIN, NS(320), NS(320), NS(640), RGB_ORDER, 0, false, 300>(), data, nLedsOrOffset, nLedsIfOffset);
  408. case TM1803_PORTD: return addLeds(new InlineBlockClocklessController<NUM_LANES, PORTD_FIRST_PIN, NS(700), NS(1100), NS(700), RGB_ORDER>(), data, nLedsOrOffset, nLedsIfOffset);
  409. case UCS1903_PORTD: return addLeds(new InlineBlockClocklessController<NUM_LANES, PORTD_FIRST_PIN, NS(500), NS(1500), NS(500), RGB_ORDER>(), data, nLedsOrOffset, nLedsIfOffset);
  410. #endif
  411. #ifdef HAS_PORTDC
  412. case WS2811_PORTDC: return addLeds(new SixteenWayInlineBlockClocklessController<NUM_LANES,NS(320), NS(320), NS(640), RGB_ORDER>(), data, nLedsOrOffset, nLedsIfOffset);
  413. case WS2811_400_PORTDC: return addLeds(new SixteenWayInlineBlockClocklessController<NUM_LANES,NS(800), NS(800), NS(900), RGB_ORDER>(), data, nLedsOrOffset, nLedsIfOffset);
  414. case WS2813_PORTDC: return addLeds(new SixteenWayInlineBlockClocklessController<NUM_LANES, NS(320), NS(320), NS(640), RGB_ORDER, 0, false, 300>(), data, nLedsOrOffset, nLedsIfOffset);
  415. case TM1803_PORTDC: return addLeds(new SixteenWayInlineBlockClocklessController<NUM_LANES, NS(700), NS(1100), NS(700), RGB_ORDER>(), data, nLedsOrOffset, nLedsIfOffset);
  416. case UCS1903_PORTDC: return addLeds(new SixteenWayInlineBlockClocklessController<NUM_LANES, NS(500), NS(1500), NS(500), RGB_ORDER>(), data, nLedsOrOffset, nLedsIfOffset);
  417. #endif
  418. }
  419. }
  420. template<EBlockChipsets CHIPSET, int NUM_LANES>
  421. static CLEDController &addLeds(struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) {
  422. return addLeds<CHIPSET,NUM_LANES,GRB>(data,nLedsOrOffset,nLedsIfOffset);
  423. }
  424. //@}
  425. #endif
  426. /// Set the global brightness scaling
  427. /// @param scale a 0-255 value for how much to scale all leds before writing them out
  428. void setBrightness(uint8_t scale) { m_Scale = scale; }
  429. /// Get the current global brightness setting
  430. /// @returns the current global brightness value
  431. uint8_t getBrightness() { return m_Scale; }
  432. /// Set the maximum power to be used, given in volts and milliamps.
  433. /// @param volts - how many volts the leds are being driven at (usually 5)
  434. /// @param milliamps - the maximum milliamps of power draw you want
  435. inline void setMaxPowerInVoltsAndMilliamps(uint8_t volts, uint32_t milliamps) { setMaxPowerInMilliWatts(volts * milliamps); }
  436. /// Set the maximum power to be used, given in milliwatts
  437. /// @param milliwatts - the max power draw desired, in milliwatts
  438. inline void setMaxPowerInMilliWatts(uint32_t milliwatts) { m_pPowerFunc = &calculate_max_brightness_for_power_mW; m_nPowerData = milliwatts; }
  439. /// Update all our controllers with the current led colors, using the passed in brightness
  440. /// @param scale temporarily override the scale
  441. void show(uint8_t scale);
  442. /// Update all our controllers with the current led colors
  443. void show() { show(m_Scale); }
  444. /// clear the leds, wiping the local array of data, optionally black out the leds as well
  445. /// @param writeData whether or not to write out to the leds as well
  446. void clear(bool writeData = false);
  447. /// clear out the local data array
  448. void clearData();
  449. /// Set all leds on all controllers to the given color/scale
  450. /// @param color what color to set the leds to
  451. /// @param scale what brightness scale to show at
  452. void showColor(const struct CRGB & color, uint8_t scale);
  453. /// Set all leds on all controllers to the given color
  454. /// @param color what color to set the leds to
  455. void showColor(const struct CRGB & color) { showColor(color, m_Scale); }
  456. /// Delay for the given number of milliseconds. Provided to allow the library to be used on platforms
  457. /// that don't have a delay function (to allow code to be more portable). Note: this will call show
  458. /// constantly to drive the dithering engine (and will call show at least once).
  459. /// @param ms the number of milliseconds to pause for
  460. void delay(unsigned long ms);
  461. /// Set a global color temperature. Sets the color temperature for all added led strips, overriding whatever
  462. /// previous color temperature those controllers may have had
  463. /// @param temp A CRGB structure describing the color temperature
  464. void setTemperature(const struct CRGB & temp);
  465. /// Set a global color correction. Sets the color correction for all added led strips,
  466. /// overriding whatever previous color correction those controllers may have had.
  467. /// @param correction A CRGB structure describin the color correction.
  468. void setCorrection(const struct CRGB & correction);
  469. /// Set the dithering mode. Sets the dithering mode for all added led strips, overriding
  470. /// whatever previous dithering option those controllers may have had.
  471. /// @param ditherMode - what type of dithering to use, either BINARY_DITHER or DISABLE_DITHER
  472. void setDither(uint8_t ditherMode = BINARY_DITHER);
  473. /// Set the maximum refresh rate. This is global for all leds. Attempts to
  474. /// call show faster than this rate will simply wait. Note that the refresh rate
  475. /// defaults to the slowest refresh rate of all the leds added through addLeds. If
  476. /// you wish to set/override this rate, be sure to call setMaxRefreshRate _after_
  477. /// adding all of your leds.
  478. /// @param refresh - maximum refresh rate in hz
  479. /// @param constrain - constrain refresh rate to the slowest speed yet set
  480. void setMaxRefreshRate(uint16_t refresh, bool constrain=false);
  481. /// for debugging, will keep track of time between calls to countFPS, and every
  482. /// nFrames calls, it will update an internal counter for the current FPS.
  483. /// @todo make this a rolling counter
  484. /// @param nFrames - how many frames to time for determining FPS
  485. void countFPS(int nFrames=25);
  486. /// Get the number of frames/second being written out
  487. /// @returns the most recently computed FPS value
  488. uint16_t getFPS() { return m_nFPS; }
  489. /// Get how many controllers have been registered
  490. /// @returns the number of controllers (strips) that have been added with addLeds
  491. int count();
  492. /// Get a reference to a registered controller
  493. /// @returns a reference to the Nth controller
  494. CLEDController & operator[](int x);
  495. /// Get the number of leds in the first controller
  496. /// @returns the number of LEDs in the first controller
  497. int size() { return (*this)[0].size(); }
  498. /// Get a pointer to led data for the first controller
  499. /// @returns pointer to the CRGB buffer for the first controller
  500. CRGB *leds() { return (*this)[0].leds(); }
  501. };
  502. #define FastSPI_LED FastLED
  503. #define FastSPI_LED2 FastLED
  504. #ifndef LEDS
  505. #define LEDS FastLED
  506. #endif
  507. extern CFastLED FastLED;
  508. // Warnings for undefined things
  509. #ifndef HAS_HARDWARE_PIN_SUPPORT
  510. #warning "No pin/port mappings found, pin access will be slightly slower. See fastpin.h for info."
  511. #define NO_HARDWARE_PIN_SUPPORT
  512. #endif
  513. FASTLED_NAMESPACE_END
  514. #endif