First commit.

This commit is contained in:
Fabian Schlenz 2020-07-17 18:55:06 +02:00
commit b47a0ab935
247 changed files with 30192 additions and 0 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
.pio/build/local/firmware.elf Executable file

Binary file not shown.

View File

@ -0,0 +1,265 @@
/* This linker script generated from xt-genldscripts.tpp for LSP . */
/* Linker Script for ld -N */
PHDRS
{
dport0_0_phdr PT_LOAD;
dram0_0_phdr PT_LOAD;
dram0_0_bss_phdr PT_LOAD;
iram1_0_phdr PT_LOAD;
irom0_0_phdr PT_LOAD;
}
/* Default entry point: */
ENTRY(app_entry)
EXTERN(_DebugExceptionVector)
EXTERN(_DoubleExceptionVector)
EXTERN(_KernelExceptionVector)
EXTERN(_NMIExceptionVector)
EXTERN(_UserExceptionVector)
EXTERN(core_version)
PROVIDE(_memmap_vecbase_reset = 0x40000000);
/* Various memory-map dependent cache attribute settings: */
_memmap_cacheattr_wb_base = 0x00000110;
_memmap_cacheattr_wt_base = 0x00000110;
_memmap_cacheattr_bp_base = 0x00000220;
_memmap_cacheattr_unused_mask = 0xFFFFF00F;
_memmap_cacheattr_wb_trapnull = 0x2222211F;
_memmap_cacheattr_wba_trapnull = 0x2222211F;
_memmap_cacheattr_wbna_trapnull = 0x2222211F;
_memmap_cacheattr_wt_trapnull = 0x2222211F;
_memmap_cacheattr_bp_trapnull = 0x2222222F;
_memmap_cacheattr_wb_strict = 0xFFFFF11F;
_memmap_cacheattr_wt_strict = 0xFFFFF11F;
_memmap_cacheattr_bp_strict = 0xFFFFF22F;
_memmap_cacheattr_wb_allvalid = 0x22222112;
_memmap_cacheattr_wt_allvalid = 0x22222112;
_memmap_cacheattr_bp_allvalid = 0x22222222;
PROVIDE(_memmap_cacheattr_reset = _memmap_cacheattr_wb_trapnull);
SECTIONS
{
.dport0.rodata : ALIGN(4)
{
_dport0_rodata_start = ABSOLUTE(.);
*(.dport0.rodata)
*(.dport.rodata)
_dport0_rodata_end = ABSOLUTE(.);
} >dport0_0_seg :dport0_0_phdr
.dport0.literal : ALIGN(4)
{
_dport0_literal_start = ABSOLUTE(.);
*(.dport0.literal)
*(.dport.literal)
_dport0_literal_end = ABSOLUTE(.);
} >dport0_0_seg :dport0_0_phdr
.dport0.data : ALIGN(4)
{
_dport0_data_start = ABSOLUTE(.);
*(.dport0.data)
*(.dport.data)
_dport0_data_end = ABSOLUTE(.);
} >dport0_0_seg :dport0_0_phdr
.data : ALIGN(4)
{
_data_start = ABSOLUTE(.);
*(.data)
*(.data.*)
*(.gnu.linkonce.d.*)
*(.data1)
*(.sdata)
*(.sdata.*)
*(.gnu.linkonce.s.*)
*(.sdata2)
*(.sdata2.*)
*(.gnu.linkonce.s2.*)
*(.jcr)
. = ALIGN(4);
_Pri_3_HandlerAddress = ABSOLUTE(.);
_data_end = ABSOLUTE(.);
} >dram0_0_seg :dram0_0_phdr
.noinit : ALIGN(4)
{
*(.noinit)
} >dram0_0_seg :dram0_0_phdr
/* IRAM is split into .text and .text1 to allow for moving specific */
/* functions into IRAM that would be matched by the irom0.text matcher */
.text : ALIGN(4)
{
_stext = .;
_text_start = ABSOLUTE(.);
*(.UserEnter.text)
. = ALIGN(16);
*(.DebugExceptionVector.text)
. = ALIGN(16);
*(.NMIExceptionVector.text)
. = ALIGN(16);
*(.KernelExceptionVector.text)
LONG(0)
LONG(0)
LONG(0)
LONG(0)
. = ALIGN(16);
*(.UserExceptionVector.text)
LONG(0)
LONG(0)
LONG(0)
LONG(0)
. = ALIGN(16);
*(.DoubleExceptionVector.text)
LONG(0)
LONG(0)
LONG(0)
LONG(0)
. = ALIGN (16);
*(.entry.text)
*(.init.literal)
*(.init)
*(.text.app_entry*) /* The main startup code */
*(.text.gdbstub*, .text.gdb_init) /* Any GDB hooks */
/* all functional callers are placed in IRAM (including SPI/IRQ callbacks/etc) here */
*(.text._ZNKSt8functionIF*EE*) /* std::function<any(...)>::operator()() const */
} >iram1_0_seg :iram1_0_phdr
.irom0.text : ALIGN(4)
{
_irom0_text_start = ABSOLUTE(.);
*(.ver_number)
*.c.o(.literal*, .text*)
*.cpp.o(EXCLUDE_FILE (umm_malloc.cpp.o) .literal*, EXCLUDE_FILE (umm_malloc.cpp.o) .text*)
*.cc.o(.literal*, .text*)
*(.rodata._ZTV*) /* C++ vtables */
*libgcc.a:unwind-dw2.o(.literal .text .rodata .literal.* .text.* .rodata.*)
*libgcc.a:unwind-dw2-fde.o(.literal .text .rodata .literal.* .text.* .rodata.*)
*libc.a:(.literal .text .literal.* .text.*)
*libm.a:(.literal .text .literal.* .text.*)
*libgcc.a:_umoddi3.o(.literal .text)
*libgcc.a:_udivdi3.o(.literal .text)
*libstdc++.a:( .literal .text .literal.* .text.*)
*libstdc++-exc.a:( .literal .text .literal.* .text.*)
*libsmartconfig.a:(.literal .text .literal.* .text.*)
*liblwip_gcc.a:(.literal .text .literal.* .text.*)
*liblwip_src.a:(.literal .text .literal.* .text.*)
*liblwip2-536.a:(.literal .text .literal.* .text.*)
*liblwip2-1460.a:(.literal .text .literal.* .text.*)
*liblwip2-536-feat.a:(.literal .text .literal.* .text.*)
*liblwip2-1460-feat.a:(.literal .text .literal.* .text.*)
*liblwip6-536-feat.a:(.literal .text .literal.* .text.*)
*liblwip6-1460-feat.a:(.literal .text .literal.* .text.*)
*libbearssl.a:(.literal .text .literal.* .text.*)
*libaxtls.a:(.literal .text .literal.* .text.*)
*libat.a:(.literal.* .text.*)
*libcrypto.a:(.literal.* .text.*)
*libespnow.a:(.literal.* .text.*)
*libjson.a:(.literal.* .text.*)
*liblwip.a:(.literal.* .text.*)
*libmesh.a:(.literal.* .text.*)
*libnet80211.a:(.literal.* .text.*)
*libsmartconfig.a:(.literal.* .text.*)
*libssl.a:(.literal.* .text.*)
*libupgrade.a:(.literal.* .text.*)
*libwpa.a:(.literal.* .text.*)
*libwpa2.a:(.literal.* .text.*)
*libwps.a:(.literal.* .text.*)
*(.irom0.literal .irom.literal .irom.text.literal .irom0.text .irom0.text.* .irom.text .irom.text.*)
/* Constant strings in flash (PSTRs) */
*(.irom0.pstr.*)
/* __FUNCTION__ locals */
*(.rodata._ZZ*__FUNCTION__)
*(.rodata._ZZ*__PRETTY_FUNCTION__)
*(.rodata._ZZ*__func__)
/* std::* exception strings, in their own section to allow string coalescing */
*(.irom.exceptiontext)
/* c++ typeof IDs, etc. */
*(.rodata._ZTIN* .rodata._ZTSN10* .rodata._ZTISt* .rodata._ZTSSt*)
/* Fundamental type info */
*(.rodata._ZTIPKc .rodata._ZTIc .rodata._ZTIv .rodata._ZTSv .rodata._ZTSc .rodata._ZTSPKc .rodata._ZTSi .rodata._ZTIi)
. = ALIGN(4);
*(.gcc_except_table .gcc_except_table.*)
. = ALIGN(4);
__eh_frame = ABSOLUTE(.);
KEEP(*(.eh_frame))
. = (. + 7) & ~ 3; /* Add a 0 entry to terminate the list */
_irom0_text_end = ABSOLUTE(.);
_flash_code_end = ABSOLUTE(.);
} >irom0_0_seg :irom0_0_phdr
.text1 : ALIGN(4)
{
*(.literal .text .iram.literal .iram.text .iram.text.* .literal.* .text.* .stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*)
*(.fini.literal)
*(.fini)
*(.gnu.version)
_text_end = ABSOLUTE(.);
_etext = .;
} >iram1_0_seg :iram1_0_phdr
.rodata : ALIGN(4)
{
_rodata_start = ABSOLUTE(.);
*(.sdk.version)
*(.rodata)
*(.rodata.*)
*(.gnu.linkonce.r.*)
*(.rodata1)
__XT_EXCEPTION_TABLE__ = ABSOLUTE(.);
*(.xt_except_table)
*(.gcc_except_table)
*(.gnu.linkonce.e.*)
*(.gnu.version_r)
*(.eh_frame)
. = (. + 3) & ~ 3;
/* C++ constructor and destructor tables, properly ordered: */
__init_array_start = ABSOLUTE(.);
KEEP (*crtbegin.o(.ctors))
KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*(.ctors))
__init_array_end = ABSOLUTE(.);
KEEP (*crtbegin.o(.dtors))
KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*(.dtors))
/* C++ exception handlers table: */
__XT_EXCEPTION_DESCS__ = ABSOLUTE(.);
*(.xt_except_desc)
*(.gnu.linkonce.h.*)
__XT_EXCEPTION_DESCS_END__ = ABSOLUTE(.);
*(.xt_except_desc_end)
*(.dynamic)
*(.gnu.version_d)
. = ALIGN(4); /* this table MUST be 4-byte aligned */
_bss_table_start = ABSOLUTE(.);
LONG(_bss_start)
LONG(_bss_end)
_bss_table_end = ABSOLUTE(.);
_rodata_end = ABSOLUTE(.);
} >dram0_0_seg :dram0_0_phdr
.bss ALIGN(8) (NOLOAD) : ALIGN(4)
{
. = ALIGN (8);
_bss_start = ABSOLUTE(.);
*(.dynsbss)
*(.sbss)
*(.sbss.*)
*(.gnu.linkonce.sb.*)
*(.scommon)
*(.sbss2)
*(.sbss2.*)
*(.gnu.linkonce.sb2.*)
*(.dynbss)
*(.bss)
*(.bss.*)
*(.gnu.linkonce.b.*)
*(COMMON)
. = ALIGN (8);
_bss_end = ABSOLUTE(.);
_heap_start = ABSOLUTE(.);
/* _stack_sentry = ALIGN(0x8); */
} >dram0_0_seg :dram0_0_bss_phdr
/* __stack = 0x3ffc8000; */
.lit4 : ALIGN(4)
{
_lit4_start = ABSOLUTE(.);
*(*.lit4)
*(.lit4.*)
*(.gnu.linkonce.lit4.*)
_lit4_end = ABSOLUTE(.);
} >iram1_0_seg :iram1_0_phdr
}
/* get ROM code address */
INCLUDE "../ld/eagle.rom.addr.v6.ld"

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1 @@
!<arch>

Binary file not shown.

View File

@ -0,0 +1 @@
d7256f1c9af796447905fc683b9cf32e6e64f50c

2
.pio/libdeps/local/FastLED/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
html/
*.gch

View File

@ -0,0 +1,275 @@
#define FASTLED_INTERNAL
#include "FastLED.h"
#if defined(__SAM3X8E__)
volatile uint32_t fuckit;
#endif
FASTLED_NAMESPACE_BEGIN
void *pSmartMatrix = NULL;
CFastLED FastLED;
CLEDController *CLEDController::m_pHead = NULL;
CLEDController *CLEDController::m_pTail = NULL;
static uint32_t lastshow = 0;
uint32_t _frame_cnt=0;
uint32_t _retry_cnt=0;
// uint32_t CRGB::Squant = ((uint32_t)((__TIME__[4]-'0') * 28))<<16 | ((__TIME__[6]-'0')*50)<<8 | ((__TIME__[7]-'0')*28);
CFastLED::CFastLED() {
// clear out the array of led controllers
// m_nControllers = 0;
m_Scale = 255;
m_nFPS = 0;
m_pPowerFunc = NULL;
m_nPowerData = 0xFFFFFFFF;
}
CLEDController &CFastLED::addLeds(CLEDController *pLed,
struct CRGB *data,
int nLedsOrOffset, int nLedsIfOffset) {
int nOffset = (nLedsIfOffset > 0) ? nLedsOrOffset : 0;
int nLeds = (nLedsIfOffset > 0) ? nLedsIfOffset : nLedsOrOffset;
pLed->init();
pLed->setLeds(data + nOffset, nLeds);
FastLED.setMaxRefreshRate(pLed->getMaxRefreshRate(),true);
return *pLed;
}
void CFastLED::show(uint8_t scale) {
// guard against showing too rapidly
while(m_nMinMicros && ((micros()-lastshow) < m_nMinMicros));
lastshow = micros();
// If we have a function for computing power, use it!
if(m_pPowerFunc) {
scale = (*m_pPowerFunc)(scale, m_nPowerData);
}
CLEDController *pCur = CLEDController::head();
while(pCur) {
uint8_t d = pCur->getDither();
if(m_nFPS < 100) { pCur->setDither(0); }
pCur->showLeds(scale);
pCur->setDither(d);
pCur = pCur->next();
}
countFPS();
}
int CFastLED::count() {
int x = 0;
CLEDController *pCur = CLEDController::head();
while( pCur) {
x++;
pCur = pCur->next();
}
return x;
}
CLEDController & CFastLED::operator[](int x) {
CLEDController *pCur = CLEDController::head();
while(x-- && pCur) {
pCur = pCur->next();
}
if(pCur == NULL) {
return *(CLEDController::head());
} else {
return *pCur;
}
}
void CFastLED::showColor(const struct CRGB & color, uint8_t scale) {
while(m_nMinMicros && ((micros()-lastshow) < m_nMinMicros));
lastshow = micros();
// If we have a function for computing power, use it!
if(m_pPowerFunc) {
scale = (*m_pPowerFunc)(scale, m_nPowerData);
}
CLEDController *pCur = CLEDController::head();
while(pCur) {
uint8_t d = pCur->getDither();
if(m_nFPS < 100) { pCur->setDither(0); }
pCur->showColor(color, scale);
pCur->setDither(d);
pCur = pCur->next();
}
countFPS();
}
void CFastLED::clear(bool writeData) {
if(writeData) {
showColor(CRGB(0,0,0), 0);
}
clearData();
}
void CFastLED::clearData() {
CLEDController *pCur = CLEDController::head();
while(pCur) {
pCur->clearLedData();
pCur = pCur->next();
}
}
void CFastLED::delay(unsigned long ms) {
unsigned long start = millis();
do {
#ifndef FASTLED_ACCURATE_CLOCK
// make sure to allow at least one ms to pass to ensure the clock moves
// forward
::delay(1);
#endif
show();
yield();
}
while((millis()-start) < ms);
}
void CFastLED::setTemperature(const struct CRGB & temp) {
CLEDController *pCur = CLEDController::head();
while(pCur) {
pCur->setTemperature(temp);
pCur = pCur->next();
}
}
void CFastLED::setCorrection(const struct CRGB & correction) {
CLEDController *pCur = CLEDController::head();
while(pCur) {
pCur->setCorrection(correction);
pCur = pCur->next();
}
}
void CFastLED::setDither(uint8_t ditherMode) {
CLEDController *pCur = CLEDController::head();
while(pCur) {
pCur->setDither(ditherMode);
pCur = pCur->next();
}
}
//
// template<int m, int n> void transpose8(unsigned char A[8], unsigned char B[8]) {
// uint32_t x, y, t;
//
// // Load the array and pack it into x and y.
// y = *(unsigned int*)(A);
// x = *(unsigned int*)(A+4);
//
// // x = (A[0]<<24) | (A[m]<<16) | (A[2*m]<<8) | A[3*m];
// // y = (A[4*m]<<24) | (A[5*m]<<16) | (A[6*m]<<8) | A[7*m];
//
// // pre-transform x
// t = (x ^ (x >> 7)) & 0x00AA00AA; x = x ^ t ^ (t << 7);
// t = (x ^ (x >>14)) & 0x0000CCCC; x = x ^ t ^ (t <<14);
//
// // pre-transform y
// t = (y ^ (y >> 7)) & 0x00AA00AA; y = y ^ t ^ (t << 7);
// t = (y ^ (y >>14)) & 0x0000CCCC; y = y ^ t ^ (t <<14);
//
// // final transform
// t = (x & 0xF0F0F0F0) | ((y >> 4) & 0x0F0F0F0F);
// y = ((x << 4) & 0xF0F0F0F0) | (y & 0x0F0F0F0F);
// x = t;
//
// B[7*n] = y; y >>= 8;
// B[6*n] = y; y >>= 8;
// B[5*n] = y; y >>= 8;
// B[4*n] = y;
//
// B[3*n] = x; x >>= 8;
// B[2*n] = x; x >>= 8;
// B[n] = x; x >>= 8;
// B[0] = x;
// // B[0]=x>>24; B[n]=x>>16; B[2*n]=x>>8; B[3*n]=x>>0;
// // B[4*n]=y>>24; B[5*n]=y>>16; B[6*n]=y>>8; B[7*n]=y>>0;
// }
//
// void transposeLines(Lines & out, Lines & in) {
// transpose8<1,2>(in.bytes, out.bytes);
// transpose8<1,2>(in.bytes + 8, out.bytes + 1);
// }
extern int noise_min;
extern int noise_max;
void CFastLED::countFPS(int nFrames) {
static int br = 0;
static uint32_t lastframe = 0; // millis();
if(br++ >= nFrames) {
uint32_t now = millis();
now -= lastframe;
if( now == 0 ) {
now = 1; // prevent division by zero below
}
m_nFPS = (br * 1000) / now;
br = 0;
lastframe = millis();
}
}
void CFastLED::setMaxRefreshRate(uint16_t refresh, bool constrain) {
if(constrain) {
// if we're constraining, the new value of m_nMinMicros _must_ be higher than previously (because we're only
// allowed to slow things down if constraining)
if(refresh > 0) {
m_nMinMicros = ( (1000000/refresh) > m_nMinMicros) ? (1000000/refresh) : m_nMinMicros;
}
} else if(refresh > 0) {
m_nMinMicros = 1000000 / refresh;
} else {
m_nMinMicros = 0;
}
}
extern "C" int atexit(void (* /*func*/ )()) { return 0; }
#ifdef FASTLED_NEEDS_YIELD
extern "C" void yield(void) { }
#endif
#ifdef NEED_CXX_BITS
namespace __cxxabiv1
{
#if !defined(ESP8266) && !defined(ESP32)
extern "C" void __cxa_pure_virtual (void) {}
#endif
/* guard variables */
/* The ABI requires a 64-bit type. */
__extension__ typedef int __guard __attribute__((mode(__DI__)));
extern "C" int __cxa_guard_acquire (__guard *) __attribute__((weak));
extern "C" void __cxa_guard_release (__guard *) __attribute__((weak));
extern "C" void __cxa_guard_abort (__guard *) __attribute__((weak));
extern "C" int __cxa_guard_acquire (__guard *g)
{
return !*(char *)(g);
}
extern "C" void __cxa_guard_release (__guard *g)
{
*(char *)g = 1;
}
extern "C" void __cxa_guard_abort (__guard *)
{
}
}
#endif
FASTLED_NAMESPACE_END

View File

@ -0,0 +1,592 @@
#ifndef __INC_FASTSPI_LED2_H
#define __INC_FASTSPI_LED2_H
///@file FastLED.h
/// central include file for FastLED, defines the CFastLED class/object
#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)
#define FASTLED_HAS_PRAGMA_MESSAGE
#endif
#define FASTLED_VERSION 3003002
#ifndef FASTLED_INTERNAL
# ifdef FASTLED_HAS_PRAGMA_MESSAGE
# pragma message "FastLED version 3.003.003"
# else
# warning FastLED version 3.003.003 (Not really a warning, just telling you here.)
# endif
#endif
#ifndef __PROG_TYPES_COMPAT__
#define __PROG_TYPES_COMPAT__
#endif
#ifdef SmartMatrix_h
#include <SmartMatrix.h>
#endif
#ifdef DmxSimple_h
#include <DmxSimple.h>
#endif
#ifdef DmxSerial_h
#include <DMXSerial.h>
#endif
#include <stdint.h>
#include "cpp_compat.h"
#include "fastled_config.h"
#include "led_sysdefs.h"
// Utility functions
#include "fastled_delay.h"
#include "bitswap.h"
#include "controller.h"
#include "fastpin.h"
#include "fastspi_types.h"
#include "dmx.h"
#include "platforms.h"
#include "fastled_progmem.h"
#include "lib8tion.h"
#include "pixeltypes.h"
#include "hsv2rgb.h"
#include "colorutils.h"
#include "pixelset.h"
#include "colorpalettes.h"
#include "noise.h"
#include "power_mgt.h"
#include "fastspi.h"
#include "chipsets.h"
FASTLED_NAMESPACE_BEGIN
/// definitions for the spi chipset constants
enum ESPIChipsets {
LPD6803,
LPD8806,
WS2801,
WS2803,
SM16716,
P9813,
APA102,
SK9822,
DOTSTAR
};
enum ESM { SMART_MATRIX };
enum OWS2811 { OCTOWS2811,OCTOWS2811_400, OCTOWS2813};
enum SWS2812 { WS2812SERIAL };
#ifdef HAS_PIXIE
template<uint8_t DATA_PIN, EOrder RGB_ORDER> class PIXIE : public PixieController<DATA_PIN, RGB_ORDER> {};
#endif
#ifdef FASTLED_HAS_CLOCKLESS
template<uint8_t DATA_PIN> class NEOPIXEL : public WS2812Controller800Khz<DATA_PIN, GRB> {};
template<uint8_t DATA_PIN, EOrder RGB_ORDER> class SM16703 : public SM16703Controller<DATA_PIN, RGB_ORDER> {};
template<uint8_t DATA_PIN, EOrder RGB_ORDER> class TM1829 : public TM1829Controller800Khz<DATA_PIN, RGB_ORDER> {};
template<uint8_t DATA_PIN, EOrder RGB_ORDER> class TM1812 : public TM1809Controller800Khz<DATA_PIN, RGB_ORDER> {};
template<uint8_t DATA_PIN, EOrder RGB_ORDER> class TM1809 : public TM1809Controller800Khz<DATA_PIN, RGB_ORDER> {};
template<uint8_t DATA_PIN, EOrder RGB_ORDER> class TM1804 : public TM1809Controller800Khz<DATA_PIN, RGB_ORDER> {};
template<uint8_t DATA_PIN, EOrder RGB_ORDER> class TM1803 : public TM1803Controller400Khz<DATA_PIN, RGB_ORDER> {};
template<uint8_t DATA_PIN, EOrder RGB_ORDER> class UCS1903 : public UCS1903Controller400Khz<DATA_PIN, RGB_ORDER> {};
template<uint8_t DATA_PIN, EOrder RGB_ORDER> class UCS1903B : public UCS1903BController800Khz<DATA_PIN, RGB_ORDER> {};
template<uint8_t DATA_PIN, EOrder RGB_ORDER> class UCS1904 : public UCS1904Controller800Khz<DATA_PIN, RGB_ORDER> {};
template<uint8_t DATA_PIN, EOrder RGB_ORDER> class UCS2903 : public UCS2903Controller<DATA_PIN, RGB_ORDER> {};
template<uint8_t DATA_PIN, EOrder RGB_ORDER> class WS2812 : public WS2812Controller800Khz<DATA_PIN, RGB_ORDER> {};
template<uint8_t DATA_PIN, EOrder RGB_ORDER> class WS2852 : public WS2812Controller800Khz<DATA_PIN, RGB_ORDER> {};
template<uint8_t DATA_PIN, EOrder RGB_ORDER> class WS2812B : public WS2812Controller800Khz<DATA_PIN, RGB_ORDER> {};
template<uint8_t DATA_PIN, EOrder RGB_ORDER> class GS1903 : public WS2812Controller800Khz<DATA_PIN, RGB_ORDER> {};
template<uint8_t DATA_PIN, EOrder RGB_ORDER> class SK6812 : public SK6812Controller<DATA_PIN, RGB_ORDER> {};
template<uint8_t DATA_PIN, EOrder RGB_ORDER> class SK6822 : public SK6822Controller<DATA_PIN, RGB_ORDER> {};
template<uint8_t DATA_PIN, EOrder RGB_ORDER> class APA106 : public SK6822Controller<DATA_PIN, RGB_ORDER> {};
template<uint8_t DATA_PIN, EOrder RGB_ORDER> class PL9823 : public PL9823Controller<DATA_PIN, RGB_ORDER> {};
template<uint8_t DATA_PIN, EOrder RGB_ORDER> class WS2811 : public WS2811Controller800Khz<DATA_PIN, RGB_ORDER> {};
template<uint8_t DATA_PIN, EOrder RGB_ORDER> class WS2813 : public WS2813Controller<DATA_PIN, RGB_ORDER> {};
template<uint8_t DATA_PIN, EOrder RGB_ORDER> class APA104 : public WS2811Controller800Khz<DATA_PIN, RGB_ORDER> {};
template<uint8_t DATA_PIN, EOrder RGB_ORDER> class WS2811_400 : public WS2811Controller400Khz<DATA_PIN, RGB_ORDER> {};
template<uint8_t DATA_PIN, EOrder RGB_ORDER> class GE8822 : public GE8822Controller800Khz<DATA_PIN, RGB_ORDER> {};
template<uint8_t DATA_PIN, EOrder RGB_ORDER> class GW6205 : public GW6205Controller800Khz<DATA_PIN, RGB_ORDER> {};
template<uint8_t DATA_PIN, EOrder RGB_ORDER> class GW6205_400 : public GW6205Controller400Khz<DATA_PIN, RGB_ORDER> {};
template<uint8_t DATA_PIN, EOrder RGB_ORDER> class LPD1886 : public LPD1886Controller1250Khz<DATA_PIN, RGB_ORDER> {};
template<uint8_t DATA_PIN, EOrder RGB_ORDER> class LPD1886_8BIT : public LPD1886Controller1250Khz_8bit<DATA_PIN, RGB_ORDER> {};
#ifdef DmxSimple_h
template<uint8_t DATA_PIN, EOrder RGB_ORDER> class DMXSIMPLE : public DMXSimpleController<DATA_PIN, RGB_ORDER> {};
#endif
#ifdef DmxSerial_h
template<EOrder RGB_ORDER> class DMXSERIAL : public DMXSerialController<RGB_ORDER> {};
#endif
#endif
enum EBlockChipsets {
#ifdef PORTA_FIRST_PIN
WS2811_PORTA,
WS2813_PORTA,
WS2811_400_PORTA,
TM1803_PORTA,
UCS1903_PORTA,
#endif
#ifdef PORTB_FIRST_PIN
WS2811_PORTB,
WS2813_PORTB,
WS2811_400_PORTB,
TM1803_PORTB,
UCS1903_PORTB,
#endif
#ifdef PORTC_FIRST_PIN
WS2811_PORTC,
WS2813_PORTC,
WS2811_400_PORTC,
TM1803_PORTC,
UCS1903_PORTC,
#endif
#ifdef PORTD_FIRST_PIN
WS2811_PORTD,
WS2813_PORTD,
WS2811_400_PORTD,
TM1803_PORTD,
UCS1903_PORTD,
#endif
#ifdef HAS_PORTDC
WS2811_PORTDC,
WS2813_PORTDC,
WS2811_400_PORTDC,
TM1803_PORTDC,
UCS1903_PORTDC,
#endif
};
#if defined(LIB8_ATTINY)
#define NUM_CONTROLLERS 2
#else
#define NUM_CONTROLLERS 8
#endif
typedef uint8_t (*power_func)(uint8_t scale, uint32_t data);
/// High level controller interface for FastLED. This class manages controllers, global settings and trackings
/// such as brightness, and refresh rates, and provides access functions for driving led data to controllers
/// via the show/showColor/clear methods.
/// @nosubgrouping
class CFastLED {
// int m_nControllers;
uint8_t m_Scale; ///< The current global brightness scale setting
uint16_t m_nFPS; ///< Tracking for current FPS value
uint32_t m_nMinMicros; ///< minimum µs between frames, used for capping frame rates.
uint32_t m_nPowerData; ///< max power use parameter
power_func m_pPowerFunc; ///< function for overriding brightness when using FastLED.show();
public:
CFastLED();
/// Add a CLEDController instance to the world. Exposed to the public to allow people to implement their own
/// CLEDController objects or instances. There are two ways to call this method (as well as the other addLeds)
/// variations. The first is with 3 arguments, in which case the arguments are the controller, a pointer to
/// led data, and the number of leds used by this controller. The second is with 4 arguments, in which case
/// the first two arguments are the same, the third argument is an offset into the CRGB data where this controller's
/// CRGB data begins, and the fourth argument is the number of leds for this controller object.
/// @param pLed - the led controller being added
/// @param data - base point to an array of CRGB data structures
/// @param nLedsOrOffset - number of leds (3 argument version) or offset into the data array
/// @param nLedsIfOffset - number of leds (4 argument version)
/// @returns a reference to the added controller
static CLEDController &addLeds(CLEDController *pLed, struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0);
/// @name Adding SPI based controllers
//@{
/// Add an SPI based CLEDController instance to the world.
/// There are two ways to call this method (as well as the other addLeds)
/// variations. The first is with 2 arguments, in which case the arguments are a pointer to
/// led data, and the number of leds used by this controller. The second is with 3 arguments, in which case
/// the first argument is the same, the second argument is an offset into the CRGB data where this controller's
/// CRGB data begins, and the third argument is the number of leds for this controller object.
///
/// This method also takes a 1 to 5 template parameters for identifying the specific chipset, data and clock pins,
/// RGB ordering, and SPI data rate
/// @param data - base point to an array of CRGB data structures
/// @param nLedsOrOffset - number of leds (3 argument version) or offset into the data array
/// @param nLedsIfOffset - number of leds (4 argument version)
/// @tparam CHIPSET - the chipset type
/// @tparam DATA_PIN - the optional data pin for the leds (if omitted, will default to the first hardware SPI MOSI pin)
/// @tparam CLOCK_PIN - the optional clock pin for the leds (if omitted, will default to the first hardware SPI clock pin)
/// @tparam RGB_ORDER - the rgb ordering for the leds (e.g. what order red, green, and blue data is written out in)
/// @tparam SPI_DATA_RATE - the data rate to drive the SPI clock at, defined using DATA_RATE_MHZ or DATA_RATE_KHZ macros
/// @returns a reference to the added controller
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) {
switch(CHIPSET) {
case LPD6803: { static LPD6803Controller<DATA_PIN, CLOCK_PIN, RGB_ORDER, SPI_DATA_RATE> c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); }
case LPD8806: { static LPD8806Controller<DATA_PIN, CLOCK_PIN, RGB_ORDER, SPI_DATA_RATE> c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); }
case WS2801: { static WS2801Controller<DATA_PIN, CLOCK_PIN, RGB_ORDER, SPI_DATA_RATE> c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); }
case WS2803: { static WS2803Controller<DATA_PIN, CLOCK_PIN, RGB_ORDER, SPI_DATA_RATE> c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); }
case SM16716: { static SM16716Controller<DATA_PIN, CLOCK_PIN, RGB_ORDER, SPI_DATA_RATE> c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); }
case P9813: { static P9813Controller<DATA_PIN, CLOCK_PIN, RGB_ORDER, SPI_DATA_RATE> c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); }
case DOTSTAR:
case APA102: { static APA102Controller<DATA_PIN, CLOCK_PIN, RGB_ORDER, SPI_DATA_RATE> c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); }
case SK9822: { static SK9822Controller<DATA_PIN, CLOCK_PIN, RGB_ORDER, SPI_DATA_RATE> c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); }
}
}
template<ESPIChipsets CHIPSET, uint8_t DATA_PIN, uint8_t CLOCK_PIN > static CLEDController &addLeds(struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) {
switch(CHIPSET) {
case LPD6803: { static LPD6803Controller<DATA_PIN, CLOCK_PIN> c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); }
case LPD8806: { static LPD8806Controller<DATA_PIN, CLOCK_PIN> c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); }
case WS2801: { static WS2801Controller<DATA_PIN, CLOCK_PIN> c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); }
case WS2803: { static WS2803Controller<DATA_PIN, CLOCK_PIN> c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); }
case SM16716: { static SM16716Controller<DATA_PIN, CLOCK_PIN> c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); }
case P9813: { static P9813Controller<DATA_PIN, CLOCK_PIN> c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); }
case DOTSTAR:
case APA102: { static APA102Controller<DATA_PIN, CLOCK_PIN> c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); }
case SK9822: { static SK9822Controller<DATA_PIN, CLOCK_PIN> c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); }
}
}
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) {
switch(CHIPSET) {
case LPD6803: { static LPD6803Controller<DATA_PIN, CLOCK_PIN, RGB_ORDER> c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); }
case LPD8806: { static LPD8806Controller<DATA_PIN, CLOCK_PIN, RGB_ORDER> c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); }
case WS2801: { static WS2801Controller<DATA_PIN, CLOCK_PIN, RGB_ORDER> c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); }
case WS2803: { static WS2803Controller<DATA_PIN, CLOCK_PIN, RGB_ORDER> c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); }
case SM16716: { static SM16716Controller<DATA_PIN, CLOCK_PIN, RGB_ORDER> c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); }
case P9813: { static P9813Controller<DATA_PIN, CLOCK_PIN, RGB_ORDER> c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); }
case DOTSTAR:
case APA102: { static APA102Controller<DATA_PIN, CLOCK_PIN, RGB_ORDER> c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); }
case SK9822: { static SK9822Controller<DATA_PIN, CLOCK_PIN, RGB_ORDER> c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); }
}
}
#ifdef SPI_DATA
template<ESPIChipsets CHIPSET> static CLEDController &addLeds(struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) {
return addLeds<CHIPSET, SPI_DATA, SPI_CLOCK, RGB>(data, nLedsOrOffset, nLedsIfOffset);
}
template<ESPIChipsets CHIPSET, EOrder RGB_ORDER> static CLEDController &addLeds(struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) {
return addLeds<CHIPSET, SPI_DATA, SPI_CLOCK, RGB_ORDER>(data, nLedsOrOffset, nLedsIfOffset);
}
template<ESPIChipsets CHIPSET, EOrder RGB_ORDER, uint32_t SPI_DATA_RATE> static CLEDController &addLeds(struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) {
return addLeds<CHIPSET, SPI_DATA, SPI_CLOCK, RGB_ORDER, SPI_DATA_RATE>(data, nLedsOrOffset, nLedsIfOffset);
}
#endif
//@}
#ifdef FASTLED_HAS_CLOCKLESS
/// @name Adding 3-wire led controllers
//@{
/// Add a clockless (aka 3wire, also DMX) based CLEDController instance to the world.
/// There are two ways to call this method (as well as the other addLeds)
/// variations. The first is with 2 arguments, in which case the arguments are a pointer to
/// led data, and the number of leds used by this controller. The second is with 3 arguments, in which case
/// the first argument is the same, the second argument is an offset into the CRGB data where this controller's
/// CRGB data begins, and the third argument is the number of leds for this controller object.
///
/// This method also takes a 2 to 3 template parameters for identifying the specific chipset, data pin, and rgb ordering
/// RGB ordering, and SPI data rate
/// @param data - base point to an array of CRGB data structures
/// @param nLedsOrOffset - number of leds (3 argument version) or offset into the data array
/// @param nLedsIfOffset - number of leds (4 argument version)
/// @tparam CHIPSET - the chipset type (required)
/// @tparam DATA_PIN - the optional data pin for the leds (required)
/// @tparam RGB_ORDER - the rgb ordering for the leds (e.g. what order red, green, and blue data is written out in)
/// @returns a reference to the added controller
template<template<uint8_t DATA_PIN, EOrder RGB_ORDER> class CHIPSET, uint8_t DATA_PIN, EOrder RGB_ORDER>
static CLEDController &addLeds(struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) {
static CHIPSET<DATA_PIN, RGB_ORDER> c;
return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset);
}
template<template<uint8_t DATA_PIN, EOrder RGB_ORDER> class CHIPSET, uint8_t DATA_PIN>
static CLEDController &addLeds(struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) {
static CHIPSET<DATA_PIN, RGB> c;
return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset);
}
template<template<uint8_t DATA_PIN> class CHIPSET, uint8_t DATA_PIN>
static CLEDController &addLeds(struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) {
static CHIPSET<DATA_PIN> c;
return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset);
}
#if defined(__FASTLED_HAS_FIBCC) && (__FASTLED_HAS_FIBCC == 1)
template<uint8_t NUM_LANES, template<uint8_t DATA_PIN, EOrder RGB_ORDER> class CHIPSET, uint8_t DATA_PIN, EOrder RGB_ORDER=RGB>
static CLEDController &addLeds(struct CRGB *data, int nLeds) {
static __FIBCC<CHIPSET, DATA_PIN, NUM_LANES, RGB_ORDER> c;
return addLeds(&c, data, nLeds);
}
#endif
#ifdef FASTSPI_USE_DMX_SIMPLE
template<EClocklessChipsets CHIPSET, uint8_t DATA_PIN, EOrder RGB_ORDER=RGB>
static CLEDController &addLeds(struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0)
{
switch(CHIPSET) {
case DMX: { static DMXController<DATA_PIN> controller; return addLeds(&controller, data, nLedsOrOffset, nLedsIfOffset); }
}
}
#endif
//@}
#endif
/// @name Adding 3rd party library controllers
//@{
/// Add a 3rd party library based CLEDController instance to the world.
/// There are two ways to call this method (as well as the other addLeds)
/// variations. The first is with 2 arguments, in which case the arguments are a pointer to
/// led data, and the number of leds used by this controller. The second is with 3 arguments, in which case
/// the first argument is the same, the second argument is an offset into the CRGB data where this controller's
/// CRGB data begins, and the third argument is the number of leds for this controller object. This class includes the SmartMatrix
/// and OctoWS2811 based controllers
///
/// This method also takes a 1 to 2 template parameters for identifying the specific chipset and rgb ordering
/// RGB ordering, and SPI data rate
/// @param data - base point to an array of CRGB data structures
/// @param nLedsOrOffset - number of leds (3 argument version) or offset into the data array
/// @param nLedsIfOffset - number of leds (4 argument version)
/// @tparam CHIPSET - the chipset type (required)
/// @tparam RGB_ORDER - the rgb ordering for the leds (e.g. what order red, green, and blue data is written out in)
/// @returns a reference to the added controller
template<template<EOrder RGB_ORDER> class CHIPSET, EOrder RGB_ORDER>
static CLEDController &addLeds(struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) {
static CHIPSET<RGB_ORDER> c;
return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset);
}
template<template<EOrder RGB_ORDER> class CHIPSET>
static CLEDController &addLeds(struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) {
static CHIPSET<RGB> c;
return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset);
}
#ifdef USE_OCTOWS2811
template<OWS2811 CHIPSET, EOrder RGB_ORDER>
static CLEDController &addLeds(struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0)
{
switch(CHIPSET) {
case OCTOWS2811: { static COctoWS2811Controller<RGB_ORDER,WS2811_800kHz> controller; return addLeds(&controller, data, nLedsOrOffset, nLedsIfOffset); }
case OCTOWS2811_400: { static COctoWS2811Controller<RGB_ORDER,WS2811_400kHz> controller; return addLeds(&controller, data, nLedsOrOffset, nLedsIfOffset); }
#ifdef WS2813_800kHz
case OCTOWS2813: { static COctoWS2811Controller<RGB_ORDER,WS2813_800kHz> controller; return addLeds(&controller, data, nLedsOrOffset, nLedsIfOffset); }
#endif
}
}
template<OWS2811 CHIPSET>
static CLEDController &addLeds(struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0)
{
return addLeds<CHIPSET,GRB>(data,nLedsOrOffset,nLedsIfOffset);
}
#endif
#ifdef USE_WS2812SERIAL
template<SWS2812 CHIPSET, int DATA_PIN, EOrder RGB_ORDER>
static CLEDController &addLeds(struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0)
{
static CWS2812SerialController<DATA_PIN,RGB_ORDER> controller;
return addLeds(&controller, data, nLedsOrOffset, nLedsIfOffset);
}
#endif
#ifdef SmartMatrix_h
template<ESM CHIPSET>
static CLEDController &addLeds(struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0)
{
switch(CHIPSET) {
case SMART_MATRIX: { static CSmartMatrixController controller; return addLeds(&controller, data, nLedsOrOffset, nLedsIfOffset); }
}
}
#endif
//@}
#ifdef FASTLED_HAS_BLOCKLESS
/// @name adding parallel output controllers
//@{
/// Add a block based CLEDController instance to the world.
/// There are two ways to call this method (as well as the other addLeds)
/// variations. The first is with 2 arguments, in which case the arguments are a pointer to
/// led data, and the number of leds used by this controller. The second is with 3 arguments, in which case
/// the first argument is the same, the second argument is an offset into the CRGB data where this controller's
/// CRGB data begins, and the third argument is the number of leds for this controller object.
///
/// This method also takes a 2 to 3 template parameters for identifying the specific chipset and rgb ordering
/// RGB ordering, and SPI data rate
/// @param data - base point to an array of CRGB data structures
/// @param nLedsOrOffset - number of leds (3 argument version) or offset into the data array
/// @param nLedsIfOffset - number of leds (4 argument version)
/// @tparam CHIPSET - the chipset/port type (required)
/// @tparam NUM_LANES - how many parallel lanes of output to write
/// @tparam RGB_ORDER - the rgb ordering for the leds (e.g. what order red, green, and blue data is written out in)
/// @returns a reference to the added controller
template<EBlockChipsets CHIPSET, int NUM_LANES, EOrder RGB_ORDER>
static CLEDController &addLeds(struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) {
switch(CHIPSET) {
#ifdef PORTA_FIRST_PIN
case WS2811_PORTA: return addLeds(new InlineBlockClocklessController<NUM_LANES, PORTA_FIRST_PIN, NS(320), NS(320), NS(640), RGB_ORDER>(), data, nLedsOrOffset, nLedsIfOffset);
case WS2811_400_PORTA: return addLeds(new InlineBlockClocklessController<NUM_LANES, PORTA_FIRST_PIN, NS(800), NS(800), NS(900), RGB_ORDER>(), data, nLedsOrOffset, nLedsIfOffset);
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);
case TM1803_PORTA: return addLeds(new InlineBlockClocklessController<NUM_LANES, PORTA_FIRST_PIN, NS(700), NS(1100), NS(700), RGB_ORDER>(), data, nLedsOrOffset, nLedsIfOffset);
case UCS1903_PORTA: return addLeds(new InlineBlockClocklessController<NUM_LANES, PORTA_FIRST_PIN, NS(500), NS(1500), NS(500), RGB_ORDER>(), data, nLedsOrOffset, nLedsIfOffset);
#endif
#ifdef PORTB_FIRST_PIN
case WS2811_PORTB: return addLeds(new InlineBlockClocklessController<NUM_LANES, PORTB_FIRST_PIN, NS(320), NS(320), NS(640), RGB_ORDER>(), data, nLedsOrOffset, nLedsIfOffset);
case WS2811_400_PORTB: return addLeds(new InlineBlockClocklessController<NUM_LANES, PORTB_FIRST_PIN, NS(800), NS(800), NS(900), RGB_ORDER>(), data, nLedsOrOffset, nLedsIfOffset);
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);
case TM1803_PORTB: return addLeds(new InlineBlockClocklessController<NUM_LANES, PORTB_FIRST_PIN, NS(700), NS(1100), NS(700), RGB_ORDER>(), data, nLedsOrOffset, nLedsIfOffset);
case UCS1903_PORTB: return addLeds(new InlineBlockClocklessController<NUM_LANES, PORTB_FIRST_PIN, NS(500), NS(1500), NS(500), RGB_ORDER>(), data, nLedsOrOffset, nLedsIfOffset);
#endif
#ifdef PORTC_FIRST_PIN
case WS2811_PORTC: return addLeds(new InlineBlockClocklessController<NUM_LANES, PORTC_FIRST_PIN, NS(320), NS(320), NS(640), RGB_ORDER>(), data, nLedsOrOffset, nLedsIfOffset);
case WS2811_400_PORTC: return addLeds(new InlineBlockClocklessController<NUM_LANES, PORTC_FIRST_PIN, NS(800), NS(800), NS(900), RGB_ORDER>(), data, nLedsOrOffset, nLedsIfOffset);
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);
case TM1803_PORTC: return addLeds(new InlineBlockClocklessController<NUM_LANES, PORTC_FIRST_PIN, NS(700), NS(1100), NS(700), RGB_ORDER>(), data, nLedsOrOffset, nLedsIfOffset);
case UCS1903_PORTC: return addLeds(new InlineBlockClocklessController<NUM_LANES, PORTC_FIRST_PIN, NS(500), NS(1500), NS(500), RGB_ORDER>(), data, nLedsOrOffset, nLedsIfOffset);
#endif
#ifdef PORTD_FIRST_PIN
case WS2811_PORTD: return addLeds(new InlineBlockClocklessController<NUM_LANES, PORTD_FIRST_PIN, NS(320), NS(320), NS(640), RGB_ORDER>(), data, nLedsOrOffset, nLedsIfOffset);
case WS2811_400_PORTD: return addLeds(new InlineBlockClocklessController<NUM_LANES, PORTD_FIRST_PIN, NS(800), NS(800), NS(900), RGB_ORDER>(), data, nLedsOrOffset, nLedsIfOffset);
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);
case TM1803_PORTD: return addLeds(new InlineBlockClocklessController<NUM_LANES, PORTD_FIRST_PIN, NS(700), NS(1100), NS(700), RGB_ORDER>(), data, nLedsOrOffset, nLedsIfOffset);
case UCS1903_PORTD: return addLeds(new InlineBlockClocklessController<NUM_LANES, PORTD_FIRST_PIN, NS(500), NS(1500), NS(500), RGB_ORDER>(), data, nLedsOrOffset, nLedsIfOffset);
#endif
#ifdef HAS_PORTDC
case WS2811_PORTDC: return addLeds(new SixteenWayInlineBlockClocklessController<NUM_LANES,NS(320), NS(320), NS(640), RGB_ORDER>(), data, nLedsOrOffset, nLedsIfOffset);
case WS2811_400_PORTDC: return addLeds(new SixteenWayInlineBlockClocklessController<NUM_LANES,NS(800), NS(800), NS(900), RGB_ORDER>(), data, nLedsOrOffset, nLedsIfOffset);
case WS2813_PORTDC: return addLeds(new SixteenWayInlineBlockClocklessController<NUM_LANES, NS(320), NS(320), NS(640), RGB_ORDER, 0, false, 300>(), data, nLedsOrOffset, nLedsIfOffset);
case TM1803_PORTDC: return addLeds(new SixteenWayInlineBlockClocklessController<NUM_LANES, NS(700), NS(1100), NS(700), RGB_ORDER>(), data, nLedsOrOffset, nLedsIfOffset);
case UCS1903_PORTDC: return addLeds(new SixteenWayInlineBlockClocklessController<NUM_LANES, NS(500), NS(1500), NS(500), RGB_ORDER>(), data, nLedsOrOffset, nLedsIfOffset);
#endif
}
}
template<EBlockChipsets CHIPSET, int NUM_LANES>
static CLEDController &addLeds(struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) {
return addLeds<CHIPSET,NUM_LANES,GRB>(data,nLedsOrOffset,nLedsIfOffset);
}
//@}
#endif
/// Set the global brightness scaling
/// @param scale a 0-255 value for how much to scale all leds before writing them out
void setBrightness(uint8_t scale) { m_Scale = scale; }
/// Get the current global brightness setting
/// @returns the current global brightness value
uint8_t getBrightness() { return m_Scale; }
/// Set the maximum power to be used, given in volts and milliamps.
/// @param volts - how many volts the leds are being driven at (usually 5)
/// @param milliamps - the maximum milliamps of power draw you want
inline void setMaxPowerInVoltsAndMilliamps(uint8_t volts, uint32_t milliamps) { setMaxPowerInMilliWatts(volts * milliamps); }
/// Set the maximum power to be used, given in milliwatts
/// @param milliwatts - the max power draw desired, in milliwatts
inline void setMaxPowerInMilliWatts(uint32_t milliwatts) { m_pPowerFunc = &calculate_max_brightness_for_power_mW; m_nPowerData = milliwatts; }
/// Update all our controllers with the current led colors, using the passed in brightness
/// @param scale temporarily override the scale
void show(uint8_t scale);
/// Update all our controllers with the current led colors
void show() { show(m_Scale); }
/// clear the leds, wiping the local array of data, optionally black out the leds as well
/// @param writeData whether or not to write out to the leds as well
void clear(bool writeData = false);
/// clear out the local data array
void clearData();
/// Set all leds on all controllers to the given color/scale
/// @param color what color to set the leds to
/// @param scale what brightness scale to show at
void showColor(const struct CRGB & color, uint8_t scale);
/// Set all leds on all controllers to the given color
/// @param color what color to set the leds to
void showColor(const struct CRGB & color) { showColor(color, m_Scale); }
/// Delay for the given number of milliseconds. Provided to allow the library to be used on platforms
/// that don't have a delay function (to allow code to be more portable). Note: this will call show
/// constantly to drive the dithering engine (and will call show at least once).
/// @param ms the number of milliseconds to pause for
void delay(unsigned long ms);
/// Set a global color temperature. Sets the color temperature for all added led strips, overriding whatever
/// previous color temperature those controllers may have had
/// @param temp A CRGB structure describing the color temperature
void setTemperature(const struct CRGB & temp);
/// Set a global color correction. Sets the color correction for all added led strips,
/// overriding whatever previous color correction those controllers may have had.
/// @param correction A CRGB structure describin the color correction.
void setCorrection(const struct CRGB & correction);
/// Set the dithering mode. Sets the dithering mode for all added led strips, overriding
/// whatever previous dithering option those controllers may have had.
/// @param ditherMode - what type of dithering to use, either BINARY_DITHER or DISABLE_DITHER
void setDither(uint8_t ditherMode = BINARY_DITHER);
/// Set the maximum refresh rate. This is global for all leds. Attempts to
/// call show faster than this rate will simply wait. Note that the refresh rate
/// defaults to the slowest refresh rate of all the leds added through addLeds. If
/// you wish to set/override this rate, be sure to call setMaxRefreshRate _after_
/// adding all of your leds.
/// @param refresh - maximum refresh rate in hz
/// @param constrain - constrain refresh rate to the slowest speed yet set
void setMaxRefreshRate(uint16_t refresh, bool constrain=false);
/// for debugging, will keep track of time between calls to countFPS, and every
/// nFrames calls, it will update an internal counter for the current FPS.
/// @todo make this a rolling counter
/// @param nFrames - how many frames to time for determining FPS
void countFPS(int nFrames=25);
/// Get the number of frames/second being written out
/// @returns the most recently computed FPS value
uint16_t getFPS() { return m_nFPS; }
/// Get how many controllers have been registered
/// @returns the number of controllers (strips) that have been added with addLeds
int count();
/// Get a reference to a registered controller
/// @returns a reference to the Nth controller
CLEDController & operator[](int x);
/// Get the number of leds in the first controller
/// @returns the number of LEDs in the first controller
int size() { return (*this)[0].size(); }
/// Get a pointer to led data for the first controller
/// @returns pointer to the CRGB buffer for the first controller
CRGB *leds() { return (*this)[0].leds(); }
};
#define FastSPI_LED FastLED
#define FastSPI_LED2 FastLED
#ifndef LEDS
#define LEDS FastLED
#endif
extern CFastLED FastLED;
// Warnings for undefined things
#ifndef HAS_HARDWARE_PIN_SUPPORT
#warning "No pin/port mappings found, pin access will be slightly slower. See fastpin.h for info."
#define NO_HARDWARE_PIN_SUPPORT
#endif
FASTLED_NAMESPACE_END
#endif

View File

@ -0,0 +1,20 @@
The MIT License (MIT)
Copyright (c) 2013 FastLED
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@ -0,0 +1,55 @@
=New platform porting guide=
== Fast porting for a new board on existing hardware ==
Sometimes "porting" FastLED simply consists of supplying new pin definitions for the given platform. For example, platforms/avr/fastpin_avr.h contains various pin definitions for all the AVR variant chipsets/boards that FastLED supports. Defining a set of pins involves setting up a set of definitions - for example here's one full set from the avr fastpin file:
```
#elif defined(__AVR_ATmega1284P__) || defined(__AVR_ATmega644P__)
_FL_IO(A); _FL_IO(B); _FL_IO(C); _FL_IO(D);
#define MAX_PIN 31
_FL_DEFPIN(0, 0, B); _FL_DEFPIN(1, 1, B); _FL_DEFPIN(2, 2, B); _FL_DEFPIN(3, 3, B);
_FL_DEFPIN(4, 4, B); _FL_DEFPIN(5, 5, B); _FL_DEFPIN(6, 6, B); _FL_DEFPIN(7, 7, B);
_FL_DEFPIN(8, 0, D); _FL_DEFPIN(9, 1, D); _FL_DEFPIN(10, 2, D); _FL_DEFPIN(11, 3, D);
_FL_DEFPIN(12, 4, D); _FL_DEFPIN(13, 5, D); _FL_DEFPIN(14, 6, D); _FL_DEFPIN(15, 7, D);
_FL_DEFPIN(16, 0, C); _FL_DEFPIN(17, 1, C); _FL_DEFPIN(18, 2, C); _FL_DEFPIN(19, 3, C);
_FL_DEFPIN(20, 4, C); _FL_DEFPIN(21, 5, C); _FL_DEFPIN(22, 6, C); _FL_DEFPIN(23, 7, C);
_FL_DEFPIN(24, 0, A); _FL_DEFPIN(25, 1, A); _FL_DEFPIN(26, 2, A); _FL_DEFPIN(27, 3, A);
_FL_DEFPIN(28, 4, A); _FL_DEFPIN(29, 5, A); _FL_DEFPIN(30, 6, A); _FL_DEFPIN(31, 7, A);
#define HAS_HARDWARE_PIN_SUPPORT 1
```
The ```_FL_IO``` macro is used to define the port registers for the platform while the ```_FL_DEFPIN``` macro is used to define pins. The parameters to the macro are the pin number, the bit on the port that represents that pin, and the port identifier itself. On some platforms, like the AVR, ports are identified by letter. On other platforms, like arm, ports are identified by number.
The ```HAS_HARDWARE_PIN_SUPPORT``` define tells the rest of the FastLED library that there is hardware pin support available. There may be other platform specific defines for things like hardware SPI ports and such.
== Setting up the basic files/folders ==
* Create platform directory (e.g. platforms/arm/kl26)
* Create configuration header led_sysdefs_arm_kl26.h:
* Define platform flags (like FASTLED_ARM/FASTLED_TEENSY)
* Define configuration parameters re: interrupts, or clock doubling
* Include extar system header files if needed
* Create main platform include, fastled_arm_kl26.h
* Include the various other header files as needed
* Modify led_sysdefs.h to conditionally include platform sysdefs header file
* Modify platforms.h to conditionally include platform fastled header
== Porting fastpin.h ==
The heart of the FastLED library is the fast pin accesss. This is a templated class that provides 1-2 cycle pin access, bypassing digital write and other such things. As such, this will usually be the first bit of the library that you will want to port when moving to a new platform. Once you have FastPIN up and running then you can do some basic work like testing toggles or running bit-bang'd SPI output.
There's two low level FastPin classes. There's the base FastPIN template class, and then there is FastPinBB which is for bit-banded access on those MCUs that support bitbanding. Note that the bitband class is optional and primarily useful in the implementation of other functionality internal to the platform. This file is also where you would do the pin to port/bit mapping defines.
Explaining how the macros work and should be used is currently beyond the scope of this document.
== Porting fastspi.h ==
This is where you define the low level interface to the hardware SPI system (including a writePixels method that does a bunch of housekeeping for writing led data). Use the fastspi_nop.h file as a reference for the methods that need to be implemented. There are ofteh other useful methods that can help with the internals of the SPI code, I recommend taking a look at how the various platforms implement their SPI classes.
== Porting clockless.h ==
This is where you define the code for the clockless controllers. Across ARM platforms this will usually be fairly similar - though different arm platforms will have different clock sources that you can/should use.

View File

@ -0,0 +1,91 @@
[![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/FastLED/public)
[![arduino-library-badge](https://www.ardu-badge.com/badge/FastLED.svg)](https://www.ardu-badge.com/FastLED)
IMPORTANT NOTE: For AVR based systems, avr-gcc 4.8.x is supported and tested. This means Arduino 1.6.5 and later.
FastLED 3.3
===========
This is a library for easily & efficiently controlling a wide variety of LED chipsets, like the ones
sold by adafruit (Neopixel, DotStar, LPD8806), Sparkfun (WS2801), and aliexpress. In addition to writing to the
leds, this library also includes a number of functions for high-performing 8bit math for manipulating
your RGB values, as well as low level classes for abstracting out access to pins and SPI hardware, while
still keeping things as fast as possible. Tested with Arduino up to 1.6.5 from arduino.cc.
Quick note for people installing from GitHub repo zips, rename the folder FastLED before copying it to your Arduino/libraries folder. Github likes putting -branchname into the name of the folder, which unfortunately, makes Arduino cranky!
We have multiple goals with this library:
* Quick start for new developers - hook up your leds and go, no need to think about specifics of the led chipsets being used
* Zero pain switching LED chipsets - you get some new leds that the library supports, just change the definition of LEDs you're using, et. voila! Your code is running with the new leds.
* High performance - with features like zero cost global brightness scaling, high performance 8-bit math for RGB manipulation, and some of the fastest bit-bang'd SPI support around, FastLED wants to keep as many CPU cycles available for your led patterns as possible
## Getting help
If you need help with using the library, please consider going to the reddit community first, which is at http://fastled.io/r (or https://reddit.com/r/FastLED) - there are hundreds of people in that group and many times you will get a quicker answer to your question there, as you will be likely to run into other people who have had the same issue. If you run into bugs with the library (compilation failures, the library doing the wrong thing), or if you'd like to request that we support a particular platform or LED chipset, then please open an issue at http://fastled.io/issues and we will try to figure out what is going wrong.
## Simple example
How quickly can you get up and running with the library? Here's a simple blink program:
#include "FastLED.h"
#define NUM_LEDS 60
CRGB leds[NUM_LEDS];
void setup() { FastLED.addLeds<NEOPIXEL, 6>(leds, NUM_LEDS); }
void loop() {
leds[0] = CRGB::White; FastLED.show(); delay(30);
leds[0] = CRGB::Black; FastLED.show(); delay(30);
}
## Supported LED chipsets
Here's a list of all the LED chipsets are supported. More details on the led chipsets are included *TODO: Link to wiki page*
* Adafruit's DotStars - AKA the APA102
* Adafruit's Neopixel - aka the WS2812B (also WS2811/WS2812/WS2813, also supported in lo-speed mode) - a 3 wire addressable led chipset
* TM1809/4 - 3 wire chipset, cheaply available on aliexpress.com
* TM1803 - 3 wire chipset, sold by radio shack
* UCS1903 - another 3 wire led chipset, cheap
* GW6205 - another 3 wire led chipset
* LPD8806 - SPI based chpiset, very high speed
* WS2801 - SPI based chipset, cheap and widely available
* SM16716 - SPI based chipset
* APA102 - SPI based chipset
* P9813 - aka Cool Neon's Total Control Lighting
* DMX - send rgb data out over DMX using arduino DMX libraries
* SmartMatrix panels - needs the SmartMatrix library - https://github.com/pixelmatix/SmartMatrix
* LPD6803 - SPI based chpiset, chip CMODE pin must be set to 1 (inside oscillator mode)
HL1606, and "595"-style shift registers are no longer supported by the library. The older Version 1 of the library ("FastSPI_LED") has support for these, but is missing many of the advanced features of current versions and is no longer being maintained.
## Supported platforms
Right now the library is supported on a variety of arduino compatable platforms. If it's ARM or AVR and uses the arduino software (or a modified version of it to build) then it is likely supported. Note that we have a long list of upcoming platforms to support, so if you don't see what you're looking for here, ask, it may be on the roadmap (or may already be supported). N.B. at the moment we are only supporting the stock compilers that ship with the arduino software. Support for upgraded compilers, as well as using AVR studio and skipping the arduino entirely, should be coming in a near future release.
* Arduino & compatibles - straight up arduino devices, uno, duo, leonardo, mega, nano, etc...
* Arduino Yún
* Adafruit Trinket & Gemma - Trinket Pro may be supported, but haven't tested to confirm yet
* Teensy 2, Teensy++ 2, Teensy 3.0, Teensy 3.1/3.2, Teensy LC, Teensy 3.5, Teensy 3.6, and Teensy 4.0 - arduino compataible from pjrc.com with some extra goodies (note the teensy 3, 3.1, and LC are ARM, not AVR!)
* Arduino Due and the digistump DigiX
* RFDuino
* SparkCore
* Arduino Zero
* ESP8266 using the arduino board definitions from http://arduino.esp8266.com/stable/package_esp8266com_index.json - please be sure to also read https://github.com/FastLED/FastLED/wiki/ESP8266-notes for information specific to the 8266.
* The wino board - http://wino-board.com
* ESP32 based boards
What types of platforms are we thinking about supporting in the future? Here's a short list: ChipKit32, Maple, Beagleboard
## What about that name?
Wait, what happend to FastSPI_LED and FastSPI_LED2? The library was initially named FastSPI_LED because it was focused on very fast and efficient SPI access. However, since then, the library has expanded to support a number of LED chipsets that don't use SPI, as well as a number of math and utility functions for LED processing across the board. We decided that the name FastLED more accurately represents the totality of what the library provides, everything fast, for LEDs.
## For more information
Check out the official site http://fastled.io for links to documentation, issues, and news
*TODO* - get candy

View File

@ -0,0 +1,28 @@
#define FASTLED_INTERNAL
#include "FastLED.h"
/// Simplified form of bits rotating function. Based on code found here - http://www.hackersdelight.org/hdcodetxt/transpose8.c.txt - rotating
/// data into LSB for a faster write (the code using this data can happily walk the array backwards)
void transpose8x1_noinline(unsigned char *A, unsigned char *B) {
uint32_t x, y, t;
// Load the array and pack it into x and y.
y = *(unsigned int*)(A);
x = *(unsigned int*)(A+4);
// pre-transform x
t = (x ^ (x >> 7)) & 0x00AA00AA; x = x ^ t ^ (t << 7);
t = (x ^ (x >>14)) & 0x0000CCCC; x = x ^ t ^ (t <<14);
// pre-transform y
t = (y ^ (y >> 7)) & 0x00AA00AA; y = y ^ t ^ (t << 7);
t = (y ^ (y >>14)) & 0x0000CCCC; y = y ^ t ^ (t <<14);
// final transform
t = (x & 0xF0F0F0F0) | ((y >> 4) & 0x0F0F0F0F);
y = ((x << 4) & 0xF0F0F0F0) | (y & 0x0F0F0F0F);
x = t;
*((uint32_t*)B) = y;
*((uint32_t*)(B+4)) = x;
}

View File

@ -0,0 +1,276 @@
#ifndef __INC_BITSWAP_H
#define __INC_BITSWAP_H
#include "FastLED.h"
FASTLED_NAMESPACE_BEGIN
///@file bitswap.h
///Functions for rotating bits/bytes
///@defgroup Bitswap Bit swapping/rotate
///Functions for doing a rotation of bits/bytes used by parallel output
///@{
#if defined(FASTLED_ARM) || defined(FASTLED_ESP8266)
/// structure representing 8 bits of access
typedef union {
uint8_t raw;
struct {
uint32_t a0:1;
uint32_t a1:1;
uint32_t a2:1;
uint32_t a3:1;
uint32_t a4:1;
uint32_t a5:1;
uint32_t a6:1;
uint32_t a7:1;
};
} just8bits;
/// structure representing 32 bits of access
typedef struct {
uint32_t a0:1;
uint32_t a1:1;
uint32_t a2:1;
uint32_t a3:1;
uint32_t a4:1;
uint32_t a5:1;
uint32_t a6:1;
uint32_t a7:1;
uint32_t b0:1;
uint32_t b1:1;
uint32_t b2:1;
uint32_t b3:1;
uint32_t b4:1;
uint32_t b5:1;
uint32_t b6:1;
uint32_t b7:1;
uint32_t c0:1;
uint32_t c1:1;
uint32_t c2:1;
uint32_t c3:1;
uint32_t c4:1;
uint32_t c5:1;
uint32_t c6:1;
uint32_t c7:1;
uint32_t d0:1;
uint32_t d1:1;
uint32_t d2:1;
uint32_t d3:1;
uint32_t d4:1;
uint32_t d5:1;
uint32_t d6:1;
uint32_t d7:1;
} sub4;
/// union containing a full 8 bytes to swap the bit orientation on
typedef union {
uint32_t word[2];
uint8_t bytes[8];
struct {
sub4 a;
sub4 b;
};
} bitswap_type;
#define SWAPSA(X,N) out. X ## 0 = in.a.a ## N; \
out. X ## 1 = in.a.b ## N; \
out. X ## 2 = in.a.c ## N; \
out. X ## 3 = in.a.d ## N;
#define SWAPSB(X,N) out. X ## 0 = in.b.a ## N; \
out. X ## 1 = in.b.b ## N; \
out. X ## 2 = in.b.c ## N; \
out. X ## 3 = in.b.d ## N;
#define SWAPS(X,N) out. X ## 0 = in.a.a ## N; \
out. X ## 1 = in.a.b ## N; \
out. X ## 2 = in.a.c ## N; \
out. X ## 3 = in.a.d ## N; \
out. X ## 4 = in.b.a ## N; \
out. X ## 5 = in.b.b ## N; \
out. X ## 6 = in.b.c ## N; \
out. X ## 7 = in.b.d ## N;
/// Do an 8byte by 8bit rotation
__attribute__((always_inline)) inline void swapbits8(bitswap_type in, bitswap_type & out) {
// SWAPS(a.a,7);
// SWAPS(a.b,6);
// SWAPS(a.c,5);
// SWAPS(a.d,4);
// SWAPS(b.a,3);
// SWAPS(b.b,2);
// SWAPS(b.c,1);
// SWAPS(b.d,0);
// SWAPSA(a.a,7);
// SWAPSA(a.b,6);
// SWAPSA(a.c,5);
// SWAPSA(a.d,4);
//
// SWAPSB(a.a,7);
// SWAPSB(a.b,6);
// SWAPSB(a.c,5);
// SWAPSB(a.d,4);
//
// SWAPSA(b.a,3);
// SWAPSA(b.b,2);
// SWAPSA(b.c,1);
// SWAPSA(b.d,0);
// //
// SWAPSB(b.a,3);
// SWAPSB(b.b,2);
// SWAPSB(b.c,1);
// SWAPSB(b.d,0);
for(int i = 0; i < 8; i++) {
just8bits work;
work.a3 = in.word[0] >> 31;
work.a2 = in.word[0] >> 23;
work.a1 = in.word[0] >> 15;
work.a0 = in.word[0] >> 7;
in.word[0] <<= 1;
work.a7 = in.word[1] >> 31;
work.a6 = in.word[1] >> 23;
work.a5 = in.word[1] >> 15;
work.a4 = in.word[1] >> 7;
in.word[1] <<= 1;
out.bytes[i] = work.raw;
}
}
/// Slow version of the 8 byte by 8 bit rotation
__attribute__((always_inline)) inline void slowswap(unsigned char *A, unsigned char *B) {
for(int row = 0; row < 7; row++) {
uint8_t x = A[row];
uint8_t bit = (1<<row);
unsigned char *p = B;
for(uint32_t mask = 1<<7 ; mask ; mask >>= 1) {
if(x & mask) {
*p++ |= bit;
} else {
*p++ &= ~bit;
}
}
// B[7] |= (x & 0x01) << row; x >>= 1;
// B[6] |= (x & 0x01) << row; x >>= 1;
// B[5] |= (x & 0x01) << row; x >>= 1;
// B[4] |= (x & 0x01) << row; x >>= 1;
// B[3] |= (x & 0x01) << row; x >>= 1;
// B[2] |= (x & 0x01) << row; x >>= 1;
// B[1] |= (x & 0x01) << row; x >>= 1;
// B[0] |= (x & 0x01) << row; x >>= 1;
}
}
void transpose8x1_noinline(unsigned char *A, unsigned char *B);
/// Simplified form of bits rotating function. Based on code found here - http://www.hackersdelight.org/hdcodetxt/transpose8.c.txt - rotating
/// data into LSB for a faster write (the code using this data can happily walk the array backwards)
__attribute__((always_inline)) inline void transpose8x1(unsigned char *A, unsigned char *B) {
uint32_t x, y, t;
// Load the array and pack it into x and y.
y = *(unsigned int*)(A);
x = *(unsigned int*)(A+4);
// pre-transform x
t = (x ^ (x >> 7)) & 0x00AA00AA; x = x ^ t ^ (t << 7);
t = (x ^ (x >>14)) & 0x0000CCCC; x = x ^ t ^ (t <<14);
// pre-transform y
t = (y ^ (y >> 7)) & 0x00AA00AA; y = y ^ t ^ (t << 7);
t = (y ^ (y >>14)) & 0x0000CCCC; y = y ^ t ^ (t <<14);
// final transform
t = (x & 0xF0F0F0F0) | ((y >> 4) & 0x0F0F0F0F);
y = ((x << 4) & 0xF0F0F0F0) | (y & 0x0F0F0F0F);
x = t;
*((uint32_t*)B) = y;
*((uint32_t*)(B+4)) = x;
}
/// Simplified form of bits rotating function. Based on code found here - http://www.hackersdelight.org/hdcodetxt/transpose8.c.txt
__attribute__((always_inline)) inline void transpose8x1_MSB(unsigned char *A, unsigned char *B) {
uint32_t x, y, t;
// Load the array and pack it into x and y.
y = *(unsigned int*)(A);
x = *(unsigned int*)(A+4);
// pre-transform x
t = (x ^ (x >> 7)) & 0x00AA00AA; x = x ^ t ^ (t << 7);
t = (x ^ (x >>14)) & 0x0000CCCC; x = x ^ t ^ (t <<14);
// pre-transform y
t = (y ^ (y >> 7)) & 0x00AA00AA; y = y ^ t ^ (t << 7);
t = (y ^ (y >>14)) & 0x0000CCCC; y = y ^ t ^ (t <<14);
// final transform
t = (x & 0xF0F0F0F0) | ((y >> 4) & 0x0F0F0F0F);
y = ((x << 4) & 0xF0F0F0F0) | (y & 0x0F0F0F0F);
x = t;
B[7] = y; y >>= 8;
B[6] = y; y >>= 8;
B[5] = y; y >>= 8;
B[4] = y;
B[3] = x; x >>= 8;
B[2] = x; x >>= 8;
B[1] = x; x >>= 8;
B[0] = x; /* */
}
/// templated bit-rotating function. Based on code found here - http://www.hackersdelight.org/hdcodetxt/transpose8.c.txt
template<int m, int n>
__attribute__((always_inline)) inline void transpose8(unsigned char *A, unsigned char *B) {
uint32_t x, y, t;
// Load the array and pack it into x and y.
if(m == 1) {
y = *(unsigned int*)(A);
x = *(unsigned int*)(A+4);
} else {
x = (A[0]<<24) | (A[m]<<16) | (A[2*m]<<8) | A[3*m];
y = (A[4*m]<<24) | (A[5*m]<<16) | (A[6*m]<<8) | A[7*m];
}
// pre-transform x
t = (x ^ (x >> 7)) & 0x00AA00AA; x = x ^ t ^ (t << 7);
t = (x ^ (x >>14)) & 0x0000CCCC; x = x ^ t ^ (t <<14);
// pre-transform y
t = (y ^ (y >> 7)) & 0x00AA00AA; y = y ^ t ^ (t << 7);
t = (y ^ (y >>14)) & 0x0000CCCC; y = y ^ t ^ (t <<14);
// final transform
t = (x & 0xF0F0F0F0) | ((y >> 4) & 0x0F0F0F0F);
y = ((x << 4) & 0xF0F0F0F0) | (y & 0x0F0F0F0F);
x = t;
B[7*n] = y; y >>= 8;
B[6*n] = y; y >>= 8;
B[5*n] = y; y >>= 8;
B[4*n] = y;
B[3*n] = x; x >>= 8;
B[2*n] = x; x >>= 8;
B[n] = x; x >>= 8;
B[0] = x;
// B[0]=x>>24; B[n]=x>>16; B[2*n]=x>>8; B[3*n]=x>>0;
// B[4*n]=y>>24; B[5*n]=y>>16; B[6*n]=y>>8; B[7*n]=y>>0;
}
#endif
FASTLED_NAMESPACE_END
///@}
#endif

View File

@ -0,0 +1,623 @@
#ifndef __INC_CHIPSETS_H
#define __INC_CHIPSETS_H
#include "FastLED.h"
#include "pixeltypes.h"
///@file chipsets.h
/// contains the bulk of the definitions for the various LED chipsets supported.
FASTLED_NAMESPACE_BEGIN
///@defgroup chipsets
/// Implementations of CLEDController classes for various led chipsets.
///
///@{
#if defined(ARDUINO) //&& defined(SoftwareSerial_h)
#if defined(SoftwareSerial_h)
#include <SoftwareSerial.h>
#define HAS_PIXIE
/// Adafruit Pixie controller class
/// @tparam DATAPIN the pin to write data out on
/// @tparam RGB_ORDER the RGB ordering for the led data
template<uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
class PixieController : public CPixelLEDController<RGB_ORDER> {
SoftwareSerial Serial;
CMinWait<2000> mWait;
public:
PixieController() : Serial(-1, DATA_PIN) {}
protected:
virtual void init() {
Serial.begin(115200);
mWait.mark();
}
virtual void showPixels(PixelController<RGB_ORDER> & pixels) {
mWait.wait();
while(pixels.has(1)) {
uint8_t r = pixels.loadAndScale0();
Serial.write(r);
uint8_t g = pixels.loadAndScale1();
Serial.write(g);
uint8_t b = pixels.loadAndScale2();
Serial.write(b);
pixels.advanceData();
pixels.stepDithering();
}
mWait.mark();
}
};
// template<SoftwareSerial & STREAM, EOrder RGB_ORDER = RGB>
// class PixieController : public PixieBaseController<STREAM, RGB_ORDER> {
// public:
// virtual void init() {
// STREAM.begin(115200);
// }
// };
#endif
#endif
///@name Clocked chipsets - nominally SPI based these chipsets have a data and a clock line.
///@{
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// LPD8806 controller class - takes data/clock/select pin values (N.B. should take an SPI definition?)
//
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// LPD8806 controller class.
/// @tparam DATA_PIN the data pin for these leds
/// @tparam CLOCK_PIN the clock pin for these leds
/// @tparam RGB_ORDER the RGB ordering for these leds
/// @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)
template <uint8_t DATA_PIN, uint8_t CLOCK_PIN, EOrder RGB_ORDER = RGB, uint32_t SPI_SPEED = DATA_RATE_MHZ(12) >
class LPD8806Controller : public CPixelLEDController<RGB_ORDER> {
typedef SPIOutput<DATA_PIN, CLOCK_PIN, SPI_SPEED> SPI;
class LPD8806_ADJUST {
public:
// LPD8806 spec wants the high bit of every rgb data byte sent out to be set.
__attribute__((always_inline)) inline static uint8_t adjust(register uint8_t data) { return ((data>>1) | 0x80) + ((data && (data<254)) & 0x01); }
__attribute__((always_inline)) inline static void postBlock(int len) {
SPI::writeBytesValueRaw(0, ((len*3+63)>>6));
}
};
SPI mSPI;
public:
LPD8806Controller() {}
virtual void init() {
mSPI.init();
}
protected:
virtual void showPixels(PixelController<RGB_ORDER> & pixels) {
mSPI.template writePixels<0, LPD8806_ADJUST, RGB_ORDER>(pixels);
}
};
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// WS2801 definition - takes data/clock/select pin values (N.B. should take an SPI definition?)
//
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// WS2801 controller class.
/// @tparam DATA_PIN the data pin for these leds
/// @tparam CLOCK_PIN the clock pin for these leds
/// @tparam RGB_ORDER the RGB ordering for these leds
/// @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)
template <uint8_t DATA_PIN, uint8_t CLOCK_PIN, EOrder RGB_ORDER = RGB, uint32_t SPI_SPEED = DATA_RATE_MHZ(1)>
class WS2801Controller : public CPixelLEDController<RGB_ORDER> {
typedef SPIOutput<DATA_PIN, CLOCK_PIN, SPI_SPEED> SPI;
SPI mSPI;
CMinWait<1000> mWaitDelay;
public:
WS2801Controller() {}
virtual void init() {
mSPI.init();
mWaitDelay.mark();
}
protected:
virtual void showPixels(PixelController<RGB_ORDER> & pixels) {
mWaitDelay.wait();
mSPI.template writePixels<0, DATA_NOP, RGB_ORDER>(pixels);
mWaitDelay.mark();
}
};
template <uint8_t DATA_PIN, uint8_t CLOCK_PIN, EOrder RGB_ORDER = RGB, uint32_t SPI_SPEED = DATA_RATE_MHZ(25)>
class WS2803Controller : public WS2801Controller<DATA_PIN, CLOCK_PIN, RGB_ORDER, SPI_SPEED> {};
/// LPD6803 controller class (LPD1101).
/// 16 bit (1 bit - const "1", 5 bit - red, 5 bit - green, 5 bit blue).
/// In chip CMODE pin must be set to 1 (inside oscillator mode).
/// Datasheet: https://cdn-shop.adafruit.com/datasheets/LPD6803.pdf
/// @tparam DATA_PIN the data pin for these leds
/// @tparam CLOCK_PIN the clock pin for these leds
/// @tparam RGB_ORDER the RGB ordering for these leds
/// @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)
template <uint8_t DATA_PIN, uint8_t CLOCK_PIN, EOrder RGB_ORDER = RGB, uint32_t SPI_SPEED = DATA_RATE_MHZ(12)>
class LPD6803Controller : public CPixelLEDController<RGB_ORDER> {
typedef SPIOutput<DATA_PIN, CLOCK_PIN, SPI_SPEED> SPI;
SPI mSPI;
void startBoundary() { mSPI.writeByte(0); mSPI.writeByte(0); mSPI.writeByte(0); mSPI.writeByte(0); }
public:
LPD6803Controller() {}
virtual void init() {
mSPI.init();
}
protected:
virtual void showPixels(PixelController<RGB_ORDER> & pixels) {
mSPI.select();
startBoundary();
while(pixels.has(1)) {
register uint16_t command;
command = 0x8000;
command |= (pixels.loadAndScale0() & 0xF8) << 7; // red is the high 5 bits
command |= (pixels.loadAndScale1() & 0xF8) << 2; // green is the middle 5 bits
mSPI.writeByte((command >> 8) & 0xFF);
command |= pixels.loadAndScale2() >> 3 ; // blue is the low 5 bits
mSPI.writeByte(command & 0xFF);
pixels.stepDithering();
pixels.advanceData();
}
//endBoundary(pixels.size());
mSPI.waitFully();
mSPI.release();
}
};
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// APA102 definition - takes data/clock/select pin values (N.B. should take an SPI definition?)
//
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// APA102 controller class.
/// @tparam DATA_PIN the data pin for these leds
/// @tparam CLOCK_PIN the clock pin for these leds
/// @tparam RGB_ORDER the RGB ordering for these leds
/// @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)
template <uint8_t DATA_PIN, uint8_t CLOCK_PIN, EOrder RGB_ORDER = RGB, uint32_t SPI_SPEED = DATA_RATE_MHZ(12)>
class APA102Controller : public CPixelLEDController<RGB_ORDER> {
typedef SPIOutput<DATA_PIN, CLOCK_PIN, SPI_SPEED> SPI;
SPI mSPI;
void startBoundary() { mSPI.writeWord(0); mSPI.writeWord(0); }
void endBoundary(int nLeds) { int nDWords = (nLeds/32); do { mSPI.writeByte(0xFF); mSPI.writeByte(0x00); mSPI.writeByte(0x00); mSPI.writeByte(0x00); } while(nDWords--); }
inline void writeLed(uint8_t brightness, uint8_t b0, uint8_t b1, uint8_t b2) __attribute__((always_inline)) {
#ifdef FASTLED_SPI_BYTE_ONLY
mSPI.writeByte(0xE0 | brightness);
mSPI.writeByte(b0);
mSPI.writeByte(b1);
mSPI.writeByte(b2);
#else
uint16_t b = 0xE000 | (brightness << 8) | (uint16_t)b0;
mSPI.writeWord(b);
uint16_t w = b1 << 8;
w |= b2;
mSPI.writeWord(w);
#endif
}
public:
APA102Controller() {}
virtual void init() {
mSPI.init();
}
protected:
virtual void showPixels(PixelController<RGB_ORDER> & pixels) {
mSPI.select();
uint8_t s0 = pixels.getScale0(), s1 = pixels.getScale1(), s2 = pixels.getScale2();
#if FASTLED_USE_GLOBAL_BRIGHTNESS == 1
const uint16_t maxBrightness = 0x1F;
uint16_t brightness = ((((uint16_t)max(max(s0, s1), s2) + 1) * maxBrightness - 1) >> 8) + 1;
s0 = (maxBrightness * s0 + (brightness >> 1)) / brightness;
s1 = (maxBrightness * s1 + (brightness >> 1)) / brightness;
s2 = (maxBrightness * s2 + (brightness >> 1)) / brightness;
#else
const uint8_t brightness = 0x1F;
#endif
startBoundary();
while (pixels.has(1)) {
writeLed(brightness, pixels.loadAndScale0(0, s0), pixels.loadAndScale1(0, s1), pixels.loadAndScale2(0, s2));
pixels.stepDithering();
pixels.advanceData();
}
endBoundary(pixels.size());
mSPI.waitFully();
mSPI.release();
}
};
/// SK9822 controller class.
/// @tparam DATA_PIN the data pin for these leds
/// @tparam CLOCK_PIN the clock pin for these leds
/// @tparam RGB_ORDER the RGB ordering for these leds
/// @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)
template <uint8_t DATA_PIN, uint8_t CLOCK_PIN, EOrder RGB_ORDER = RGB, uint32_t SPI_SPEED = DATA_RATE_MHZ(24)>
class SK9822Controller : public CPixelLEDController<RGB_ORDER> {
typedef SPIOutput<DATA_PIN, CLOCK_PIN, SPI_SPEED> SPI;
SPI mSPI;
void startBoundary() { mSPI.writeWord(0); mSPI.writeWord(0); }
void endBoundary(int nLeds) { int nLongWords = (nLeds/32); do { mSPI.writeByte(0x00); mSPI.writeByte(0x00); mSPI.writeByte(0x00); mSPI.writeByte(0x00); } while(nLongWords--); }
inline void writeLed(uint8_t brightness, uint8_t b0, uint8_t b1, uint8_t b2) __attribute__((always_inline)) {
#ifdef FASTLED_SPI_BYTE_ONLY
mSPI.writeByte(0xE0 | brightness);
mSPI.writeByte(b0);
mSPI.writeByte(b1);
mSPI.writeByte(b2);
#else
uint16_t b = 0xE000 | (brightness << 8) | (uint16_t)b0;
mSPI.writeWord(b);
uint16_t w = b1 << 8;
w |= b2;
mSPI.writeWord(w);
#endif
}
public:
SK9822Controller() {}
virtual void init() {
mSPI.init();
}
protected:
virtual void showPixels(PixelController<RGB_ORDER> & pixels) {
mSPI.select();
uint8_t s0 = pixels.getScale0(), s1 = pixels.getScale1(), s2 = pixels.getScale2();
#if FASTLED_USE_GLOBAL_BRIGHTNESS == 1
const uint16_t maxBrightness = 0x1F;
uint16_t brightness = ((((uint16_t)max(max(s0, s1), s2) + 1) * maxBrightness - 1) >> 8) + 1;
s0 = (maxBrightness * s0 + (brightness >> 1)) / brightness;
s1 = (maxBrightness * s1 + (brightness >> 1)) / brightness;
s2 = (maxBrightness * s2 + (brightness >> 1)) / brightness;
#else
const uint8_t brightness = 0x1F;
#endif
startBoundary();
while (pixels.has(1)) {
writeLed(brightness, pixels.loadAndScale0(0, s0), pixels.loadAndScale1(0, s1), pixels.loadAndScale2(0, s2));
pixels.stepDithering();
pixels.advanceData();
}
endBoundary(pixels.size());
mSPI.waitFully();
mSPI.release();
}
};
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// P9813 definition - takes data/clock/select pin values (N.B. should take an SPI definition?)
//
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// P9813 controller class.
/// @tparam DATA_PIN the data pin for these leds
/// @tparam CLOCK_PIN the clock pin for these leds
/// @tparam RGB_ORDER the RGB ordering for these leds
/// @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)
template <uint8_t DATA_PIN, uint8_t CLOCK_PIN, EOrder RGB_ORDER = RGB, uint32_t SPI_SPEED = DATA_RATE_MHZ(10)>
class P9813Controller : public CPixelLEDController<RGB_ORDER> {
typedef SPIOutput<DATA_PIN, CLOCK_PIN, SPI_SPEED> SPI;
SPI mSPI;
void writeBoundary() { mSPI.writeWord(0); mSPI.writeWord(0); }
inline void writeLed(uint8_t r, uint8_t g, uint8_t b) __attribute__((always_inline)) {
register uint8_t top = 0xC0 | ((~b & 0xC0) >> 2) | ((~g & 0xC0) >> 4) | ((~r & 0xC0) >> 6);
mSPI.writeByte(top); mSPI.writeByte(b); mSPI.writeByte(g); mSPI.writeByte(r);
}
public:
P9813Controller() {}
virtual void init() {
mSPI.init();
}
protected:
virtual void showPixels(PixelController<RGB_ORDER> & pixels) {
mSPI.select();
writeBoundary();
while(pixels.has(1)) {
writeLed(pixels.loadAndScale0(), pixels.loadAndScale1(), pixels.loadAndScale2());
pixels.advanceData();
pixels.stepDithering();
}
writeBoundary();
mSPI.waitFully();
mSPI.release();
}
};
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// SM16716 definition - takes data/clock/select pin values (N.B. should take an SPI definition?)
//
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// SM16716 controller class.
/// @tparam DATA_PIN the data pin for these leds
/// @tparam CLOCK_PIN the clock pin for these leds
/// @tparam RGB_ORDER the RGB ordering for these leds
/// @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)
template <uint8_t DATA_PIN, uint8_t CLOCK_PIN, EOrder RGB_ORDER = RGB, uint32_t SPI_SPEED = DATA_RATE_MHZ(16)>
class SM16716Controller : public CPixelLEDController<RGB_ORDER> {
typedef SPIOutput<DATA_PIN, CLOCK_PIN, SPI_SPEED> SPI;
SPI mSPI;
void writeHeader() {
// Write out 50 zeros to the spi line (6 blocks of 8 followed by two single bit writes)
mSPI.select();
mSPI.template writeBit<0>(0);
mSPI.writeByte(0);
mSPI.writeByte(0);
mSPI.writeByte(0);
mSPI.template writeBit<0>(0);
mSPI.writeByte(0);
mSPI.writeByte(0);
mSPI.writeByte(0);
mSPI.waitFully();
mSPI.release();
}
public:
SM16716Controller() {}
virtual void init() {
mSPI.init();
}
protected:
virtual void showPixels(PixelController<RGB_ORDER> & pixels) {
// Make sure the FLAG_START_BIT flag is set to ensure that an extra 1 bit is sent at the start
// of each triplet of bytes for rgb data
// writeHeader();
mSPI.template writePixels<FLAG_START_BIT, DATA_NOP, RGB_ORDER>( pixels );
writeHeader();
}
};
/// @}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Clockless template instantiations - see clockless.h for how the timing values are used
//
// Base template for clockless controllers. These controllers have 3 control points in their cycle for each bit.
// At T=0 : the line is raised hi to start a bit
// At T=T1 : the line is dropped low to transmit a zero bit
// At T=T1+T2 : the line is dropped low to transmit a one bit
// At T=T1+T2+T3 : the cycle is concluded (next bit can be sent)
//
// The units used for T1, T2, and T3 is nanoseconds.
// For 8MHz/16MHz/24MHz frequencies, these values are also guaranteed
// to be integral multiples of an 8MHz clock (125ns increments).
//
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#ifdef FASTLED_HAS_CLOCKLESS
/// @name clockless controllers
/// Provides timing definitions for the variety of clockless controllers supplied by the library.
/// @{
// Allow clock that clockless controller is based on to have different
// frequency than the CPU.
#if !defined(CLOCKLESS_FREQUENCY)
#define CLOCKLESS_FREQUENCY F_CPU
#endif
// We want to force all avr's to use the Trinket controller when running at 8Mhz, because even the 328's at 8Mhz
// need the more tightly defined timeframes.
#if (CLOCKLESS_FREQUENCY == 8000000 || CLOCKLESS_FREQUENCY == 16000000 || CLOCKLESS_FREQUENCY == 24000000) // || CLOCKLESS_FREQUENCY == 48000000 || CLOCKLESS_FREQUENCY == 96000000) // 125ns/clock
#define FMUL (CLOCKLESS_FREQUENCY/8000000)
// GE8822
template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
class GE8822Controller800Khz : public ClocklessController<DATA_PIN, 3 * FMUL, 5 * FMUL, 3 * FMUL, RGB_ORDER, 4> {};
// LPD1886
template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
class LPD1886Controller1250Khz : public ClocklessController<DATA_PIN, 2 * FMUL, 3 * FMUL, 2 * FMUL, RGB_ORDER, 4> {};
// LPD1886
template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
class LPD1886Controller1250Khz_8bit : public ClocklessController<DATA_PIN, 2 * FMUL, 3 * FMUL, 2 * FMUL, RGB_ORDER> {};
// WS2811@800khz 2 clocks, 5 clocks, 3 clocks
template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
class WS2812Controller800Khz : public ClocklessController<DATA_PIN, 2 * FMUL, 5 * FMUL, 3 * FMUL, RGB_ORDER> {};
template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
class WS2811Controller800Khz : public ClocklessController<DATA_PIN, 3 * FMUL, 4 * FMUL, 3 * FMUL, RGB_ORDER> {};
template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB> //not tested
class WS2813Controller : public ClocklessController<DATA_PIN, 3 * FMUL, 4 * FMUL, 3 * FMUL, RGB_ORDER> {};
template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
class WS2811Controller400Khz : public ClocklessController<DATA_PIN, 4 * FMUL, 10 * FMUL, 6 * FMUL, RGB_ORDER> {};
template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
class SK6822Controller : public ClocklessController<DATA_PIN, 3 * FMUL, 8 * FMUL, 3 * FMUL, RGB_ORDER> {};
template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
class SM16703Controller : public ClocklessController<DATA_PIN, 3 * FMUL, 4 * FMUL, 3 * FMUL, RGB_ORDER> {};
template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
class SK6812Controller : public ClocklessController<DATA_PIN, 3 * FMUL, 3 * FMUL, 4 * FMUL, RGB_ORDER> {};
template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
class UCS1903Controller400Khz : public ClocklessController<DATA_PIN, 4 * FMUL, 12 * FMUL, 4 * FMUL, RGB_ORDER> {};
template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
class UCS1903BController800Khz : public ClocklessController<DATA_PIN, 2 * FMUL, 4 * FMUL, 4 * FMUL, RGB_ORDER> {};
template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
class UCS1904Controller800Khz : public ClocklessController<DATA_PIN, 3 * FMUL, 3 * FMUL, 4 * FMUL, RGB_ORDER> {};
template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
class UCS2903Controller : public ClocklessController<DATA_PIN, 2 * FMUL, 6 * FMUL, 2 * FMUL, RGB_ORDER> {};
template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
class TM1809Controller800Khz : public ClocklessController<DATA_PIN, 2 * FMUL, 5 * FMUL, 3 * FMUL, RGB_ORDER> {};
template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
class TM1803Controller400Khz : public ClocklessController<DATA_PIN, 6 * FMUL, 9 * FMUL, 6 * FMUL, RGB_ORDER> {};
template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
class TM1829Controller800Khz : public ClocklessController<DATA_PIN, 2 * FMUL, 5 * FMUL, 3 * FMUL, RGB_ORDER, 0, true, 500> {};
template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
class GW6205Controller400Khz : public ClocklessController<DATA_PIN, 6 * FMUL, 7 * FMUL, 6 * FMUL, RGB_ORDER, 4> {};
template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
class GW6205Controller800Khz : public ClocklessController<DATA_PIN, 2 * FMUL, 4 * FMUL, 4 * FMUL, RGB_ORDER, 4> {};
template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
class PL9823Controller : public ClocklessController<DATA_PIN, 3 * FMUL, 8 * FMUL, 3 * FMUL, RGB_ORDER> {};
#else
// Similar to NS() macro, this calculates the number of cycles for
// the clockless chipset (which may differ from CPU cycles)
#ifdef FASTLED_TEENSY4
// just use raw nanosecond values for the teensy4
#define C_NS(_NS) _NS
#else
#define C_NS(_NS) (((_NS * ((CLOCKLESS_FREQUENCY / 1000000L)) + 999)) / 1000)
#endif
// GE8822 - 350ns 660ns 350ns
template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
class GE8822Controller800Khz : public ClocklessController<DATA_PIN, C_NS(350), C_NS(660), C_NS(350), RGB_ORDER, 4> {};
// GW6205@400khz - 800ns, 800ns, 800ns
template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
class GW6205Controller400Khz : public ClocklessController<DATA_PIN, C_NS(800), C_NS(800), C_NS(800), RGB_ORDER, 4> {};
// GW6205@400khz - 400ns, 400ns, 400ns
template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
class GW6205Controller800Khz : public ClocklessController<DATA_PIN, C_NS(400), C_NS(400), C_NS(400), RGB_ORDER, 4> {};
// UCS1903 - 500ns, 1500ns, 500ns
template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
class UCS1903Controller400Khz : public ClocklessController<DATA_PIN, C_NS(500), C_NS(1500), C_NS(500), RGB_ORDER> {};
// UCS1903B - 400ns, 450ns, 450ns
template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
class UCS1903BController800Khz : public ClocklessController<DATA_PIN, C_NS(400), C_NS(450), C_NS(450), RGB_ORDER> {};
// UCS1904 - 400ns, 400ns, 450ns
template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
class UCS1904Controller800Khz : public ClocklessController<DATA_PIN, C_NS(400), C_NS(400), C_NS(450), RGB_ORDER> {};
// UCS2903 - 250ns, 750ns, 250ns
template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
class UCS2903Controller : public ClocklessController<DATA_PIN, C_NS(250), C_NS(750), C_NS(250), RGB_ORDER> {};
// TM1809 - 350ns, 350ns, 550ns
template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
class TM1809Controller800Khz : public ClocklessController<DATA_PIN, C_NS(350), C_NS(350), C_NS(450), RGB_ORDER> {};
// WS2811 - 320ns, 320ns, 640ns
template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
class WS2811Controller800Khz : public ClocklessController<DATA_PIN, C_NS(320), C_NS(320), C_NS(640), RGB_ORDER> {};
// WS2813 - 320ns, 320ns, 640ns
template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
class WS2813Controller : public ClocklessController<DATA_PIN, C_NS(320), C_NS(320), C_NS(640), RGB_ORDER> {};
// WS2812 - 250ns, 625ns, 375ns
template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
class WS2812Controller800Khz : public ClocklessController<DATA_PIN, C_NS(250), C_NS(625), C_NS(375), RGB_ORDER> {};
// WS2811@400khz - 800ns, 800ns, 900ns
template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
class WS2811Controller400Khz : public ClocklessController<DATA_PIN, C_NS(800), C_NS(800), C_NS(900), RGB_ORDER> {};
// 750NS, 750NS, 750NS
template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
class TM1803Controller400Khz : public ClocklessController<DATA_PIN, C_NS(700), C_NS(1100), C_NS(700), RGB_ORDER> {};
template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
class TM1829Controller800Khz : public ClocklessController<DATA_PIN, C_NS(340), C_NS(340), C_NS(550), RGB_ORDER, 0, true, 500> {};
template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
class TM1829Controller1600Khz : public ClocklessController<DATA_PIN, C_NS(100), C_NS(300), C_NS(200), RGB_ORDER, 0, true, 500> {};
template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
class LPD1886Controller1250Khz : public ClocklessController<DATA_PIN, C_NS(200), C_NS(400), C_NS(200), RGB_ORDER, 4> {};
template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
class LPD1886Controller1250Khz_8bit : public ClocklessController<DATA_PIN, C_NS(200), C_NS(400), C_NS(200), RGB_ORDER> {};
template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
class SK6822Controller : public ClocklessController<DATA_PIN, C_NS(375), C_NS(1000), C_NS(375), RGB_ORDER> {};
template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
class SK6812Controller : public ClocklessController<DATA_PIN, C_NS(300), C_NS(300), C_NS(600), RGB_ORDER> {};
template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
class SM16703Controller : public ClocklessController<DATA_PIN, C_NS(300), C_NS(600), C_NS(300), RGB_ORDER> {};
template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
class PL9823Controller : public ClocklessController<DATA_PIN, C_NS(350), C_NS(1010), C_NS(350), RGB_ORDER> {};
#endif
///@}
#endif
///@}
FASTLED_NAMESPACE_END
#endif

Some files were not shown because too many files have changed in this diff Show More