Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/AlexGyver/Arduino_Ambilight.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex <beragumbo@ya.ru>2017-09-03 00:37:36 +0300
committerAlex <beragumbo@ya.ru>2017-09-03 00:37:36 +0300
commite9e091ba628994af5f75c27f76becf5d26cba33e (patch)
tree398e7c857a0a8d7850af5310a826a3261886030c /Библиотеки/FastLED-master/platforms
parent24c7f7bfe652daee35173de5585f8ae28e1d6040 (diff)
added
Diffstat (limited to 'Библиотеки/FastLED-master/platforms')
-rw-r--r--Библиотеки/FastLED-master/platforms/arm/common/m0clockless.h318
-rw-r--r--Библиотеки/FastLED-master/platforms/arm/d21/clockless_arm_d21.h61
-rw-r--r--Библиотеки/FastLED-master/platforms/arm/d21/fastled_arm_d21.h8
-rw-r--r--Библиотеки/FastLED-master/platforms/arm/d21/fastpin_arm_d21.h153
-rw-r--r--Библиотеки/FastLED-master/platforms/arm/d21/led_sysdefs_arm_d21.h26
-rw-r--r--Библиотеки/FastLED-master/platforms/arm/k20/clockless_arm_k20.h124
-rw-r--r--Библиотеки/FastLED-master/platforms/arm/k20/clockless_block_arm_k20.h330
-rw-r--r--Библиотеки/FastLED-master/platforms/arm/k20/fastled_arm_k20.h14
-rw-r--r--Библиотеки/FastLED-master/platforms/arm/k20/fastpin_arm_k20.h120
-rw-r--r--Библиотеки/FastLED-master/platforms/arm/k20/fastspi_arm_k20.h466
-rw-r--r--Библиотеки/FastLED-master/platforms/arm/k20/led_sysdefs_arm_k20.h46
-rw-r--r--Библиотеки/FastLED-master/platforms/arm/k20/octows2811_controller.h66
-rw-r--r--Библиотеки/FastLED-master/platforms/arm/k20/smartmatrix_t3.h55
-rw-r--r--Библиотеки/FastLED-master/platforms/arm/k66/clockless_arm_k66.h124
-rw-r--r--Библиотеки/FastLED-master/platforms/arm/k66/clockless_block_arm_k66.h344
-rw-r--r--Библиотеки/FastLED-master/platforms/arm/k66/fastled_arm_k66.h14
-rw-r--r--Библиотеки/FastLED-master/platforms/arm/k66/fastpin_arm_k66.h128
-rw-r--r--Библиотеки/FastLED-master/platforms/arm/k66/fastspi_arm_k66.h464
-rw-r--r--Библиотеки/FastLED-master/platforms/arm/k66/led_sysdefs_arm_k66.h46
-rw-r--r--Библиотеки/FastLED-master/platforms/arm/kl26/clockless_arm_kl26.h65
-rw-r--r--Библиотеки/FastLED-master/platforms/arm/kl26/fastled_arm_kl26.h10
-rw-r--r--Библиотеки/FastLED-master/platforms/arm/kl26/fastpin_arm_kl26.h88
-rw-r--r--Библиотеки/FastLED-master/platforms/arm/kl26/fastspi_arm_kl26.h252
-rw-r--r--Библиотеки/FastLED-master/platforms/arm/kl26/led_sysdefs_arm_kl26.h47
-rw-r--r--Библиотеки/FastLED-master/platforms/arm/nrf51/clockless_arm_nrf51.h83
-rw-r--r--Библиотеки/FastLED-master/platforms/arm/nrf51/fastled_arm_nrf51.h11
-rw-r--r--Библиотеки/FastLED-master/platforms/arm/nrf51/fastpin_arm_nrf51.h119
-rw-r--r--Библиотеки/FastLED-master/platforms/arm/nrf51/fastspi_arm_nrf51.h150
-rw-r--r--Библиотеки/FastLED-master/platforms/arm/nrf51/led_sysdefs_arm_nrf51.h46
-rw-r--r--Библиотеки/FastLED-master/platforms/arm/sam/clockless_arm_sam.h120
-rw-r--r--Библиотеки/FastLED-master/platforms/arm/sam/clockless_block_arm_sam.h184
-rw-r--r--Библиотеки/FastLED-master/platforms/arm/sam/fastled_arm_sam.h11
-rw-r--r--Библиотеки/FastLED-master/platforms/arm/sam/fastpin_arm_sam.h137
-rw-r--r--Библиотеки/FastLED-master/platforms/arm/sam/fastspi_arm_sam.h163
-rw-r--r--Библиотеки/FastLED-master/platforms/arm/sam/led_sysdefs_arm_sam.h39
-rw-r--r--Библиотеки/FastLED-master/platforms/arm/stm32/clockless_arm_stm32.h126
-rw-r--r--Библиотеки/FastLED-master/platforms/arm/stm32/fastled_arm_stm32.h10
-rw-r--r--Библиотеки/FastLED-master/platforms/arm/stm32/fastpin_arm_stm32.h105
-rw-r--r--Библиотеки/FastLED-master/platforms/arm/stm32/led_sysdefs_arm_stm32.h47
-rw-r--r--Библиотеки/FastLED-master/platforms/avr/clockless_trinket.h464
-rw-r--r--Библиотеки/FastLED-master/platforms/avr/fastled_avr.h14
-rw-r--r--Библиотеки/FastLED-master/platforms/avr/fastpin_avr.h330
-rw-r--r--Библиотеки/FastLED-master/platforms/avr/fastspi_avr.h505
-rw-r--r--Библиотеки/FastLED-master/platforms/avr/led_sysdefs_avr.h54
-rw-r--r--Библиотеки/FastLED-master/platforms/esp/8266/clockless_block_esp8266.h159
-rw-r--r--Библиотеки/FastLED-master/platforms/esp/8266/clockless_esp8266.h117
-rw-r--r--Библиотеки/FastLED-master/platforms/esp/8266/fastled_esp8266.h7
-rw-r--r--Библиотеки/FastLED-master/platforms/esp/8266/fastpin_esp8266.h101
-rw-r--r--Библиотеки/FastLED-master/platforms/esp/8266/led_sysdefs_esp8266.h39
49 files changed, 6510 insertions, 0 deletions
diff --git a/Библиотеки/FastLED-master/platforms/arm/common/m0clockless.h b/Библиотеки/FastLED-master/platforms/arm/common/m0clockless.h
new file mode 100644
index 0000000..11512fd
--- /dev/null
+++ b/Библиотеки/FastLED-master/platforms/arm/common/m0clockless.h
@@ -0,0 +1,318 @@
+#ifndef __INC_M0_CLOCKLESS_H
+#define __INC_M0_CLOCKLESS_H
+
+struct M0ClocklessData {
+ uint8_t d[3];
+ uint8_t e[3];
+ uint8_t adj;
+ uint8_t pad;
+ uint32_t s[3];
+};
+
+
+template<int HI_OFFSET, int LO_OFFSET, int T1, int T2, int T3, EOrder RGB_ORDER, int WAIT_TIME>int
+showLedData(volatile uint32_t *_port, uint32_t _bitmask, const uint8_t *_leds, uint32_t num_leds, struct M0ClocklessData *pData) {
+ // Lo register variables
+ register uint32_t scratch=0;
+ register struct M0ClocklessData *base = pData;
+ register volatile uint32_t *port = _port;
+ register uint32_t d=0;
+ register uint32_t counter=num_leds;
+ register uint32_t bn=0;
+ register uint32_t b=0;
+ register uint32_t bitmask = _bitmask;
+
+ // high register variable
+ register const uint8_t *leds = _leds;
+#if (FASTLED_SCALE8_FIXED == 1)
+ pData->s[0]++;
+ pData->s[1]++;
+ pData->s[2]++;
+#endif
+ asm __volatile__ (
+ ///////////////////////////////////////////////////////////////////////////
+ //
+ // asm macro definitions - used to assemble the clockless output
+ //
+ ".ifnotdef fl_delay_def;"
+#ifdef FASTLED_ARM_M0_PLUS
+ " .set fl_is_m0p, 1;"
+ " .macro m0pad;"
+ " nop;"
+ " .endm;"
+#else
+ " .set fl_is_m0p, 0;"
+ " .macro m0pad;"
+ " .endm;"
+#endif
+ " .set fl_delay_def, 1;"
+ " .set fl_delay_mod, 4;"
+ " .if fl_is_m0p == 1;"
+ " .set fl_delay_mod, 3;"
+ " .endif;"
+ " .macro fl_delay dtime, reg=r0;"
+ " .if (\\dtime > 0);"
+ " .set dcycle, (\\dtime / fl_delay_mod);"
+ " .set dwork, (dcycle * fl_delay_mod);"
+ " .set drem, (\\dtime - dwork);"
+ " .rept (drem);"
+ " nop;"
+ " .endr;"
+ " .if dcycle > 0;"
+ " mov \\reg, #dcycle;"
+ " delayloop_\\@:;"
+ " sub \\reg, #1;"
+ " bne delayloop_\\@;"
+ " .if fl_is_m0p == 0;"
+ " nop;"
+ " .endif;"
+ " .endif;"
+ " .endif;"
+ " .endm;"
+
+ " .macro mod_delay dtime,b1,b2,reg;"
+ " .set adj, (\\b1 + \\b2);"
+ " .if adj < \\dtime;"
+ " .set dtime2, (\\dtime - adj);"
+ " fl_delay dtime2, \\reg;"
+ " .endif;"
+ " .endm;"
+
+ // check the bit and drop the line low if it isn't set
+ " .macro qlo4 b,bitmask,port,loff ;"
+ " lsl \\b, #1 ;"
+ " bcs skip_\\@ ;"
+ " str \\bitmask, [\\port, \\loff] ;"
+ " skip_\\@: ;"
+ " m0pad;"
+ " .endm ;"
+
+ // set the pin hi or low (determined by the offset passed in )
+ " .macro qset2 bitmask,port,loff;"
+ " str \\bitmask, [\\port, \\loff];"
+ " m0pad;"
+ " .endm;"
+
+ // Load up the next led byte to work with, put it in bn
+ " .macro loadleds3 leds, bn, rled, scratch;"
+ " mov \\scratch, \\leds;"
+ " ldrb \\bn, [\\scratch, \\rled];"
+ " .endm;"
+
+ // check whether or not we should dither
+ " .macro loaddither7 bn,d,base,rdither;"
+ " ldrb \\d, [\\base, \\rdither];"
+ " lsl \\d, #24;" //; shift high for the qadd w/bn
+ " lsl \\bn, #24;" //; shift high for the qadd w/d
+ " bne chkskip_\\@;" //; if bn==0, clear d;"
+ " eor \\d, \\d;" //; clear d;"
+ " m0pad;"
+ " chkskip_\\@:;"
+ " .endm;"
+
+ // Do the qadd8 for dithering -- there's two versions of this. The m0 version
+ // takes advantage of the 3 cycle branch to do two things after the branch,
+ // while keeping timing constant. The m0+, however, branches in 2 cycles, so
+ // we have to work around that a bit more. This is one of the few times
+ // where the m0 will actually be _more_ efficient than the m0+
+ " .macro dither5 bn,d;"
+ " .syntax unified;"
+ " .if fl_is_m0p == 0;"
+ " adds \\bn, \\d;" // do the add
+ " bcc dither5_1_\\@;"
+ " mvns \\bn, \\bn;" // set the low 24bits ot 1's
+ " lsls \\bn, \\bn, #24;" // move low 8 bits to the high bits
+ " dither5_1_\\@:;"
+ " nop;" // nop to keep timing in line
+ " .else;"
+ " adds \\bn, \\d;" // do the add"
+ " bcc dither5_2_\\@;"
+ " mvns \\bn, \\bn;" // set the low 24bits ot 1's
+ " dither5_2_\\@:;"
+ " bcc dither5_3_\\@;"
+ " lsls \\bn, \\bn, #24;" // move low 8 bits to the high bits
+ " dither5_3_\\@:;"
+ " .endif;"
+ " .syntax divided;"
+ " .endm;"
+
+ // Do our scaling
+ " .macro scale4 bn, base, scale, scratch;"
+ " ldr \\scratch, [\\base, \\scale];"
+ " lsr \\bn, \\bn, #24;" // bring bn back down to its low 8 bits
+ " mul \\bn, \\scratch;" // do the multiply
+ " .endm;"
+
+ // swap bn into b
+ " .macro swapbbn1 b,bn;"
+ " lsl \\b, \\bn, #16;" // put the 8 bits we want for output high
+ " .endm;"
+
+ // adjust the dithering value for the next time around (load e from memory
+ // to do the math)
+ " .macro adjdither7 base,d,rled,eoffset,scratch;"
+ " ldrb \\d, [\\base, \\rled];"
+ " ldrb \\scratch,[\\base,\\eoffset];" // load e
+ " .syntax unified;"
+ " subs \\d, \\scratch, \\d;" // d=e-d
+ " .syntax divided;"
+ " strb \\d, [\\base, \\rled];" // save d
+ " .endm;"
+
+ // increment the led pointer (base+6 has what we're incrementing by)
+ " .macro incleds3 leds, base, scratch;"
+ " ldrb \\scratch, [\\base, #6];" // load incremen
+ " add \\leds, \\leds, \\scratch;" // update leds pointer
+ " .endm;"
+
+ // compare and loop
+ " .macro cmploop5 counter,label;"
+ " .syntax unified;"
+ " subs \\counter, #1;"
+ " .syntax divided;"
+ " beq done_\\@;"
+ " m0pad;"
+ " b \\label;"
+ " done_\\@:;"
+ " .endm;"
+
+ " .endif;"
+ );
+
+#define M0_ASM_ARGS : \
+ [leds] "+h" (leds), \
+ [counter] "+l" (counter), \
+ [scratch] "+l" (scratch), \
+ [d] "+l" (d), \
+ [bn] "+l" (bn), \
+ [b] "+l" (b) \
+ : \
+ [port] "l" (port), \
+ [base] "l" (base), \
+ [bitmask] "l" (bitmask), \
+ [hi_off] "I" (HI_OFFSET), \
+ [lo_off] "I" (LO_OFFSET), \
+ [led0] "I" (RO(0)), \
+ [led1] "I" (RO(1)), \
+ [led2] "I" (RO(2)), \
+ [e0] "I" (3+RO(0)), \
+ [e1] "I" (3+RO(1)), \
+ [e2] "I" (3+RO(2)), \
+ [scale0] "I" (4*(2+RO(0))), \
+ [scale1] "I" (4*(2+RO(1))), \
+ [scale2] "I" (4*(2+RO(2))), \
+ [T1] "I" (T1), \
+ [T2] "I" (T2), \
+ [T3] "I" (T3) \
+ :
+
+ /////////////////////////////////////////////////////////////////////////
+ // now for some convinience macros to make building our lines a bit cleaner
+#define LOOP " loop_%=:"
+#define HI2 " qset2 %[bitmask], %[port], %[hi_off];"
+#define D1 " mod_delay %c[T1],2,0,%[scratch];"
+#define QLO4 " qlo4 %[b],%[bitmask],%[port], %[lo_off];"
+#define LOADLEDS3(X) " loadleds3 %[leds], %[bn], %[led" #X "] ,%[scratch];"
+#define D2(ADJ) " mod_delay %c[T2],4," #ADJ ",%[scratch];"
+#define LO2 " qset2 %[bitmask], %[port], %[lo_off];"
+#define D3(ADJ) " mod_delay %c[T3],2," #ADJ ",%[scratch];"
+#define LOADDITHER7(X) " loaddither7 %[bn], %[d], %[base], %[led" #X "];"
+#define DITHER5 " dither5 %[bn], %[d];"
+#define SCALE4(X) " scale4 %[bn], %[base], %[scale" #X "], %[scratch];"
+#define SWAPBBN1 " swapbbn1 %[b], %[bn];"
+#define ADJDITHER7(X) " adjdither7 %[base],%[d],%[led" #X "],%[e" #X "],%[scratch];"
+#define INCLEDS3 " incleds3 %[leds],%[base],%[scratch];"
+#define CMPLOOP5 " cmploop5 %[counter], loop_%=;"
+#define NOTHING ""
+
+#if !(defined(SEI_CHK) && (FASTLED_ALLOW_INTERRUPTS == 1))
+ // We're not allowing interrupts - run the entire loop in asm to keep things
+ // as tight as possible. In an ideal world, we should be pushing out ws281x
+ // leds (or other 3-wire leds) with zero gaps between pixels.
+ asm __volatile__ (
+ // pre-load byte 0
+ LOADLEDS3(0) LOADDITHER7(0) DITHER5 SCALE4(0) ADJDITHER7(0) SWAPBBN1
+
+ // loop over writing out the data
+ LOOP
+ // Write out byte 0, prepping byte 1
+ HI2 D1 QLO4 NOTHING D2(0) LO2 D3(0)
+ HI2 D1 QLO4 LOADLEDS3(1) D2(3) LO2 D3(0)
+ HI2 D1 QLO4 LOADDITHER7(1) D2(7) LO2 D3(0)
+ HI2 D1 QLO4 DITHER5 D2(5) LO2 D3(0)
+ HI2 D1 QLO4 SCALE4(1) D2(4) LO2 D3(0)
+ HI2 D1 QLO4 ADJDITHER7(1) D2(7) LO2 D3(0)
+ HI2 D1 QLO4 NOTHING D2(0) LO2 D3(0)
+ HI2 D1 QLO4 SWAPBBN1 D2(1) LO2 D3(0)
+
+ // Write out byte 1, prepping byte 2
+ HI2 D1 QLO4 NOTHING D2(0) LO2 D3(0)
+ HI2 D1 QLO4 LOADLEDS3(2) D2(3) LO2 D3(0)
+ HI2 D1 QLO4 LOADDITHER7(2) D2(7) LO2 D3(0)
+ HI2 D1 QLO4 DITHER5 D2(5) LO2 D3(0)
+ HI2 D1 QLO4 SCALE4(2) D2(4) LO2 D3(0)
+ HI2 D1 QLO4 ADJDITHER7(2) D2(7) LO2 D3(0)
+ HI2 D1 QLO4 INCLEDS3 D2(3) LO2 D3(0)
+ HI2 D1 QLO4 SWAPBBN1 D2(1) LO2 D3(0)
+
+ // Write out byte 2, prepping byte 0
+ HI2 D1 QLO4 NOTHING D2(0) LO2 D3(0)
+ HI2 D1 QLO4 LOADLEDS3(0) D2(3) LO2 D3(0)
+ HI2 D1 QLO4 LOADDITHER7(0) D2(7) LO2 D3(0)
+ HI2 D1 QLO4 DITHER5 D2(5) LO2 D3(0)
+ HI2 D1 QLO4 SCALE4(0) D2(4) LO2 D3(0)
+ HI2 D1 QLO4 ADJDITHER7(0) D2(7) LO2 D3(0)
+ HI2 D1 QLO4 NOTHING D2(0) LO2 D3(0)
+ HI2 D1 QLO4 SWAPBBN1 D2(1) LO2 D3(5) CMPLOOP5
+
+ M0_ASM_ARGS
+ );
+#else
+ // We're allowing interrupts - track the loop outside the asm code, to allow
+ // inserting the interrupt overrun checks.
+ asm __volatile__ (
+ // pre-load byte 0
+ LOADLEDS3(0) LOADDITHER7(0) DITHER5 SCALE4(0) ADJDITHER7(0) SWAPBBN1
+ M0_ASM_ARGS);
+
+ do {
+ asm __volatile__ (
+ // Write out byte 0, prepping byte 1
+ HI2 D1 QLO4 NOTHING D2(0) LO2 D3(0)
+ HI2 D1 QLO4 LOADLEDS3(1) D2(3) LO2 D3(0)
+ HI2 D1 QLO4 LOADDITHER7(1) D2(7) LO2 D3(0)
+ HI2 D1 QLO4 DITHER5 D2(5) LO2 D3(0)
+ HI2 D1 QLO4 SCALE4(1) D2(4) LO2 D3(0)
+ HI2 D1 QLO4 ADJDITHER7(1) D2(7) LO2 D3(0)
+ HI2 D1 QLO4 NOTHING D2(0) LO2 D3(0)
+ HI2 D1 QLO4 SWAPBBN1 D2(1) LO2 D3(0)
+
+ // Write out byte 1, prepping byte 2
+ HI2 D1 QLO4 NOTHING D2(0) LO2 D3(0)
+ HI2 D1 QLO4 LOADLEDS3(2) D2(3) LO2 D3(0)
+ HI2 D1 QLO4 LOADDITHER7(2) D2(7) LO2 D3(0)
+ HI2 D1 QLO4 DITHER5 D2(5) LO2 D3(0)
+ HI2 D1 QLO4 SCALE4(2) D2(4) LO2 D3(0)
+ HI2 D1 QLO4 ADJDITHER7(2) D2(7) LO2 D3(0)
+ HI2 D1 QLO4 NOTHING D2(0) LO2 D3(0)
+ HI2 D1 QLO4 SWAPBBN1 D2(1) LO2 D3(0)
+
+ // Write out byte 2, prepping byte 0
+ HI2 D1 QLO4 INCLEDS3 D2(3) LO2 D3(0)
+ HI2 D1 QLO4 LOADLEDS3(0) D2(3) LO2 D3(0)
+ HI2 D1 QLO4 LOADDITHER7(0) D2(7) LO2 D3(0)
+ HI2 D1 QLO4 DITHER5 D2(5) LO2 D3(0)
+ HI2 D1 QLO4 SCALE4(0) D2(4) LO2 D3(0)
+ HI2 D1 QLO4 ADJDITHER7(0) D2(7) LO2 D3(0)
+ HI2 D1 QLO4 NOTHING D2(0) LO2 D3(0)
+ HI2 D1 QLO4 SWAPBBN1 D2(1) LO2 D3(5)
+
+ M0_ASM_ARGS
+ );
+ SEI_CHK; INNER_SEI; --counter; CLI_CHK;
+ } while(counter);
+#endif
+ return num_leds;
+}
+
+#endif
diff --git a/Библиотеки/FastLED-master/platforms/arm/d21/clockless_arm_d21.h b/Библиотеки/FastLED-master/platforms/arm/d21/clockless_arm_d21.h
new file mode 100644
index 0000000..9144579
--- /dev/null
+++ b/Библиотеки/FastLED-master/platforms/arm/d21/clockless_arm_d21.h
@@ -0,0 +1,61 @@
+#ifndef __INC_CLOCKLESS_ARM_D21
+#define __INC_CLOCKLESS_ARM_D21
+
+#include "platforms/arm/common/m0clockless.h"
+FASTLED_NAMESPACE_BEGIN
+#define FASTLED_HAS_CLOCKLESS 1
+
+template <uint8_t DATA_PIN, int T1, int T2, int T3, EOrder RGB_ORDER = RGB, int XTRA0 = 0, bool FLIP = false, int WAIT_TIME = 50>
+class ClocklessController : public CPixelLEDController<RGB_ORDER> {
+ typedef typename FastPinBB<DATA_PIN>::port_ptr_t data_ptr_t;
+ typedef typename FastPinBB<DATA_PIN>::port_t data_t;
+
+ data_t mPinMask;
+ data_ptr_t mPort;
+ CMinWait<WAIT_TIME> mWait;
+public:
+ virtual void init() {
+ FastPinBB<DATA_PIN>::setOutput();
+ mPinMask = FastPinBB<DATA_PIN>::mask();
+ mPort = FastPinBB<DATA_PIN>::port();
+ }
+
+ virtual uint16_t getMaxRefreshRate() const { return 400; }
+
+ virtual void showPixels(PixelController<RGB_ORDER> & pixels) {
+ mWait.wait();
+ cli();
+ if(!showRGBInternal(pixels)) {
+ sei(); delayMicroseconds(WAIT_TIME); cli();
+ showRGBInternal(pixels);
+ }
+ sei();
+ mWait.mark();
+ }
+
+ // This method is made static to force making register Y available to use for data on AVR - if the method is non-static, then
+ // gcc will use register Y for the this pointer.
+ static uint32_t showRGBInternal(PixelController<RGB_ORDER> pixels) {
+ struct M0ClocklessData data;
+ data.d[0] = pixels.d[0];
+ data.d[1] = pixels.d[1];
+ data.d[2] = pixels.d[2];
+ data.s[0] = pixels.mScale[0];
+ data.s[1] = pixels.mScale[1];
+ data.s[2] = pixels.mScale[2];
+ data.e[0] = pixels.e[0];
+ data.e[1] = pixels.e[1];
+ data.e[2] = pixels.e[2];
+ data.adj = pixels.mAdvance;
+
+ typename FastPin<DATA_PIN>::port_ptr_t portBase = FastPin<DATA_PIN>::port();
+ return showLedData<8,4,T1,T2,T3,RGB_ORDER, WAIT_TIME>(portBase, FastPin<DATA_PIN>::mask(), pixels.mData, pixels.mLen, &data);
+ }
+
+
+};
+
+FASTLED_NAMESPACE_END
+
+
+#endif // __INC_CLOCKLESS_ARM_D21
diff --git a/Библиотеки/FastLED-master/platforms/arm/d21/fastled_arm_d21.h b/Библиотеки/FastLED-master/platforms/arm/d21/fastled_arm_d21.h
new file mode 100644
index 0000000..3a62efc
--- /dev/null
+++ b/Библиотеки/FastLED-master/platforms/arm/d21/fastled_arm_d21.h
@@ -0,0 +1,8 @@
+#ifndef __INC_FASTLED_ARM_D21_H
+#define __INC_FASTLED_ARM_D21_H
+
+#include "fastled_delay.h"
+#include "fastpin_arm_d21.h"
+#include "clockless_arm_d21.h"
+
+#endif
diff --git a/Библиотеки/FastLED-master/platforms/arm/d21/fastpin_arm_d21.h b/Библиотеки/FastLED-master/platforms/arm/d21/fastpin_arm_d21.h
new file mode 100644
index 0000000..8e83dd4
--- /dev/null
+++ b/Библиотеки/FastLED-master/platforms/arm/d21/fastpin_arm_d21.h
@@ -0,0 +1,153 @@
+#ifndef __INC_FASTPIN_ARM_SAM_H
+#define __INC_FASTPIN_ARM_SAM_H
+
+FASTLED_NAMESPACE_BEGIN
+
+#if defined(FASTLED_FORCE_SOFTWARE_PINS)
+#warning "Software pin support forced, pin access will be slightly slower."
+#define NO_HARDWARE_PIN_SUPPORT
+#undef HAS_HARDWARE_PIN_SUPPORT
+
+#else
+
+/// Template definition for STM32 style ARM pins, providing direct access to the various GPIO registers. Note that this
+/// uses the full port GPIO registers. In theory, in some way, bit-band register access -should- be faster, however I have found
+/// that something about the way gcc does register allocation results in the bit-band code being slower. It will need more fine tuning.
+/// The registers are data output, set output, clear output, toggle output, input, and direction
+
+template<uint8_t PIN, uint8_t _BIT, uint32_t _MASK, int _GRP> class _ARMPIN {
+public:
+ typedef volatile uint32_t * port_ptr_t;
+ typedef uint32_t port_t;
+
+ #if 0
+ inline static void setOutput() {
+ if(_BIT<8) {
+ _CRL::r() = (_CRL::r() & (0xF << (_BIT*4)) | (0x1 << (_BIT*4));
+ } else {
+ _CRH::r() = (_CRH::r() & (0xF << ((_BIT-8)*4))) | (0x1 << ((_BIT-8)*4));
+ }
+ }
+ inline static void setInput() { /* TODO */ } // TODO: preform MUX config { _PDDR::r() &= ~_MASK; }
+ #endif
+
+ inline static void setOutput() { pinMode(PIN, OUTPUT); } // TODO: perform MUX config { _PDDR::r() |= _MASK; }
+ inline static void setInput() { pinMode(PIN, INPUT); } // TODO: preform MUX config { _PDDR::r() &= ~_MASK; }
+
+ inline static void hi() __attribute__ ((always_inline)) { PORT->Group[_GRP].OUTSET.reg = _MASK; }
+ inline static void lo() __attribute__ ((always_inline)) { PORT->Group[_GRP].OUTCLR.reg = _MASK; }
+ // inline static void lo() __attribute__ ((always_inline)) { PORT->Group[_GRP].BSRR = (_MASK<<16); }
+ inline static void set(register port_t val) __attribute__ ((always_inline)) { PORT->Group[_GRP].OUT.reg = val; }
+
+ inline static void strobe() __attribute__ ((always_inline)) { toggle(); toggle(); }
+
+ inline static void toggle() __attribute__ ((always_inline)) { PORT->Group[_GRP].OUTTGL.reg = _MASK; }
+
+ inline static void hi(register port_ptr_t port) __attribute__ ((always_inline)) { hi(); }
+ inline static void lo(register port_ptr_t port) __attribute__ ((always_inline)) { lo(); }
+ inline static void fastset(register port_ptr_t port, register port_t val) __attribute__ ((always_inline)) { *port = val; }
+
+ inline static port_t hival() __attribute__ ((always_inline)) { return PORT->Group[_GRP].OUT.reg | _MASK; }
+ inline static port_t loval() __attribute__ ((always_inline)) { return PORT->Group[_GRP].OUT.reg & ~_MASK; }
+ inline static port_ptr_t port() __attribute__ ((always_inline)) { return &PORT->Group[_GRP].OUT.reg; }
+ inline static port_ptr_t sport() __attribute__ ((always_inline)) { return &PORT->Group[_GRP].OUTSET.reg; }
+ inline static port_ptr_t cport() __attribute__ ((always_inline)) { return &PORT->Group[_GRP].OUTCLR.reg; }
+ inline static port_t mask() __attribute__ ((always_inline)) { return _MASK; }
+};
+
+#define _R(T) struct __gen_struct_ ## T
+#define _RD32(T) struct __gen_struct_ ## T { static __attribute__((always_inline)) inline volatile PortGroup * r() { return T; } };
+
+#define _IO32(L) _RD32(GPIO ## L)
+
+#define _DEFPIN_ARM(PIN, L, BIT) template<> class FastPin<PIN> : public _ARMPIN<PIN, BIT, 1 << BIT, L> {};
+
+// Actual pin definitions
+#if defined(ARDUINO_SAMD_ZERO)
+
+#define MAX_PIN 42
+_DEFPIN_ARM( 0,0,10); _DEFPIN_ARM( 1,0,11); _DEFPIN_ARM( 2,0, 8); _DEFPIN_ARM( 3,0, 9);
+_DEFPIN_ARM( 4,0,14); _DEFPIN_ARM( 5,0,15); _DEFPIN_ARM( 6,0,20); _DEFPIN_ARM( 7,0,21);
+_DEFPIN_ARM( 8,0, 6); _DEFPIN_ARM( 9,0, 7); _DEFPIN_ARM(10,0,18); _DEFPIN_ARM(11,0,16);
+_DEFPIN_ARM(12,0,19); _DEFPIN_ARM(13,0,17); _DEFPIN_ARM(14,0, 2); _DEFPIN_ARM(15,1, 8);
+_DEFPIN_ARM(16,1, 9); _DEFPIN_ARM(17,0, 4); _DEFPIN_ARM(18,0, 5); _DEFPIN_ARM(19,1, 2);
+_DEFPIN_ARM(20,0,22); _DEFPIN_ARM(21,0,23); _DEFPIN_ARM(22,0,12); _DEFPIN_ARM(23,1,11);
+_DEFPIN_ARM(24,1,10); _DEFPIN_ARM(25,1, 3); _DEFPIN_ARM(26,0,27); _DEFPIN_ARM(27,0,28);
+_DEFPIN_ARM(28,0,24); _DEFPIN_ARM(29,0,25); _DEFPIN_ARM(30,1,22); _DEFPIN_ARM(31,1,23);
+_DEFPIN_ARM(32,0,22); _DEFPIN_ARM(33,0,23); _DEFPIN_ARM(34,0,19); _DEFPIN_ARM(35,0,16);
+_DEFPIN_ARM(36,0,18); _DEFPIN_ARM(37,0,17); _DEFPIN_ARM(38,0,13); _DEFPIN_ARM(39,0,21);
+_DEFPIN_ARM(40,0, 6); _DEFPIN_ARM(41,0, 7); _DEFPIN_ARM(42,0, 3);
+
+#define SPI_DATA 24
+#define SPI_CLOCK 23
+
+#define HAS_HARDWARE_PIN_SUPPORT 1
+
+#elif defined(ARDUINO_SODAQ_AUTONOMO)
+
+#define MAX_PIN 56
+_DEFPIN_ARM( 0,0, 9); _DEFPIN_ARM( 1,0,10); _DEFPIN_ARM( 2,0,11); _DEFPIN_ARM( 3,1,10);
+_DEFPIN_ARM( 4,1,11); _DEFPIN_ARM( 5,1,12); _DEFPIN_ARM( 6,1,13); _DEFPIN_ARM( 7,1,14);
+_DEFPIN_ARM( 8,1,15); _DEFPIN_ARM( 9,0,14); _DEFPIN_ARM(10,0,15); _DEFPIN_ARM(11,0,16);
+_DEFPIN_ARM(12,0,17); _DEFPIN_ARM(13,0,18); _DEFPIN_ARM(14,0,19); _DEFPIN_ARM(15,1,16);
+_DEFPIN_ARM(16,0, 8); _DEFPIN_ARM(17,0,28); _DEFPIN_ARM(18,1,17); _DEFPIN_ARM(19,0, 2);
+_DEFPIN_ARM(20,0, 6); _DEFPIN_ARM(21,0, 5); _DEFPIN_ARM(22,0, 4); _DEFPIN_ARM(23,1, 9);
+_DEFPIN_ARM(24,1, 8); _DEFPIN_ARM(25,1, 7); _DEFPIN_ARM(26,1, 6); _DEFPIN_ARM(27,1, 5);
+_DEFPIN_ARM(28,1, 4); _DEFPIN_ARM(29,0, 7); _DEFPIN_ARM(30,1, 3); _DEFPIN_ARM(31,1, 2);
+_DEFPIN_ARM(32,1, 1); _DEFPIN_ARM(33,1, 0); _DEFPIN_ARM(34,0, 3); _DEFPIN_ARM(35,0, 3);
+_DEFPIN_ARM(36,1,30); _DEFPIN_ARM(37,1,31); _DEFPIN_ARM(38,1,22); _DEFPIN_ARM(39,1,23);
+_DEFPIN_ARM(40,0,12); _DEFPIN_ARM(41,0,13); _DEFPIN_ARM(42,0,22); _DEFPIN_ARM(43,0,23);
+_DEFPIN_ARM(44,0,20); _DEFPIN_ARM(45,0,21); _DEFPIN_ARM(46,0,27); _DEFPIN_ARM(47,0,24);
+_DEFPIN_ARM(48,0,25); _DEFPIN_ARM(49,1,13); _DEFPIN_ARM(50,1,14); _DEFPIN_ARM(51,0,17);
+_DEFPIN_ARM(52,0,18); _DEFPIN_ARM(53,1,12); _DEFPIN_ARM(54,1,13); _DEFPIN_ARM(55,1,14);
+_DEFPIN_ARM(56,1,15);
+
+#define SPI_DATA 44
+#define SPI_CLOCK 45
+
+#define HAS_HARDWARE_PIN_SUPPORT 1
+
+#elif defined(ARDUINO_SAMD_WINO)
+
+#define MAX_PIN 22
+_DEFPIN_ARM( 0, 0, 23); _DEFPIN_ARM( 1, 0, 22); _DEFPIN_ARM( 2, 0, 16); _DEFPIN_ARM( 3, 0, 17);
+_DEFPIN_ARM( 4, 0, 18); _DEFPIN_ARM( 5, 0, 19); _DEFPIN_ARM( 6, 0, 24); _DEFPIN_ARM( 7, 0, 25);
+_DEFPIN_ARM( 8, 0, 27); _DEFPIN_ARM( 9, 0, 28); _DEFPIN_ARM( 10, 0, 30); _DEFPIN_ARM( 11, 0, 31);
+_DEFPIN_ARM( 12, 0, 15); _DEFPIN_ARM( 13, 0, 14); _DEFPIN_ARM( 14, 0, 2); _DEFPIN_ARM( 15, 0, 3);
+_DEFPIN_ARM( 16, 0, 4); _DEFPIN_ARM( 17, 0, 5); _DEFPIN_ARM( 18, 0, 6); _DEFPIN_ARM( 19, 0, 7);
+_DEFPIN_ARM( 20, 0, 8); _DEFPIN_ARM( 21, 0, 9); _DEFPIN_ARM( 22, 0, 10); _DEFPIN_ARM( 23, 0, 11);
+
+#define HAS_HARDWARE_PIN_SUPPORT 1
+
+#elif defined(ARDUINO_SAMD_MKR1000)
+
+#define MAX_PIN 22
+_DEFPIN_ARM( 0, 0, 22); _DEFPIN_ARM( 1, 0, 23); _DEFPIN_ARM( 2, 0, 10); _DEFPIN_ARM( 3, 0, 11);
+_DEFPIN_ARM( 4, 1, 10); _DEFPIN_ARM( 5, 1, 11); _DEFPIN_ARM( 6, 0, 20); _DEFPIN_ARM( 7, 0, 21);
+_DEFPIN_ARM( 8, 0, 16); _DEFPIN_ARM( 9, 0, 17); _DEFPIN_ARM( 10, 0, 19); _DEFPIN_ARM( 11, 0, 8);
+_DEFPIN_ARM( 12, 0, 9); _DEFPIN_ARM( 13, 1, 23); _DEFPIN_ARM( 14, 1, 22); _DEFPIN_ARM( 15, 0, 2);
+_DEFPIN_ARM( 16, 1, 2); _DEFPIN_ARM( 17, 1, 3); _DEFPIN_ARM( 18, 0, 4); _DEFPIN_ARM( 19, 0, 5);
+_DEFPIN_ARM( 20, 0, 6); _DEFPIN_ARM( 21, 0, 7);
+
+#define SPI_DATA 8
+#define SPI_CLOCK 9
+
+#define HAS_HARDWARE_PIN_SUPPORT 1
+
+#elif defined(ARDUINO_GEMMA_M0)
+
+#define MAX_PIN 3
+_DEFPIN_ARM( 0, 0, 8); _DEFPIN_ARM( 1, 0, 2); _DEFPIN_ARM( 2, 0, 9);
+
+#define HAS_HARDWARE_PIN_SUPPORT 0
+
+#endif
+
+
+
+#endif // FASTLED_FORCE_SOFTWARE_PINS
+
+FASTLED_NAMESPACE_END
+
+
+#endif // __INC_FASTPIN_ARM_SAM_H
diff --git a/Библиотеки/FastLED-master/platforms/arm/d21/led_sysdefs_arm_d21.h b/Библиотеки/FastLED-master/platforms/arm/d21/led_sysdefs_arm_d21.h
new file mode 100644
index 0000000..b343d3f
--- /dev/null
+++ b/Библиотеки/FastLED-master/platforms/arm/d21/led_sysdefs_arm_d21.h
@@ -0,0 +1,26 @@
+#ifndef __INC_LED_SYSDEFS_ARM_D21_H
+#define __INC_LED_SYSDEFS_ARM_D21_H
+
+
+#define FASTLED_ARM
+#define FASTLED_ARM_M0_PLUS
+
+#ifndef INTERRUPT_THRESHOLD
+#define INTERRUPT_THRESHOLD 1
+#endif
+
+// Default to allowing interrupts
+#ifndef FASTLED_ALLOW_INTERRUPTS
+#define FASTLED_ALLOW_INTERRUPTS 0
+#endif
+
+#if FASTLED_ALLOW_INTERRUPTS == 1
+#define FASTLED_ACCURATE_CLOCK
+#endif
+
+// reusing/abusing cli/sei defs for due
+#define cli() __disable_irq();
+#define sei() __enable_irq();
+
+
+#endif
diff --git a/Библиотеки/FastLED-master/platforms/arm/k20/clockless_arm_k20.h b/Библиотеки/FastLED-master/platforms/arm/k20/clockless_arm_k20.h
new file mode 100644
index 0000000..bc2090b
--- /dev/null
+++ b/Библиотеки/FastLED-master/platforms/arm/k20/clockless_arm_k20.h
@@ -0,0 +1,124 @@
+#ifndef __INC_CLOCKLESS_ARM_K20_H
+#define __INC_CLOCKLESS_ARM_K20_H
+
+FASTLED_NAMESPACE_BEGIN
+
+// Definition for a single channel clockless controller for the k20 family of chips, like that used in the teensy 3.0/3.1
+// See clockless.h for detailed info on how the template parameters are used.
+#if defined(FASTLED_TEENSY3)
+
+#define FASTLED_HAS_CLOCKLESS 1
+
+template <int DATA_PIN, int T1, int T2, int T3, EOrder RGB_ORDER = RGB, int XTRA0 = 0, bool FLIP = false, int WAIT_TIME = 50>
+class ClocklessController : public CPixelLEDController<RGB_ORDER> {
+ typedef typename FastPin<DATA_PIN>::port_ptr_t data_ptr_t;
+ typedef typename FastPin<DATA_PIN>::port_t data_t;
+
+ data_t mPinMask;
+ data_ptr_t mPort;
+ CMinWait<WAIT_TIME> mWait;
+public:
+ virtual void init() {
+ FastPin<DATA_PIN>::setOutput();
+ mPinMask = FastPin<DATA_PIN>::mask();
+ mPort = FastPin<DATA_PIN>::port();
+ }
+
+ virtual uint16_t getMaxRefreshRate() const { return 400; }
+
+protected:
+
+ virtual void showPixels(PixelController<RGB_ORDER> & pixels) {
+ mWait.wait();
+ if(!showRGBInternal(pixels)) {
+ sei(); delayMicroseconds(WAIT_TIME); cli();
+ showRGBInternal(pixels);
+ }
+ mWait.mark();
+ }
+
+ template<int BITS> __attribute__ ((always_inline)) inline static void writeBits(register uint32_t & next_mark, register data_ptr_t port, register data_t hi, register data_t lo, register uint8_t & b) {
+ for(register uint32_t i = BITS-1; i > 0; i--) {
+ while(ARM_DWT_CYCCNT < next_mark);
+ next_mark = ARM_DWT_CYCCNT + (T1+T2+T3);
+ FastPin<DATA_PIN>::fastset(port, hi);
+ if(b&0x80) {
+ while((next_mark - ARM_DWT_CYCCNT) > (T3+(2*(F_CPU/24000000))));
+ FastPin<DATA_PIN>::fastset(port, lo);
+ } else {
+ while((next_mark - ARM_DWT_CYCCNT) > (T2+T3+(2*(F_CPU/24000000))));
+ FastPin<DATA_PIN>::fastset(port, lo);
+ }
+ b <<= 1;
+ }
+
+ while(ARM_DWT_CYCCNT < next_mark);
+ next_mark = ARM_DWT_CYCCNT + (T1+T2+T3);
+ FastPin<DATA_PIN>::fastset(port, hi);
+
+ if(b&0x80) {
+ while((next_mark - ARM_DWT_CYCCNT) > (T3+(2*(F_CPU/24000000))));
+ FastPin<DATA_PIN>::fastset(port, lo);
+ } else {
+ while((next_mark - ARM_DWT_CYCCNT) > (T2+T3+(2*(F_CPU/24000000))));
+ FastPin<DATA_PIN>::fastset(port, lo);
+ }
+ }
+
+ // This method is made static to force making register Y available to use for data on AVR - if the method is non-static, then
+ // gcc will use register Y for the this pointer.
+ static uint32_t showRGBInternal(PixelController<RGB_ORDER> pixels) {
+ // Get access to the clock
+ ARM_DEMCR |= ARM_DEMCR_TRCENA;
+ ARM_DWT_CTRL |= ARM_DWT_CTRL_CYCCNTENA;
+ ARM_DWT_CYCCNT = 0;
+
+ register data_ptr_t port = FastPin<DATA_PIN>::port();
+ register data_t hi = *port | FastPin<DATA_PIN>::mask();;
+ register data_t lo = *port & ~FastPin<DATA_PIN>::mask();;
+ *port = lo;
+
+ // Setup the pixel controller and load/scale the first byte
+ pixels.preStepFirstByteDithering();
+ register uint8_t b = pixels.loadAndScale0();
+
+ cli();
+ uint32_t next_mark = ARM_DWT_CYCCNT + (T1+T2+T3);
+
+ while(pixels.has(1)) {
+ pixels.stepDithering();
+ #if (FASTLED_ALLOW_INTERRUPTS == 1)
+ cli();
+ // if interrupts took longer than 45µs, punt on the current frame
+ if(ARM_DWT_CYCCNT > next_mark) {
+ if((ARM_DWT_CYCCNT-next_mark) > ((WAIT_TIME-INTERRUPT_THRESHOLD)*CLKS_PER_US)) { sei(); return 0; }
+ }
+
+ hi = *port | FastPin<DATA_PIN>::mask();
+ lo = *port & ~FastPin<DATA_PIN>::mask();
+ #endif
+ // Write first byte, read next byte
+ writeBits<8+XTRA0>(next_mark, port, hi, lo, b);
+ b = pixels.loadAndScale1();
+
+ // Write second byte, read 3rd byte
+ writeBits<8+XTRA0>(next_mark, port, hi, lo, b);
+ b = pixels.loadAndScale2();
+
+ // Write third byte, read 1st byte of next pixel
+ writeBits<8+XTRA0>(next_mark, port, hi, lo, b);
+ b = pixels.advanceAndLoadAndScale0();
+ #if (FASTLED_ALLOW_INTERRUPTS == 1)
+ sei();
+ #endif
+ };
+
+ sei();
+ return ARM_DWT_CYCCNT;
+ }
+};
+#endif
+
+FASTLED_NAMESPACE_END
+
+#endif
diff --git a/Библиотеки/FastLED-master/platforms/arm/k20/clockless_block_arm_k20.h b/Библиотеки/FastLED-master/platforms/arm/k20/clockless_block_arm_k20.h
new file mode 100644
index 0000000..f2b7646
--- /dev/null
+++ b/Библиотеки/FastLED-master/platforms/arm/k20/clockless_block_arm_k20.h
@@ -0,0 +1,330 @@
+#ifndef __INC_BLOCK_CLOCKLESS_ARM_K20_H
+#define __INC_BLOCK_CLOCKLESS_ARM_K20_H
+
+// Definition for a single channel clockless controller for the k20 family of chips, like that used in the teensy 3.0/3.1
+// See clockless.h for detailed info on how the template parameters are used.
+#if defined(FASTLED_TEENSY3)
+#define FASTLED_HAS_BLOCKLESS 1
+
+#define PORTC_FIRST_PIN 15
+#define PORTD_FIRST_PIN 2
+#define HAS_PORTDC 1
+
+#define PORT_MASK (((1<<LANES)-1) & ((FIRST_PIN==2) ? 0xFF : 0xFFF))
+
+#define MIN(X,Y) (((X)<(Y)) ? (X):(Y))
+#define USED_LANES ((FIRST_PIN==2) ? MIN(LANES,8) : MIN(LANES,12))
+
+#include "kinetis.h"
+
+FASTLED_NAMESPACE_BEGIN
+
+template <uint8_t LANES, int FIRST_PIN, int T1, int T2, int T3, EOrder RGB_ORDER = GRB, int XTRA0 = 0, bool FLIP = false, int WAIT_TIME = 40>
+class InlineBlockClocklessController : public CPixelLEDController<RGB_ORDER, LANES, PORT_MASK> {
+ typedef typename FastPin<FIRST_PIN>::port_ptr_t data_ptr_t;
+ typedef typename FastPin<FIRST_PIN>::port_t data_t;
+
+ data_t mPinMask;
+ data_ptr_t mPort;
+ CMinWait<WAIT_TIME> mWait;
+public:
+ virtual int size() { return CLEDController::size() * LANES; }
+
+ virtual void showPixels(PixelController<RGB_ORDER, LANES, PORT_MASK> & pixels) {
+ mWait.wait();
+ uint32_t clocks = showRGBInternal(pixels);
+ #if FASTLED_ALLOW_INTTERUPTS == 0
+ // Adjust the timer
+ long microsTaken = CLKS_TO_MICROS(clocks);
+ MS_COUNTER += (1 + (microsTaken / 1000));
+ #endif
+
+ mWait.mark();
+ }
+
+ virtual void init() {
+ if(FIRST_PIN == PORTC_FIRST_PIN) { // PORTC
+ switch(USED_LANES) {
+ case 12: FastPin<30>::setOutput();
+ case 11: FastPin<29>::setOutput();
+ case 10: FastPin<27>::setOutput();
+ case 9: FastPin<28>::setOutput();
+ case 8: FastPin<12>::setOutput();
+ case 7: FastPin<11>::setOutput();
+ case 6: FastPin<13>::setOutput();
+ case 5: FastPin<10>::setOutput();
+ case 4: FastPin<9>::setOutput();
+ case 3: FastPin<23>::setOutput();
+ case 2: FastPin<22>::setOutput();
+ case 1: FastPin<15>::setOutput();
+ }
+ } else if(FIRST_PIN == PORTD_FIRST_PIN) { // PORTD
+ switch(USED_LANES) {
+ case 8: FastPin<5>::setOutput();
+ case 7: FastPin<21>::setOutput();
+ case 6: FastPin<20>::setOutput();
+ case 5: FastPin<6>::setOutput();
+ case 4: FastPin<8>::setOutput();
+ case 3: FastPin<7>::setOutput();
+ case 2: FastPin<14>::setOutput();
+ case 1: FastPin<2>::setOutput();
+ }
+ }
+ mPinMask = FastPin<FIRST_PIN>::mask();
+ mPort = FastPin<FIRST_PIN>::port();
+ }
+
+ virtual uint16_t getMaxRefreshRate() const { return 400; }
+
+ typedef union {
+ uint8_t bytes[12];
+ uint16_t shorts[6];
+ uint32_t raw[3];
+ } Lines;
+
+ template<int BITS,int PX> __attribute__ ((always_inline)) inline static void writeBits(register uint32_t & next_mark, register Lines & b, PixelController<RGB_ORDER, LANES, PORT_MASK> &pixels) { // , register uint32_t & b2) {
+ register Lines b2;
+ if(USED_LANES>8) {
+ transpose8<1,2>(b.bytes,b2.bytes);
+ transpose8<1,2>(b.bytes+8,b2.bytes+1);
+ } else {
+ transpose8x1(b.bytes,b2.bytes);
+ }
+ register uint8_t d = pixels.template getd<PX>(pixels);
+ register uint8_t scale = pixels.template getscale<PX>(pixels);
+
+ for(register uint32_t i = 0; i < (USED_LANES/2); i++) {
+ while(ARM_DWT_CYCCNT < next_mark);
+ next_mark = ARM_DWT_CYCCNT + (T1+T2+T3)-3;
+ *FastPin<FIRST_PIN>::sport() = PORT_MASK;
+
+ while((next_mark - ARM_DWT_CYCCNT) > (T2+T3+(2*(F_CPU/24000000))));
+ if(USED_LANES>8) {
+ *FastPin<FIRST_PIN>::cport() = ((~b2.shorts[i]) & PORT_MASK);
+ } else {
+ *FastPin<FIRST_PIN>::cport() = ((~b2.bytes[7-i]) & PORT_MASK);
+ }
+
+ while((next_mark - ARM_DWT_CYCCNT) > (T3));
+ *FastPin<FIRST_PIN>::cport() = PORT_MASK;
+
+ b.bytes[i] = pixels.template loadAndScale<PX>(pixels,i,d,scale);
+ b.bytes[i+(USED_LANES/2)] = pixels.template loadAndScale<PX>(pixels,i+(USED_LANES/2),d,scale);
+ }
+
+ // if folks use an odd numnber of lanes, get the last byte's value here
+ if(USED_LANES & 0x01) {
+ b.bytes[USED_LANES-1] = pixels.template loadAndScale<PX>(pixels,USED_LANES-1,d,scale);
+ }
+
+ for(register uint32_t i = USED_LANES/2; i < 8; i++) {
+ while(ARM_DWT_CYCCNT < next_mark);
+ next_mark = ARM_DWT_CYCCNT + (T1+T2+T3)-3;
+ *FastPin<FIRST_PIN>::sport() = PORT_MASK;
+ while((next_mark - ARM_DWT_CYCCNT) > (T2+T3+(2*(F_CPU/24000000))));
+ if(USED_LANES>8) {
+ *FastPin<FIRST_PIN>::cport() = ((~b2.shorts[i]) & PORT_MASK);
+ } else {
+ // b2.bytes[0] = 0;
+ *FastPin<FIRST_PIN>::cport() = ((~b2.bytes[7-i]) & PORT_MASK);
+ }
+
+ while((next_mark - ARM_DWT_CYCCNT) > (T3));
+ *FastPin<FIRST_PIN>::cport() = PORT_MASK;
+
+ }
+ }
+
+
+
+ // This method is made static to force making register Y available to use for data on AVR - if the method is non-static, then
+ // gcc will use register Y for the this pointer.
+ static uint32_t showRGBInternal(PixelController<RGB_ORDER, LANES, PORT_MASK> &allpixels) {
+ // Get access to the clock
+ ARM_DEMCR |= ARM_DEMCR_TRCENA;
+ ARM_DWT_CTRL |= ARM_DWT_CTRL_CYCCNTENA;
+ ARM_DWT_CYCCNT = 0;
+
+ // Setup the pixel controller and load/scale the first byte
+ allpixels.preStepFirstByteDithering();
+ register Lines b0;
+
+ allpixels.preStepFirstByteDithering();
+ for(int i = 0; i < USED_LANES; i++) {
+ b0.bytes[i] = allpixels.loadAndScale0(i);
+ }
+
+ cli();
+ uint32_t next_mark = ARM_DWT_CYCCNT + (T1+T2+T3);
+
+ while(allpixels.has(1)) {
+ #if (FASTLED_ALLOW_INTERRUPTS == 1)
+ cli();
+ // if interrupts took longer than 45µs, punt on the current frame
+ if(ARM_DWT_CYCCNT > next_mark) {
+ if((ARM_DWT_CYCCNT-next_mark) > ((WAIT_TIME-5)*CLKS_PER_US)) { sei(); return ARM_DWT_CYCCNT; }
+ }
+ #endif
+ allpixels.stepDithering();
+
+ // Write first byte, read next byte
+ writeBits<8+XTRA0,1>(next_mark, b0, allpixels);
+
+ // Write second byte, read 3rd byte
+ writeBits<8+XTRA0,2>(next_mark, b0, allpixels);
+ allpixels.advanceData();
+
+ // Write third byte
+ writeBits<8+XTRA0,0>(next_mark, b0, allpixels);
+ #if (FASTLED_ALLOW_INTERRUPTS == 1)
+ sei();
+ #endif
+ };
+
+ return ARM_DWT_CYCCNT;
+ }
+};
+
+#define PMASK ((1<<(LANES))-1)
+#define PMASK_HI (PMASK>>8 & 0xFF)
+#define PMASK_LO (PMASK & 0xFF)
+
+template <uint8_t LANES, int T1, int T2, int T3, EOrder RGB_ORDER = GRB, int XTRA0 = 0, bool FLIP = false, int WAIT_TIME = 50>
+class SixteenWayInlineBlockClocklessController : public CPixelLEDController<RGB_ORDER, LANES, PMASK> {
+ typedef typename FastPin<PORTC_FIRST_PIN>::port_ptr_t data_ptr_t;
+ typedef typename FastPin<PORTC_FIRST_PIN>::port_t data_t;
+
+ data_t mPinMask;
+ data_ptr_t mPort;
+ CMinWait<WAIT_TIME> mWait;
+public:
+ virtual void init() {
+ static_assert(LANES <= 16, "Maximum of 16 lanes for Teensy parallel controllers!");
+ // FastPin<30>::setOutput();
+ // FastPin<29>::setOutput();
+ // FastPin<27>::setOutput();
+ // FastPin<28>::setOutput();
+ switch(LANES) {
+ case 16: FastPin<12>::setOutput();
+ case 15: FastPin<11>::setOutput();
+ case 14: FastPin<13>::setOutput();
+ case 13: FastPin<10>::setOutput();
+ case 12: FastPin<9>::setOutput();
+ case 11: FastPin<23>::setOutput();
+ case 10: FastPin<22>::setOutput();
+ case 9: FastPin<15>::setOutput();
+
+ case 8: FastPin<5>::setOutput();
+ case 7: FastPin<21>::setOutput();
+ case 6: FastPin<20>::setOutput();
+ case 5: FastPin<6>::setOutput();
+ case 4: FastPin<8>::setOutput();
+ case 3: FastPin<7>::setOutput();
+ case 2: FastPin<14>::setOutput();
+ case 1: FastPin<2>::setOutput();
+ }
+ }
+
+ virtual void showPixels(PixelController<RGB_ORDER, LANES, PMASK> & pixels) {
+ mWait.wait();
+ uint32_t clocks = showRGBInternal(pixels);
+ #if FASTLED_ALLOW_INTTERUPTS == 0
+ // Adjust the timer
+ long microsTaken = CLKS_TO_MICROS(clocks);
+ MS_COUNTER += (1 + (microsTaken / 1000));
+ #endif
+
+ mWait.mark();
+ }
+
+ typedef union {
+ uint8_t bytes[16];
+ uint16_t shorts[8];
+ uint32_t raw[4];
+ } Lines;
+
+ template<int BITS,int PX> __attribute__ ((always_inline)) inline static void writeBits(register uint32_t & next_mark, register Lines & b, PixelController<RGB_ORDER,LANES, PMASK> &pixels) { // , register uint32_t & b2) {
+ register Lines b2;
+ transpose8x1(b.bytes,b2.bytes);
+ transpose8x1(b.bytes+8,b2.bytes+8);
+ register uint8_t d = pixels.template getd<PX>(pixels);
+ register uint8_t scale = pixels.template getscale<PX>(pixels);
+
+ for(register uint32_t i = 0; (i < LANES) && (i < 8); i++) {
+ while(ARM_DWT_CYCCNT < next_mark);
+ next_mark = ARM_DWT_CYCCNT + (T1+T2+T3)-3;
+ *FastPin<PORTD_FIRST_PIN>::sport() = PMASK_LO;
+ *FastPin<PORTC_FIRST_PIN>::sport() = PMASK_HI;
+
+ while((next_mark - ARM_DWT_CYCCNT) > (T2+T3+6));
+ *FastPin<PORTD_FIRST_PIN>::cport() = ((~b2.bytes[7-i]) & PMASK_LO);
+ *FastPin<PORTC_FIRST_PIN>::cport() = ((~b2.bytes[15-i]) & PMASK_HI);
+
+ while((next_mark - ARM_DWT_CYCCNT) > (T3));
+ *FastPin<PORTD_FIRST_PIN>::cport() = PMASK_LO;
+ *FastPin<PORTC_FIRST_PIN>::cport() = PMASK_HI;
+
+ b.bytes[i] = pixels.template loadAndScale<PX>(pixels,i,d,scale);
+ if(LANES==16 || (LANES>8 && ((i+8) < LANES))) {
+ b.bytes[i+8] = pixels.template loadAndScale<PX>(pixels,i+8,d,scale);
+ }
+ }
+ }
+
+
+
+ // This method is made static to force making register Y available to use for data on AVR - if the method is non-static, then
+ // gcc will use register Y for the this pointer.
+ static uint32_t showRGBInternal(PixelController<RGB_ORDER,LANES, PMASK> &allpixels) {
+ // Get access to the clock
+ ARM_DEMCR |= ARM_DEMCR_TRCENA;
+ ARM_DWT_CTRL |= ARM_DWT_CTRL_CYCCNTENA;
+ ARM_DWT_CYCCNT = 0;
+
+ // Setup the pixel controller and load/scale the first byte
+ allpixels.preStepFirstByteDithering();
+ register Lines b0;
+
+ allpixels.preStepFirstByteDithering();
+ for(int i = 0; i < LANES; i++) {
+ b0.bytes[i] = allpixels.loadAndScale0(i);
+ }
+
+ cli();
+ uint32_t next_mark = ARM_DWT_CYCCNT + (T1+T2+T3);
+
+ while(allpixels.has(1)) {
+ allpixels.stepDithering();
+ #if 0 && (FASTLED_ALLOW_INTERRUPTS == 1)
+ cli();
+ // if interrupts took longer than 45µs, punt on the current frame
+ if(ARM_DWT_CYCCNT > next_mark) {
+ if((ARM_DWT_CYCCNT-next_mark) > ((WAIT_TIME-INTERRUPT_THRESHOLD)*CLKS_PER_US)) { sei(); return ARM_DWT_CYCCNT; }
+ }
+ #endif
+
+ // Write first byte, read next byte
+ writeBits<8+XTRA0,1>(next_mark, b0, allpixels);
+
+ // Write second byte, read 3rd byte
+ writeBits<8+XTRA0,2>(next_mark, b0, allpixels);
+ allpixels.advanceData();
+
+ // Write third byte
+ writeBits<8+XTRA0,0>(next_mark, b0, allpixels);
+
+ #if 0 && (FASTLED_ALLOW_INTERRUPTS == 1)
+ sei();
+ #endif
+ };
+ sei();
+
+ return ARM_DWT_CYCCNT;
+ }
+};
+
+FASTLED_NAMESPACE_END
+
+#endif
+
+#endif
diff --git a/Библиотеки/FastLED-master/platforms/arm/k20/fastled_arm_k20.h b/Библиотеки/FastLED-master/platforms/arm/k20/fastled_arm_k20.h
new file mode 100644
index 0000000..7220aef
--- /dev/null
+++ b/Библиотеки/FastLED-master/platforms/arm/k20/fastled_arm_k20.h
@@ -0,0 +1,14 @@
+#ifndef __INC_FASTLED_ARM_K20_H
+#define __INC_FASTLED_ARM_K20_H
+
+// Include the k20 headers
+#include "bitswap.h"
+#include "fastled_delay.h"
+#include "fastpin_arm_k20.h"
+#include "fastspi_arm_k20.h"
+#include "octows2811_controller.h"
+#include "smartmatrix_t3.h"
+#include "clockless_arm_k20.h"
+#include "clockless_block_arm_k20.h"
+
+#endif
diff --git a/Библиотеки/FastLED-master/platforms/arm/k20/fastpin_arm_k20.h b/Библиотеки/FastLED-master/platforms/arm/k20/fastpin_arm_k20.h
new file mode 100644
index 0000000..b26e560
--- /dev/null
+++ b/Библиотеки/FastLED-master/platforms/arm/k20/fastpin_arm_k20.h
@@ -0,0 +1,120 @@
+#ifndef __FASTPIN_ARM_K20_H
+#define __FASTPIN_ARM_K20_H
+
+FASTLED_NAMESPACE_BEGIN
+
+#if defined(FASTLED_FORCE_SOFTWARE_PINS)
+#warning "Software pin support forced, pin access will be sloightly slower."
+#define NO_HARDWARE_PIN_SUPPORT
+#undef HAS_HARDWARE_PIN_SUPPORT
+
+#else
+
+
+/// Template definition for teensy 3.0 style ARM pins, providing direct access to the various GPIO registers. Note that this
+/// uses the full port GPIO registers. In theory, in some way, bit-band register access -should- be faster, however I have found
+/// that something about the way gcc does register allocation results in the bit-band code being slower. It will need more fine tuning.
+/// The registers are data output, set output, clear output, toggle output, input, and direction
+template<uint8_t PIN, uint32_t _MASK, typename _PDOR, typename _PSOR, typename _PCOR, typename _PTOR, typename _PDIR, typename _PDDR> class _ARMPIN {
+public:
+ typedef volatile uint32_t * port_ptr_t;
+ typedef uint32_t port_t;
+
+ inline static void setOutput() { pinMode(PIN, OUTPUT); } // TODO: perform MUX config { _PDDR::r() |= _MASK; }
+ inline static void setInput() { pinMode(PIN, INPUT); } // TODO: preform MUX config { _PDDR::r() &= ~_MASK; }
+
+ inline static void hi() __attribute__ ((always_inline)) { _PSOR::r() = _MASK; }
+ inline static void lo() __attribute__ ((always_inline)) { _PCOR::r() = _MASK; }
+ inline static void set(register port_t val) __attribute__ ((always_inline)) { _PDOR::r() = val; }
+
+ inline static void strobe() __attribute__ ((always_inline)) { toggle(); toggle(); }
+
+ inline static void toggle() __attribute__ ((always_inline)) { _PTOR::r() = _MASK; }
+
+ inline static void hi(register port_ptr_t port) __attribute__ ((always_inline)) { hi(); }
+ inline static void lo(register port_ptr_t port) __attribute__ ((always_inline)) { lo(); }
+ inline static void fastset(register port_ptr_t port, register port_t val) __attribute__ ((always_inline)) { *port = val; }
+
+ inline static port_t hival() __attribute__ ((always_inline)) { return _PDOR::r() | _MASK; }
+ inline static port_t loval() __attribute__ ((always_inline)) { return _PDOR::r() & ~_MASK; }
+ inline static port_ptr_t port() __attribute__ ((always_inline)) { return &_PDOR::r(); }
+ inline static port_ptr_t sport() __attribute__ ((always_inline)) { return &_PSOR::r(); }
+ inline static port_ptr_t cport() __attribute__ ((always_inline)) { return &_PCOR::r(); }
+ inline static port_t mask() __attribute__ ((always_inline)) { return _MASK; }
+};
+
+/// Template definition for teensy 3.0 style ARM pins using bit banding, providing direct access to the various GPIO registers. GCC
+/// does a poor job of optimizing around these accesses so they are not being used just yet.
+template<uint8_t PIN, int _BIT, typename _PDOR, typename _PSOR, typename _PCOR, typename _PTOR, typename _PDIR, typename _PDDR> class _ARMPIN_BITBAND {
+public:
+ typedef volatile uint32_t * port_ptr_t;
+ typedef uint32_t port_t;
+
+ inline static void setOutput() { pinMode(PIN, OUTPUT); } // TODO: perform MUX config { _PDDR::r() |= _MASK; }
+ inline static void setInput() { pinMode(PIN, INPUT); } // TODO: preform MUX config { _PDDR::r() &= ~_MASK; }
+
+ inline static void hi() __attribute__ ((always_inline)) { *_PDOR::template rx<_BIT>() = 1; }
+ inline static void lo() __attribute__ ((always_inline)) { *_PDOR::template rx<_BIT>() = 0; }
+ inline static void set(register port_t val) __attribute__ ((always_inline)) { *_PDOR::template rx<_BIT>() = val; }
+
+ inline static void strobe() __attribute__ ((always_inline)) { toggle(); toggle(); }
+
+ inline static void toggle() __attribute__ ((always_inline)) { *_PTOR::template rx<_BIT>() = 1; }
+
+ inline static void hi(register port_ptr_t port) __attribute__ ((always_inline)) { hi(); }
+ inline static void lo(register port_ptr_t port) __attribute__ ((always_inline)) { lo(); }
+ inline static void fastset(register port_ptr_t port, register port_t val) __attribute__ ((always_inline)) { *_PDOR::template rx<_BIT>() = val; }
+
+ inline static port_t hival() __attribute__ ((always_inline)) { return 1; }
+ inline static port_t loval() __attribute__ ((always_inline)) { return 0; }
+ inline static port_ptr_t port() __attribute__ ((always_inline)) { return _PDOR::template rx<_BIT>(); }
+ inline static port_t mask() __attribute__ ((always_inline)) { return 1; }
+};
+
+// Macros for k20 pin access/definition
+#define GPIO_BITBAND_ADDR(reg, bit) (((uint32_t)&(reg) - 0x40000000) * 32 + (bit) * 4 + 0x42000000)
+#define GPIO_BITBAND_PTR(reg, bit) ((uint32_t *)GPIO_BITBAND_ADDR((reg), (bit)))
+
+#define _R(T) struct __gen_struct_ ## T
+#define _RD32(T) struct __gen_struct_ ## T { static __attribute__((always_inline)) inline reg32_t r() { return T; } \
+ template<int BIT> static __attribute__((always_inline)) inline ptr_reg32_t rx() { return GPIO_BITBAND_PTR(T, BIT); } };
+#define _IO32(L) _RD32(GPIO ## L ## _PDOR); _RD32(GPIO ## L ## _PSOR); _RD32(GPIO ## L ## _PCOR); _RD32(GPIO ## L ## _PTOR); _RD32(GPIO ## L ## _PDIR); _RD32(GPIO ## L ## _PDDR);
+
+#define _DEFPIN_ARM(PIN, BIT, L) template<> class FastPin<PIN> : public _ARMPIN<PIN, 1 << BIT, _R(GPIO ## L ## _PDOR), _R(GPIO ## L ## _PSOR), _R(GPIO ## L ## _PCOR), \
+ _R(GPIO ## L ## _PTOR), _R(GPIO ## L ## _PDIR), _R(GPIO ## L ## _PDDR)> {}; \
+ template<> class FastPinBB<PIN> : public _ARMPIN_BITBAND<PIN, BIT, _R(GPIO ## L ## _PDOR), _R(GPIO ## L ## _PSOR), _R(GPIO ## L ## _PCOR), \
+ _R(GPIO ## L ## _PTOR), _R(GPIO ## L ## _PDIR), _R(GPIO ## L ## _PDDR)> {};
+
+// Actual pin definitions
+#if defined(FASTLED_TEENSY3) && defined(CORE_TEENSY)
+
+_IO32(A); _IO32(B); _IO32(C); _IO32(D); _IO32(E);
+
+#define MAX_PIN 33
+_DEFPIN_ARM(0, 16, B); _DEFPIN_ARM(1, 17, B); _DEFPIN_ARM(2, 0, D); _DEFPIN_ARM(3, 12, A);
+_DEFPIN_ARM(4, 13, A); _DEFPIN_ARM(5, 7, D); _DEFPIN_ARM(6, 4, D); _DEFPIN_ARM(7, 2, D);
+_DEFPIN_ARM(8, 3, D); _DEFPIN_ARM(9, 3, C); _DEFPIN_ARM(10, 4, C); _DEFPIN_ARM(11, 6, C);
+_DEFPIN_ARM(12, 7, C); _DEFPIN_ARM(13, 5, C); _DEFPIN_ARM(14, 1, D); _DEFPIN_ARM(15, 0, C);
+_DEFPIN_ARM(16, 0, B); _DEFPIN_ARM(17, 1, B); _DEFPIN_ARM(18, 3, B); _DEFPIN_ARM(19, 2, B);
+_DEFPIN_ARM(20, 5, D); _DEFPIN_ARM(21, 6, D); _DEFPIN_ARM(22, 1, C); _DEFPIN_ARM(23, 2, C);
+_DEFPIN_ARM(24, 5, A); _DEFPIN_ARM(25, 19, B); _DEFPIN_ARM(26, 1, E); _DEFPIN_ARM(27, 9, C);
+_DEFPIN_ARM(28, 8, C); _DEFPIN_ARM(29, 10, C); _DEFPIN_ARM(30, 11, C); _DEFPIN_ARM(31, 0, E);
+_DEFPIN_ARM(32, 18, B); _DEFPIN_ARM(33, 4, A);
+
+#define SPI_DATA 11
+#define SPI_CLOCK 13
+#define SPI1 (*(SPI_t *)0x4002D000)
+
+#define SPI2_DATA 7
+#define SPI2_CLOCK 14
+
+#define FASTLED_TEENSY3
+#define ARM_HARDWARE_SPI
+#define HAS_HARDWARE_PIN_SUPPORT
+#endif
+
+#endif // FASTLED_FORCE_SOFTWARE_PINS
+
+FASTLED_NAMESPACE_END
+
+#endif // __INC_FASTPIN_ARM_K20
diff --git a/Библиотеки/FastLED-master/platforms/arm/k20/fastspi_arm_k20.h b/Библиотеки/FastLED-master/platforms/arm/k20/fastspi_arm_k20.h
new file mode 100644
index 0000000..70210a3
--- /dev/null
+++ b/Библиотеки/FastLED-master/platforms/arm/k20/fastspi_arm_k20.h
@@ -0,0 +1,466 @@
+#ifndef __INC_FASTSPI_ARM_H
+#define __INC_FASTSPI_ARM_H
+
+FASTLED_NAMESPACE_BEGIN
+
+#if defined(FASTLED_TEENSY3) && defined(CORE_TEENSY)
+
+// Version 1.20 renamed SPI_t to KINETISK_SPI_t
+#if TEENSYDUINO >= 120
+#define SPI_t KINETISK_SPI_t
+#endif
+
+#ifndef KINETISK_SPI0
+#define KINETISK_SPI0 SPI0
+#endif
+
+#ifndef SPI_PUSHR_CONT
+#define SPI_PUSHR_CONT SPIX.PUSHR_CONT
+#define SPI_PUSHR_CTAS(X) SPIX.PUSHR_CTAS(X)
+#define SPI_PUSHR_EOQ SPIX.PUSHR_EOQ
+#define SPI_PUSHR_CTCNT SPIX.PUSHR_CTCNT
+#define SPI_PUSHR_PCS(X) SPIX.PUSHR_PCS(X)
+#endif
+
+// Template function that, on compilation, expands to a constant representing the highest bit set in a byte. Right now,
+// if no bits are set (value is 0), it returns 0, which is also the value returned if the lowest bit is the only bit
+// set (the zero-th bit). Unclear if I will want this to change at some point.
+template<int VAL, int BIT> class BitWork {
+public:
+ static int highestBit() __attribute__((always_inline)) { return (VAL & 1 << BIT) ? BIT : BitWork<VAL, BIT-1>::highestBit(); }
+};
+template<int VAL> class BitWork<VAL, 0> {
+public:
+ static int highestBit() __attribute__((always_inline)) { return 0; }
+};
+
+#define MAX(A, B) (( (A) > (B) ) ? (A) : (B))
+
+#define USE_CONT 0
+// intra-frame backup data
+struct SPIState {
+ uint32_t _ctar0,_ctar1;
+ uint32_t pins[4];
+};
+
+// extern SPIState gState;
+
+
+// Templated function to translate a clock divider value into the prescalar, scalar, and clock doubling setting for the world.
+template <int VAL> void getScalars(uint32_t & preScalar, uint32_t & scalar, uint32_t & dbl) {
+ switch(VAL) {
+ // Handle the dbl clock cases
+ case 0: case 1:
+ case 2: preScalar = 0; scalar = 0; dbl = 1; break;
+ case 3: preScalar = 1; scalar = 0; dbl = 1; break;
+ case 5: preScalar = 2; scalar = 0; dbl = 1; break;
+ case 7: preScalar = 3; scalar = 0; dbl = 1; break;
+
+ // Handle the scalar value 6 cases (since it's not a power of two, it won't get caught
+ // below)
+ case 9: preScalar = 1; scalar = 2; dbl = 1; break;
+ case 18: case 19: preScalar = 1; scalar = 2; dbl = 0; break;
+
+ case 15: preScalar = 2; scalar = 2; dbl = 1; break;
+ case 30: case 31: preScalar = 2; scalar = 2; dbl = 0; break;
+
+ case 21: case 22: case 23: preScalar = 3; scalar = 2; dbl = 1; break;
+ case 42: case 43: case 44: case 45: case 46: case 47: preScalar = 3; scalar = 2; dbl = 0; break;
+ default: {
+ int p2 = BitWork<VAL/2, 15>::highestBit();
+ int p3 = BitWork<VAL/3, 15>::highestBit();
+ int p5 = BitWork<VAL/5, 15>::highestBit();
+ int p7 = BitWork<VAL/7, 15>::highestBit();
+
+ int w2 = 2 * (1 << p2);
+ int w3 = (VAL/3) > 0 ? 3 * (1 << p3) : 0;
+ int w5 = (VAL/5) > 0 ? 5 * (1 << p5) : 0;
+ int w7 = (VAL/7) > 0 ? 7 * (1 << p7) : 0;
+
+ int maxval = MAX(MAX(w2, w3), MAX(w5, w7));
+
+ if(w2 == maxval) { preScalar = 0; scalar = p2; }
+ else if(w3 == maxval) { preScalar = 1; scalar = p3; }
+ else if(w5 == maxval) { preScalar = 2; scalar = p5; }
+ else if(w7 == maxval) { preScalar = 3; scalar = p7; }
+
+ dbl = 0;
+ if(scalar == 0) { dbl = 1; }
+ else if(scalar < 3) { scalar--; }
+ }
+ }
+ return;
+}
+
+#define SPIX (*(SPI_t*)pSPIX)
+
+template <uint8_t _DATA_PIN, uint8_t _CLOCK_PIN, uint8_t _SPI_CLOCK_DIVIDER, uint32_t pSPIX>
+class ARMHardwareSPIOutput {
+ Selectable *m_pSelect;
+ SPIState gState;
+
+ // Borrowed from the teensy3 SPSR emulation code -- note, enabling pin 7 disables pin 11 (and vice versa),
+ // and likewise enabling pin 14 disables pin 13 (and vice versa)
+ inline void enable_pins(void) __attribute__((always_inline)) {
+ //serial_print("enable_pins\n");
+ switch(_DATA_PIN) {
+ case 7:
+ CORE_PIN7_CONFIG = PORT_PCR_DSE | PORT_PCR_MUX(2);
+ CORE_PIN11_CONFIG = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1);
+ break;
+ case 11:
+ CORE_PIN11_CONFIG = PORT_PCR_DSE | PORT_PCR_MUX(2);
+ CORE_PIN7_CONFIG = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1);
+ break;
+ }
+
+ switch(_CLOCK_PIN) {
+ case 13:
+ CORE_PIN13_CONFIG = PORT_PCR_DSE | PORT_PCR_MUX(2);
+ CORE_PIN14_CONFIG = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1);
+ break;
+ case 14:
+ CORE_PIN14_CONFIG = PORT_PCR_DSE | PORT_PCR_MUX(2);
+ CORE_PIN13_CONFIG = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1);
+ break;
+ }
+ }
+
+ // Borrowed from the teensy3 SPSR emulation code. We disable the pins that we're using, and restore the state on the pins that we aren't using
+ inline void disable_pins(void) __attribute__((always_inline)) {
+ switch(_DATA_PIN) {
+ case 7: CORE_PIN7_CONFIG = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1); CORE_PIN11_CONFIG = gState.pins[1]; break;
+ case 11: CORE_PIN11_CONFIG = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1); CORE_PIN7_CONFIG = gState.pins[0]; break;
+ }
+
+ switch(_CLOCK_PIN) {
+ case 13: CORE_PIN13_CONFIG = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1); CORE_PIN14_CONFIG = gState.pins[3]; break;
+ case 14: CORE_PIN14_CONFIG = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1); CORE_PIN13_CONFIG = gState.pins[2]; break;
+ }
+ }
+
+ static inline void update_ctars(uint32_t ctar0, uint32_t ctar1) __attribute__((always_inline)) {
+ if(SPIX.CTAR0 == ctar0 && SPIX.CTAR1 == ctar1) return;
+ uint32_t mcr = SPIX.MCR;
+ if(mcr & SPI_MCR_MDIS) {
+ SPIX.CTAR0 = ctar0;
+ SPIX.CTAR1 = ctar1;
+ } else {
+ SPIX.MCR = mcr | SPI_MCR_MDIS | SPI_MCR_HALT;
+ SPIX.CTAR0 = ctar0;
+ SPIX.CTAR1 = ctar1;
+ SPIX.MCR = mcr;
+ }
+ }
+
+ static inline void update_ctar0(uint32_t ctar) __attribute__((always_inline)) {
+ if (SPIX.CTAR0 == ctar) return;
+ uint32_t mcr = SPIX.MCR;
+ if (mcr & SPI_MCR_MDIS) {
+ SPIX.CTAR0 = ctar;
+ } else {
+ SPIX.MCR = mcr | SPI_MCR_MDIS | SPI_MCR_HALT;
+ SPIX.CTAR0 = ctar;
+
+ SPIX.MCR = mcr;
+ }
+ }
+
+ static inline void update_ctar1(uint32_t ctar) __attribute__((always_inline)) {
+ if (SPIX.CTAR1 == ctar) return;
+ uint32_t mcr = SPIX.MCR;
+ if (mcr & SPI_MCR_MDIS) {
+ SPIX.CTAR1 = ctar;
+ } else {
+ SPIX.MCR = mcr | SPI_MCR_MDIS | SPI_MCR_HALT;
+ SPIX.CTAR1 = ctar;
+ SPIX.MCR = mcr;
+
+ }
+ }
+
+ void setSPIRate() {
+ // Configure CTAR0, defaulting to 8 bits and CTAR1, defaulting to 16 bits
+ uint32_t _PBR = 0;
+ uint32_t _BR = 0;
+ uint32_t _CSSCK = 0;
+ uint32_t _DBR = 0;
+
+ // if(_SPI_CLOCK_DIVIDER >= 256) { _PBR = 0; _BR = _CSSCK = 7; _DBR = 0; } // osc/256
+ // else if(_SPI_CLOCK_DIVIDER >= 128) { _PBR = 0; _BR = _CSSCK = 6; _DBR = 0; } // osc/128
+ // else if(_SPI_CLOCK_DIVIDER >= 64) { _PBR = 0; _BR = _CSSCK = 5; _DBR = 0; } // osc/64
+ // else if(_SPI_CLOCK_DIVIDER >= 32) { _PBR = 0; _BR = _CSSCK = 4; _DBR = 0; } // osc/32
+ // else if(_SPI_CLOCK_DIVIDER >= 16) { _PBR = 0; _BR = _CSSCK = 3; _DBR = 0; } // osc/16
+ // else if(_SPI_CLOCK_DIVIDER >= 8) { _PBR = 0; _BR = _CSSCK = 1; _DBR = 0; } // osc/8
+ // else if(_SPI_CLOCK_DIVIDER >= 7) { _PBR = 3; _BR = _CSSCK = 0; _DBR = 1; } // osc/7
+ // else if(_SPI_CLOCK_DIVIDER >= 5) { _PBR = 2; _BR = _CSSCK = 0; _DBR = 1; } // osc/5
+ // else if(_SPI_CLOCK_DIVIDER >= 4) { _PBR = 0; _BR = _CSSCK = 0; _DBR = 0; } // osc/4
+ // else if(_SPI_CLOCK_DIVIDER >= 3) { _PBR = 1; _BR = _CSSCK = 0; _DBR = 1; } // osc/3
+ // else { _PBR = 0; _BR = _CSSCK = 0; _DBR = 1; } // osc/2
+
+ getScalars<_SPI_CLOCK_DIVIDER>(_PBR, _BR, _DBR);
+ _CSSCK = _BR;
+
+ uint32_t ctar0 = SPI_CTAR_FMSZ(7) | SPI_CTAR_PBR(_PBR) | SPI_CTAR_BR(_BR) | SPI_CTAR_CSSCK(_CSSCK);
+ uint32_t ctar1 = SPI_CTAR_FMSZ(15) | SPI_CTAR_PBR(_PBR) | SPI_CTAR_BR(_BR) | SPI_CTAR_CSSCK(_CSSCK);
+
+ #if USE_CONT == 1
+ ctar0 |= SPI_CTAR_CPHA | SPI_CTAR_CPOL;
+ ctar1 |= SPI_CTAR_CPHA | SPI_CTAR_CPOL;
+ #endif
+
+ if(_DBR) {
+ ctar0 |= SPI_CTAR_DBR;
+ ctar1 |= SPI_CTAR_DBR;
+ }
+
+ update_ctars(ctar0,ctar1);
+ }
+
+ void inline save_spi_state() __attribute__ ((always_inline)) {
+ // save ctar data
+ gState._ctar0 = SPIX.CTAR0;
+ gState._ctar1 = SPIX.CTAR1;
+
+ // save data for the not-us pins
+ gState.pins[0] = CORE_PIN7_CONFIG;
+ gState.pins[1] = CORE_PIN11_CONFIG;
+ gState.pins[2] = CORE_PIN13_CONFIG;
+ gState.pins[3] = CORE_PIN14_CONFIG;
+ }
+
+ void inline restore_spi_state() __attribute__ ((always_inline)) {
+ // restore ctar data
+ update_ctars(gState._ctar0,gState._ctar1);
+
+ // restore data for the not-us pins (not necessary because disable_pins will do this)
+ // CORE_PIN7_CONFIG = gState.pins[0];
+ // CORE_PIN11_CONFIG = gState.pins[1];
+ // CORE_PIN13_CONFIG = gState.pins[2];
+ // CORE_PIN14_CONFIG = gState.pins[3];
+ }
+
+
+public:
+ ARMHardwareSPIOutput() { m_pSelect = NULL; }
+ ARMHardwareSPIOutput(Selectable *pSelect) { m_pSelect = pSelect; }
+ void setSelect(Selectable *pSelect) { m_pSelect = pSelect; }
+
+
+ void init() {
+ // set the pins to output
+ FastPin<_DATA_PIN>::setOutput();
+ FastPin<_CLOCK_PIN>::setOutput();
+
+ // Enable SPI0 clock
+ uint32_t sim6 = SIM_SCGC6;
+ if((SPI_t*)pSPIX == &KINETISK_SPI0) {
+ if (!(sim6 & SIM_SCGC6_SPI0)) {
+ //serial_print("init1\n");
+ SIM_SCGC6 = sim6 | SIM_SCGC6_SPI0;
+ SPIX.CTAR0 = SPI_CTAR_FMSZ(7) | SPI_CTAR_PBR(1) | SPI_CTAR_BR(1);
+ }
+ } else if((SPI_t*)pSPIX == &SPI1) {
+ if (!(sim6 & SIM_SCGC6_SPI1)) {
+ //serial_print("init1\n");
+ SIM_SCGC6 = sim6 | SIM_SCGC6_SPI1;
+ SPIX.CTAR0 = SPI_CTAR_FMSZ(7) | SPI_CTAR_PBR(1) | SPI_CTAR_BR(1);
+ }
+ }
+
+ // Configure SPI as the master and enable
+ SPIX.MCR |= SPI_MCR_MSTR; // | SPI_MCR_CONT_SCKE);
+ SPIX.MCR &= ~(SPI_MCR_MDIS | SPI_MCR_HALT);
+
+ // pin/spi configuration happens on select
+ }
+
+ static void waitFully() __attribute__((always_inline)) {
+ // Wait for the last byte to get shifted into the register
+ bool empty = false;
+
+ do {
+ cli();
+ if ((SPIX.SR & 0xF000) > 0) {
+ // reset the TCF flag
+ SPIX.SR |= SPI_SR_TCF;
+ } else {
+ empty = true;
+ }
+ sei();
+ } while (!empty);
+
+ // wait for the TCF flag to get set
+ while (!(SPIX.SR & SPI_SR_TCF));
+ SPIX.SR |= (SPI_SR_TCF | SPI_SR_EOQF);
+ }
+
+ static bool needwait() __attribute__((always_inline)) { return (SPIX.SR & 0x4000); }
+ static void wait() __attribute__((always_inline)) { while( (SPIX.SR & 0x4000) ); }
+ static void wait1() __attribute__((always_inline)) { while( (SPIX.SR & 0xF000) >= 0x2000); }
+
+ enum ECont { CONT, NOCONT };
+ enum EWait { PRE, POST, NONE };
+ enum ELast { NOTLAST, LAST };
+
+ #if USE_CONT == 1
+ #define CM CONT
+ #else
+ #define CM NOCONT
+ #endif
+ #define WM PRE
+
+ template<ECont CONT_STATE, EWait WAIT_STATE, ELast LAST_STATE> class Write {
+ public:
+ static void writeWord(uint16_t w) __attribute__((always_inline)) {
+ if(WAIT_STATE == PRE) { wait(); }
+ cli();
+ SPIX.PUSHR = ((LAST_STATE == LAST) ? SPI_PUSHR_EOQ : 0) |
+ ((CONT_STATE == CONT) ? SPI_PUSHR_CONT : 0) |
+ SPI_PUSHR_CTAS(1) | (w & 0xFFFF);
+ SPIX.SR |= SPI_SR_TCF;
+ sei();
+ if(WAIT_STATE == POST) { wait(); }
+ }
+
+ static void writeByte(uint8_t b) __attribute__((always_inline)) {
+ if(WAIT_STATE == PRE) { wait(); }
+ cli();
+ SPIX.PUSHR = ((LAST_STATE == LAST) ? SPI_PUSHR_EOQ : 0) |
+ ((CONT_STATE == CONT) ? SPI_PUSHR_CONT : 0) |
+ SPI_PUSHR_CTAS(0) | (b & 0xFF);
+ SPIX.SR |= SPI_SR_TCF;
+ sei();
+ if(WAIT_STATE == POST) { wait(); }
+ }
+ };
+
+ static void writeWord(uint16_t w) __attribute__((always_inline)) { wait(); cli(); SPIX.PUSHR = SPI_PUSHR_CTAS(1) | (w & 0xFFFF); SPIX.SR |= SPI_SR_TCF; sei(); }
+ static void writeWordNoWait(uint16_t w) __attribute__((always_inline)) { cli(); SPIX.PUSHR = SPI_PUSHR_CTAS(1) | (w & 0xFFFF); SPIX.SR |= SPI_SR_TCF; sei(); }
+
+ static void writeByte(uint8_t b) __attribute__((always_inline)) { wait(); cli(); SPIX.PUSHR = SPI_PUSHR_CTAS(0) | (b & 0xFF); SPIX.SR |= SPI_SR_TCF; sei(); }
+ static void writeBytePostWait(uint8_t b) __attribute__((always_inline)) { cli(); SPIX.PUSHR = SPI_PUSHR_CTAS(0) | (b & 0xFF);SPIX.SR |= SPI_SR_TCF; sei(); wait(); }
+ static void writeByteNoWait(uint8_t b) __attribute__((always_inline)) { cli(); SPIX.PUSHR = SPI_PUSHR_CTAS(0) | (b & 0xFF); SPIX.SR |= SPI_SR_TCF; sei(); }
+
+ static void writeWordCont(uint16_t w) __attribute__((always_inline)) { wait(); cli(); SPIX.PUSHR = SPI_PUSHR_CONT | SPI_PUSHR_CTAS(1) | (w & 0xFFFF); SPIX.SR |= SPI_SR_TCF; sei(); }
+ static void writeWordContNoWait(uint16_t w) __attribute__((always_inline)) { cli(); SPIX.PUSHR = SPI_PUSHR_CONT | SPI_PUSHR_CTAS(1) | (w & 0xFFFF); SPIX.SR |= SPI_SR_TCF; sei();}
+
+ static void writeByteCont(uint8_t b) __attribute__((always_inline)) { wait(); cli(); SPIX.PUSHR = SPI_PUSHR_CONT | SPI_PUSHR_CTAS(0) | (b & 0xFF); SPIX.SR |= SPI_SR_TCF; sei(); }
+ static void writeByteContPostWait(uint8_t b) __attribute__((always_inline)) { cli(); SPIX.PUSHR = SPI_PUSHR_CONT | SPI_PUSHR_CTAS(0) | (b & 0xFF); SPIX.SR |= SPI_SR_TCF; sei(); wait(); }
+ static void writeByteContNoWait(uint8_t b) __attribute__((always_inline)) { cli(); SPIX.PUSHR = SPI_PUSHR_CONT | SPI_PUSHR_CTAS(0) | (b & 0xFF); SPIX.SR |= SPI_SR_TCF; sei(); }
+
+ // not the most efficient mechanism in the world - but should be enough for sm16716 and friends
+ template <uint8_t BIT> inline static void writeBit(uint8_t b) {
+ uint32_t ctar1_save = SPIX.CTAR1;
+
+ // Clear out the FMSZ bits, reset them for 1 bit transferd for the start bit
+ uint32_t ctar1 = (ctar1_save & (~SPI_CTAR_FMSZ(15))) | SPI_CTAR_FMSZ(0);
+ update_ctar1(ctar1);
+
+ writeWord( (b & (1 << BIT)) != 0);
+
+ update_ctar1(ctar1_save);
+ }
+
+ void inline select() __attribute__((always_inline)) {
+ save_spi_state();
+ if(m_pSelect != NULL) { m_pSelect->select(); }
+ setSPIRate();
+ enable_pins();
+ }
+
+ void inline release() __attribute__((always_inline)) {
+ disable_pins();
+ if(m_pSelect != NULL) { m_pSelect->release(); }
+ restore_spi_state();
+ }
+
+ static void writeBytesValueRaw(uint8_t value, int len) {
+ while(len--) { Write<CM, WM, NOTLAST>::writeByte(value); }
+ }
+
+ void writeBytesValue(uint8_t value, int len) {
+ select();
+ while(len--) {
+ writeByte(value);
+ }
+ waitFully();
+ release();
+ }
+
+ // Write a block of n uint8_ts out
+ template <class D> void writeBytes(register uint8_t *data, int len) {
+ uint8_t *end = data + len;
+ select();
+ // could be optimized to write 16bit words out instead of 8bit bytes
+ while(data != end) {
+ writeByte(D::adjust(*data++));
+ }
+ D::postBlock(len);
+ waitFully();
+ release();
+ }
+
+ void writeBytes(register uint8_t *data, int len) { writeBytes<DATA_NOP>(data, len); }
+
+ // write a block of uint8_ts out in groups of three. len is the total number of uint8_ts to write out. The template
+ // parameters indicate how many uint8_ts to skip at the beginning and/or end of each grouping
+ template <uint8_t FLAGS, class D, EOrder RGB_ORDER> void writePixels(PixelController<RGB_ORDER> pixels) {
+ select();
+ int len = pixels.mLen;
+
+ // Setup the pixel controller
+ if((FLAGS & FLAG_START_BIT) == 0) {
+ //If no start bit stupiditiy, write out as many 16-bit blocks as we can
+ while(pixels.has(2)) {
+ // Load and write out the first two bytes
+ if(WM == NONE) { wait1(); }
+ Write<CM, WM, NOTLAST>::writeWord(D::adjust(pixels.loadAndScale0()) << 8 | D::adjust(pixels.loadAndScale1()));
+
+ // Load and write out the next two bytes (step dithering, advance data in between since we
+ // cross pixels here)
+ Write<CM, WM, NOTLAST>::writeWord(D::adjust(pixels.loadAndScale2()) << 8 | D::adjust(pixels.stepAdvanceAndLoadAndScale0()));
+
+ // Load and write out the next two bytes
+ Write<CM, WM, NOTLAST>::writeWord(D::adjust(pixels.loadAndScale1()) << 8 | D::adjust(pixels.loadAndScale2()));
+ pixels.stepDithering();
+ pixels.advanceData();
+ }
+
+ if(pixels.has(1)) {
+ if(WM == NONE) { wait1(); }
+ // write out the rest as alternating 16/8-bit blocks (likely to be just one)
+ Write<CM, WM, NOTLAST>::writeWord(D::adjust(pixels.loadAndScale0()) << 8 | D::adjust(pixels.loadAndScale1()));
+ Write<CM, WM, NOTLAST>::writeByte(D::adjust(pixels.loadAndScale2()));
+ }
+
+ D::postBlock(len);
+ waitFully();
+ } else if(FLAGS & FLAG_START_BIT) {
+ uint32_t ctar1_save = SPIX.CTAR1;
+
+ // Clear out the FMSZ bits, reset them for 9 bits transferd for the start bit
+ uint32_t ctar1 = (ctar1_save & (~SPI_CTAR_FMSZ(15))) | SPI_CTAR_FMSZ(8);
+ update_ctar1(ctar1);
+
+ while(pixels.has(1)) {
+ writeWord( 0x100 | D::adjust(pixels.loadAndScale0()));
+ writeByte(D::adjust(pixels.loadAndScale1()));
+ writeByte(D::adjust(pixels.loadAndScale2()));
+ pixels.advanceData();
+ pixels.stepDithering();
+ }
+ D::postBlock(len);
+ waitFully();
+
+ // restore ctar1
+ update_ctar1(ctar1_save);
+ }
+ release();
+ }
+};
+#endif
+
+FASTLED_NAMESPACE_END
+
+#endif
diff --git a/Библиотеки/FastLED-master/platforms/arm/k20/led_sysdefs_arm_k20.h b/Библиотеки/FastLED-master/platforms/arm/k20/led_sysdefs_arm_k20.h
new file mode 100644
index 0000000..0dcb626
--- /dev/null
+++ b/Библиотеки/FastLED-master/platforms/arm/k20/led_sysdefs_arm_k20.h
@@ -0,0 +1,46 @@
+#ifndef __INC_LED_SYSDEFS_ARM_K20_H
+#define __INC_LED_SYSDEFS_ARM_K20_H
+
+#define FASTLED_TEENSY3
+#define FASTLED_ARM
+
+#ifndef INTERRUPT_THRESHOLD
+#define INTERRUPT_THRESHOLD 1
+#endif
+
+// Default to allowing interrupts
+#ifndef FASTLED_ALLOW_INTERRUPTS
+#define FASTLED_ALLOW_INTERRUPTS 1
+#endif
+
+#if FASTLED_ALLOW_INTERRUPTS == 1
+#define FASTLED_ACCURATE_CLOCK
+#endif
+
+#if (F_CPU == 96000000)
+#define CLK_DBL 1
+#endif
+
+// Get some system include files
+#include <avr/io.h>
+#include <avr/interrupt.h> // for cli/se definitions
+
+// Define the register types
+#if defined(ARDUINO) // && ARDUINO < 150
+typedef volatile uint8_t RoReg; /**< Read only 8-bit register (volatile const unsigned int) */
+typedef volatile uint8_t RwReg; /**< Read-Write 8-bit register (volatile unsigned int) */
+#endif
+
+extern volatile uint32_t systick_millis_count;
+# define MS_COUNTER systick_millis_count
+
+
+// Default to using PROGMEM, since TEENSY3 provides it
+// even though all it does is ignore it. Just being
+// conservative here in case TEENSY3 changes.
+#ifndef FASTLED_USE_PROGMEM
+#define FASTLED_USE_PROGMEM 1
+#endif
+
+
+#endif
diff --git a/Библиотеки/FastLED-master/platforms/arm/k20/octows2811_controller.h b/Библиотеки/FastLED-master/platforms/arm/k20/octows2811_controller.h
new file mode 100644
index 0000000..63f6d8f
--- /dev/null
+++ b/Библиотеки/FastLED-master/platforms/arm/k20/octows2811_controller.h
@@ -0,0 +1,66 @@
+#ifndef __INC_OCTOWS2811_CONTROLLER_H
+#define __INC_OCTOWS2811_CONTROLLER_H
+
+#ifdef USE_OCTOWS2811
+
+// #include "OctoWS2811.h"
+
+FASTLED_NAMESPACE_BEGIN
+
+template<EOrder RGB_ORDER = GRB, uint8_t CHIP = WS2811_800kHz>
+class COctoWS2811Controller : public CPixelLEDController<RGB_ORDER, 8, 0xFF> {
+ OctoWS2811 *pocto;
+ uint8_t *drawbuffer,*framebuffer;
+
+ void _init(int nLeds) {
+ if(pocto == NULL) {
+ drawbuffer = (uint8_t*)malloc(nLeds * 8 * 3);
+ framebuffer = (uint8_t*)malloc(nLeds * 8 * 3);
+
+ // byte ordering is handled in show by the pixel controller
+ int config = WS2811_RGB;
+ config |= CHIP;
+
+ pocto = new OctoWS2811(nLeds, framebuffer, drawbuffer, config);
+
+ pocto->begin();
+ }
+ }
+public:
+ COctoWS2811Controller() { pocto = NULL; }
+
+
+ virtual void init() { /* do nothing yet */ }
+
+ typedef union {
+ uint8_t bytes[8];
+ uint32_t raw[2];
+ } Lines;
+
+ virtual void showPixels(PixelController<RGB_ORDER, 8, 0xFF> & pixels) {
+ _init(pixels.size());
+
+ uint8_t *pData = drawbuffer;
+ while(pixels.has(1)) {
+ Lines b;
+
+ for(int i = 0; i < 8; i++) { b.bytes[i] = pixels.loadAndScale0(i); }
+ transpose8x1_MSB(b.bytes,pData); pData += 8;
+ for(int i = 0; i < 8; i++) { b.bytes[i] = pixels.loadAndScale1(i); }
+ transpose8x1_MSB(b.bytes,pData); pData += 8;
+ for(int i = 0; i < 8; i++) { b.bytes[i] = pixels.loadAndScale2(i); }
+ transpose8x1_MSB(b.bytes,pData); pData += 8;
+ pixels.stepDithering();
+ pixels.advanceData();
+ }
+
+ pocto->show();
+ }
+
+};
+
+FASTLED_NAMESPACE_END
+
+#endif
+
+#endif
diff --git a/Библиотеки/FastLED-master/platforms/arm/k20/smartmatrix_t3.h b/Библиотеки/FastLED-master/platforms/arm/k20/smartmatrix_t3.h
new file mode 100644
index 0000000..14c3734
--- /dev/null
+++ b/Библиотеки/FastLED-master/platforms/arm/k20/smartmatrix_t3.h
@@ -0,0 +1,55 @@
+#ifndef __INC_SMARTMATRIX_T3_H
+#define __INC_SMARTMATRIX_T3_H
+
+#ifdef SmartMatrix_h
+#include<SmartMatrix.h>
+
+FASTLED_NAMESPACE_BEGIN
+
+extern SmartMatrix *pSmartMatrix;
+
+// note - dmx simple must be included before FastSPI for this code to be enabled
+class CSmartMatrixController : public CPixelLEDController<RGB_ORDER> {
+ SmartMatrix matrix;
+
+public:
+ // initialize the LED controller
+ virtual void init() {
+ // Initialize 32x32 LED Matrix
+ matrix.begin();
+ matrix.setBrightness(255);
+ matrix.setColorCorrection(ccNone);
+
+ // Clear screen
+ clearLeds(0);
+ matrix.swapBuffers();
+ pSmartMatrix = &matrix;
+ }
+
+ virtual void showPixels(PixelController<RGB_ORDER> & pixels) {
+ if(SMART_MATRIX_CAN_TRIPLE_BUFFER) {
+ rgb24 *md = matrix.getRealBackBuffer();
+ } else {
+ rgb24 *md = matrix.backBuffer();
+ }
+ while(pixels.has(1)) {
+ md->red = pixels.loadAndScale0();
+ md->green = pixels.loadAndScale1();
+ md->blue = pixels.loadAndScale2();
+ md++;
+ pixels.advanceData();
+ pixels.stepDithering();
+ }
+ matrix.swapBuffers();
+ if(SMART_MATRIX_CAN_TRIPLE_BUFFER && pixels.advanceBy() > 0) {
+ matrix.setBackBuffer(pixels.mData);
+ }
+ }
+
+};
+
+FASTLED_NAMESPACE_END
+
+#endif
+
+#endif
diff --git a/Библиотеки/FastLED-master/platforms/arm/k66/clockless_arm_k66.h b/Библиотеки/FastLED-master/platforms/arm/k66/clockless_arm_k66.h
new file mode 100644
index 0000000..6102105
--- /dev/null
+++ b/Библиотеки/FastLED-master/platforms/arm/k66/clockless_arm_k66.h
@@ -0,0 +1,124 @@
+#ifndef __INC_CLOCKLESS_ARM_K66_H
+#define __INC_CLOCKLESS_ARM_K66_H
+
+FASTLED_NAMESPACE_BEGIN
+
+// Definition for a single channel clockless controller for the k66 family of chips, like that used in the teensy 3.6
+// See clockless.h for detailed info on how the template parameters are used.
+#if defined(FASTLED_TEENSY3)
+
+#define FASTLED_HAS_CLOCKLESS 1
+
+template <int DATA_PIN, int T1, int T2, int T3, EOrder RGB_ORDER = RGB, int XTRA0 = 0, bool FLIP = false, int WAIT_TIME = 50>
+class ClocklessController : public CPixelLEDController<RGB_ORDER> {
+ typedef typename FastPin<DATA_PIN>::port_ptr_t data_ptr_t;
+ typedef typename FastPin<DATA_PIN>::port_t data_t;
+
+ data_t mPinMask;
+ data_ptr_t mPort;
+ CMinWait<WAIT_TIME> mWait;
+public:
+ virtual void init() {
+ FastPin<DATA_PIN>::setOutput();
+ mPinMask = FastPin<DATA_PIN>::mask();
+ mPort = FastPin<DATA_PIN>::port();
+ }
+
+ virtual uint16_t getMaxRefreshRate() const { return 400; }
+
+protected:
+
+ virtual void showPixels(PixelController<RGB_ORDER> & pixels) {
+ mWait.wait();
+ if(!showRGBInternal(pixels)) {
+ sei(); delayMicroseconds(WAIT_TIME); cli();
+ showRGBInternal(pixels);
+ }
+ mWait.mark();
+ }
+
+ template<int BITS> __attribute__ ((always_inline)) inline static void writeBits(register uint32_t & next_mark, register data_ptr_t port, register data_t hi, register data_t lo, register uint8_t & b) {
+ for(register uint32_t i = BITS-1; i > 0; i--) {
+ while(ARM_DWT_CYCCNT < next_mark);
+ next_mark = ARM_DWT_CYCCNT + (T1+T2+T3);
+ FastPin<DATA_PIN>::fastset(port, hi);
+ if(b&0x80) {
+ while((next_mark - ARM_DWT_CYCCNT) > (T3+(2*(F_CPU/24000000))));
+ FastPin<DATA_PIN>::fastset(port, lo);
+ } else {
+ while((next_mark - ARM_DWT_CYCCNT) > (T2+T3+(2*(F_CPU/24000000))));
+ FastPin<DATA_PIN>::fastset(port, lo);
+ }
+ b <<= 1;
+ }
+
+ while(ARM_DWT_CYCCNT < next_mark);
+ next_mark = ARM_DWT_CYCCNT + (T1+T2+T3);
+ FastPin<DATA_PIN>::fastset(port, hi);
+
+ if(b&0x80) {
+ while((next_mark - ARM_DWT_CYCCNT) > (T3+(2*(F_CPU/24000000))));
+ FastPin<DATA_PIN>::fastset(port, lo);
+ } else {
+ while((next_mark - ARM_DWT_CYCCNT) > (T2+T3+(2*(F_CPU/24000000))));
+ FastPin<DATA_PIN>::fastset(port, lo);
+ }
+ }
+
+ // This method is made static to force making register Y available to use for data on AVR - if the method is non-static, then
+ // gcc will use register Y for the this pointer.
+ static uint32_t showRGBInternal(PixelController<RGB_ORDER> pixels) {
+ // Get access to the clock
+ ARM_DEMCR |= ARM_DEMCR_TRCENA;
+ ARM_DWT_CTRL |= ARM_DWT_CTRL_CYCCNTENA;
+ ARM_DWT_CYCCNT = 0;
+
+ register data_ptr_t port = FastPin<DATA_PIN>::port();
+ register data_t hi = *port | FastPin<DATA_PIN>::mask();;
+ register data_t lo = *port & ~FastPin<DATA_PIN>::mask();;
+ *port = lo;
+
+ // Setup the pixel controller and load/scale the first byte
+ pixels.preStepFirstByteDithering();
+ register uint8_t b = pixels.loadAndScale0();
+
+ cli();
+ uint32_t next_mark = ARM_DWT_CYCCNT + (T1+T2+T3);
+
+ while(pixels.has(1)) {
+ pixels.stepDithering();
+ #if (FASTLED_ALLOW_INTERRUPTS == 1)
+ cli();
+ // if interrupts took longer than 45µs, punt on the current frame
+ if(ARM_DWT_CYCCNT > next_mark) {
+ if((ARM_DWT_CYCCNT-next_mark) > ((WAIT_TIME-INTERRUPT_THRESHOLD)*CLKS_PER_US)) { sei(); return 0; }
+ }
+
+ hi = *port | FastPin<DATA_PIN>::mask();
+ lo = *port & ~FastPin<DATA_PIN>::mask();
+ #endif
+ // Write first byte, read next byte
+ writeBits<8+XTRA0>(next_mark, port, hi, lo, b);
+ b = pixels.loadAndScale1();
+
+ // Write second byte, read 3rd byte
+ writeBits<8+XTRA0>(next_mark, port, hi, lo, b);
+ b = pixels.loadAndScale2();
+
+ // Write third byte, read 1st byte of next pixel
+ writeBits<8+XTRA0>(next_mark, port, hi, lo, b);
+ b = pixels.advanceAndLoadAndScale0();
+ #if (FASTLED_ALLOW_INTERRUPTS == 1)
+ sei();
+ #endif
+ };
+
+ sei();
+ return ARM_DWT_CYCCNT;
+ }
+};
+#endif
+
+FASTLED_NAMESPACE_END
+
+#endif
diff --git a/Библиотеки/FastLED-master/platforms/arm/k66/clockless_block_arm_k66.h b/Библиотеки/FastLED-master/platforms/arm/k66/clockless_block_arm_k66.h
new file mode 100644
index 0000000..3b3f978
--- /dev/null
+++ b/Библиотеки/FastLED-master/platforms/arm/k66/clockless_block_arm_k66.h
@@ -0,0 +1,344 @@
+#ifndef __INC_BLOCK_CLOCKLESS_ARM_K66_H
+#define __INC_BLOCK_CLOCKLESS_ARM_K66_H
+
+// Definition for a single channel clockless controller for the k66 family of chips, like that used in the teensy 3.6
+// See clockless.h for detailed info on how the template parameters are used.
+#if defined(FASTLED_TEENSY3)
+#define FASTLED_HAS_BLOCKLESS 1
+
+#define PORTB_FIRST_PIN 0
+#define PORTC_FIRST_PIN 15
+#define PORTD_FIRST_PIN 2
+#define HAS_PORTDC 1
+
+#define LANE_MASK (((1<<LANES)-1) & ((FIRST_PIN==2) ? 0xFF : 0xFFF))
+#define PORT_SHIFT(P) ((P) << ((FIRST_PIN==0) ? 16 : 0))
+#define PORT_MASK PORT_SHIFT(LANE_MASK)
+
+#define MIN(X,Y) (((X)<(Y)) ? (X):(Y))
+#define USED_LANES ((FIRST_PIN!=15) ? MIN(LANES,8) : MIN(LANES,12))
+
+#include "kinetis.h"
+
+FASTLED_NAMESPACE_BEGIN
+
+template <uint8_t LANES, int FIRST_PIN, int T1, int T2, int T3, EOrder RGB_ORDER = GRB, int XTRA0 = 0, bool FLIP = false, int WAIT_TIME = 40>
+class InlineBlockClocklessController : public CPixelLEDController<RGB_ORDER, LANES, LANE_MASK> {
+ typedef typename FastPin<FIRST_PIN>::port_ptr_t data_ptr_t;
+ typedef typename FastPin<FIRST_PIN>::port_t data_t;
+
+ data_t mPinMask;
+ data_ptr_t mPort;
+ CMinWait<WAIT_TIME> mWait;
+public:
+ virtual int size() { return CLEDController::size() * LANES; }
+
+ virtual void showPixels(PixelController<RGB_ORDER, LANES, LANE_MASK> & pixels) {
+ mWait.wait();
+ uint32_t clocks = showRGBInternal(pixels);
+ #if FASTLED_ALLOW_INTTERUPTS == 0
+ // Adjust the timer
+ long microsTaken = CLKS_TO_MICROS(clocks);
+ MS_COUNTER += (1 + (microsTaken / 1000));
+ #endif
+
+ mWait.mark();
+ }
+
+ virtual void init() {
+ if(FIRST_PIN == PORTC_FIRST_PIN) { // PORTC
+ switch(USED_LANES) {
+ case 12: FastPin<30>::setOutput();
+ case 11: FastPin<29>::setOutput();
+ case 10: FastPin<27>::setOutput();
+ case 9: FastPin<28>::setOutput();
+ case 8: FastPin<12>::setOutput();
+ case 7: FastPin<11>::setOutput();
+ case 6: FastPin<13>::setOutput();
+ case 5: FastPin<10>::setOutput();
+ case 4: FastPin<9>::setOutput();
+ case 3: FastPin<23>::setOutput();
+ case 2: FastPin<22>::setOutput();
+ case 1: FastPin<15>::setOutput();
+ }
+ } else if(FIRST_PIN == PORTD_FIRST_PIN) { // PORTD
+ switch(USED_LANES) {
+ case 8: FastPin<5>::setOutput();
+ case 7: FastPin<21>::setOutput();
+ case 6: FastPin<20>::setOutput();
+ case 5: FastPin<6>::setOutput();
+ case 4: FastPin<8>::setOutput();
+ case 3: FastPin<7>::setOutput();
+ case 2: FastPin<14>::setOutput();
+ case 1: FastPin<2>::setOutput();
+ }
+ } else if (FIRST_PIN == PORTB_FIRST_PIN) { // PORTB
+ switch (USED_LANES) {
+ case 8: FastPin<45>::setOutput();
+ case 7: FastPin<44>::setOutput();
+ case 6: FastPin<46>::setOutput();
+ case 5: FastPin<43>::setOutput();
+ case 4: FastPin<30>::setOutput();
+ case 3: FastPin<29>::setOutput();
+ case 2: FastPin<1>::setOutput();
+ case 1: FastPin<0>::setOutput();
+ }
+ }
+ mPinMask = FastPin<FIRST_PIN>::mask();
+ mPort = FastPin<FIRST_PIN>::port();
+ }
+
+ virtual uint16_t getMaxRefreshRate() const { return 400; }
+
+ typedef union {
+ uint8_t bytes[12];
+ uint16_t shorts[6];
+ uint32_t raw[3];
+ } Lines;
+
+ template<int BITS,int PX> __attribute__ ((always_inline)) inline static void writeBits(register uint32_t & next_mark, register Lines & b, PixelController<RGB_ORDER, LANES, LANE_MASK> &pixels) { // , register uint32_t & b2) {
+ register Lines b2;
+ if(USED_LANES>8) {
+ transpose8<1,2>(b.bytes,b2.bytes);
+ transpose8<1,2>(b.bytes+8,b2.bytes+1);
+ } else {
+ transpose8x1(b.bytes,b2.bytes);
+ }
+ register uint8_t d = pixels.template getd<PX>(pixels);
+ register uint8_t scale = pixels.template getscale<PX>(pixels);
+
+ for(register uint32_t i = 0; i < (USED_LANES/2); i++) {
+ while(ARM_DWT_CYCCNT < next_mark);
+ next_mark = ARM_DWT_CYCCNT + (T1+T2+T3)-3;
+ *FastPin<FIRST_PIN>::sport() = PORT_MASK;
+
+ while((next_mark - ARM_DWT_CYCCNT) > (T2+T3+(2*(F_CPU/24000000))));
+ if(USED_LANES>8) {
+ *FastPin<FIRST_PIN>::cport() = ((~b2.shorts[i]) & PORT_MASK);
+ } else {
+ *FastPin<FIRST_PIN>::cport() = (PORT_SHIFT(~b2.bytes[7-i]) & PORT_MASK);
+ }
+
+ while((next_mark - ARM_DWT_CYCCNT) > (T3));
+ *FastPin<FIRST_PIN>::cport() = PORT_MASK;
+
+ b.bytes[i] = pixels.template loadAndScale<PX>(pixels,i,d,scale);
+ b.bytes[i+(USED_LANES/2)] = pixels.template loadAndScale<PX>(pixels,i+(USED_LANES/2),d,scale);
+ }
+
+ // if folks use an odd numnber of lanes, get the last byte's value here
+ if(USED_LANES & 0x01) {
+ b.bytes[USED_LANES-1] = pixels.template loadAndScale<PX>(pixels,USED_LANES-1,d,scale);
+ }
+
+ for(register uint32_t i = USED_LANES/2; i < 8; i++) {
+ while(ARM_DWT_CYCCNT < next_mark);
+ next_mark = ARM_DWT_CYCCNT + (T1+T2+T3)-3;
+ *FastPin<FIRST_PIN>::sport() = PORT_MASK;
+ while((next_mark - ARM_DWT_CYCCNT) > (T2+T3+(2*(F_CPU/24000000))));
+ if(USED_LANES>8) {
+ *FastPin<FIRST_PIN>::cport() = ((~b2.shorts[i]) & PORT_MASK);
+ } else {
+ // b2.bytes[0] = 0;
+ *FastPin<FIRST_PIN>::cport() = (PORT_SHIFT(~b2.bytes[7-i]) & PORT_MASK);
+ }
+
+ while((next_mark - ARM_DWT_CYCCNT) > (T3));
+ *FastPin<FIRST_PIN>::cport() = PORT_MASK;
+
+ }
+ }
+
+
+
+ // This method is made static to force making register Y available to use for data on AVR - if the method is non-static, then
+ // gcc will use register Y for the this pointer.
+ static uint32_t showRGBInternal(PixelController<RGB_ORDER, LANES, LANE_MASK> &allpixels) {
+ // Get access to the clock
+ ARM_DEMCR |= ARM_DEMCR_TRCENA;
+ ARM_DWT_CTRL |= ARM_DWT_CTRL_CYCCNTENA;
+ ARM_DWT_CYCCNT = 0;
+
+ // Setup the pixel controller and load/scale the first byte
+ allpixels.preStepFirstByteDithering();
+ register Lines b0;
+
+ allpixels.preStepFirstByteDithering();
+ for(int i = 0; i < USED_LANES; i++) {
+ b0.bytes[i] = allpixels.loadAndScale0(i);
+ }
+
+ cli();
+ uint32_t next_mark = ARM_DWT_CYCCNT + (T1+T2+T3);
+
+ while(allpixels.has(1)) {
+ #if (FASTLED_ALLOW_INTERRUPTS == 1)
+ cli();
+ // if interrupts took longer than 45µs, punt on the current frame
+ if(ARM_DWT_CYCCNT > next_mark) {
+ if((ARM_DWT_CYCCNT-next_mark) > ((WAIT_TIME-5)*CLKS_PER_US)) { sei(); return ARM_DWT_CYCCNT; }
+ }
+ #endif
+ allpixels.stepDithering();
+
+ // Write first byte, read next byte
+ writeBits<8+XTRA0,1>(next_mark, b0, allpixels);
+
+ // Write second byte, read 3rd byte
+ writeBits<8+XTRA0,2>(next_mark, b0, allpixels);
+ allpixels.advanceData();
+
+ // Write third byte
+ writeBits<8+XTRA0,0>(next_mark, b0, allpixels);
+ #if (FASTLED_ALLOW_INTERRUPTS == 1)
+ sei();
+ #endif
+ };
+
+ return ARM_DWT_CYCCNT;
+ }
+};
+
+#define PMASK ((1<<(LANES))-1)
+#define PMASK_HI (PMASK>>8 & 0xFF)
+#define PMASK_LO (PMASK & 0xFF)
+
+template <uint8_t LANES, int T1, int T2, int T3, EOrder RGB_ORDER = GRB, int XTRA0 = 0, bool FLIP = false, int WAIT_TIME = 50>
+class SixteenWayInlineBlockClocklessController : public CPixelLEDController<RGB_ORDER, LANES, PMASK> {
+ typedef typename FastPin<PORTC_FIRST_PIN>::port_ptr_t data_ptr_t;
+ typedef typename FastPin<PORTC_FIRST_PIN>::port_t data_t;
+
+ data_t mPinMask;
+ data_ptr_t mPort;
+ CMinWait<WAIT_TIME> mWait;
+public:
+ virtual void init() {
+ static_assert(LANES <= 16, "Maximum of 16 lanes for Teensy parallel controllers!");
+ // FastPin<30>::setOutput();
+ // FastPin<29>::setOutput();
+ // FastPin<27>::setOutput();
+ // FastPin<28>::setOutput();
+ switch(LANES) {
+ case 16: FastPin<12>::setOutput();
+ case 15: FastPin<11>::setOutput();
+ case 14: FastPin<13>::setOutput();
+ case 13: FastPin<10>::setOutput();
+ case 12: FastPin<9>::setOutput();
+ case 11: FastPin<23>::setOutput();
+ case 10: FastPin<22>::setOutput();
+ case 9: FastPin<15>::setOutput();
+
+ case 8: FastPin<5>::setOutput();
+ case 7: FastPin<21>::setOutput();
+ case 6: FastPin<20>::setOutput();
+ case 5: FastPin<6>::setOutput();
+ case 4: FastPin<8>::setOutput();
+ case 3: FastPin<7>::setOutput();
+ case 2: FastPin<14>::setOutput();
+ case 1: FastPin<2>::setOutput();
+ }
+ }
+
+ virtual void showPixels(PixelController<RGB_ORDER, LANES, PMASK> & pixels) {
+ mWait.wait();
+ uint32_t clocks = showRGBInternal(pixels);
+ #if FASTLED_ALLOW_INTTERUPTS == 0
+ // Adjust the timer
+ long microsTaken = CLKS_TO_MICROS(clocks);
+ MS_COUNTER += (1 + (microsTaken / 1000));
+ #endif
+
+ mWait.mark();
+ }
+
+ typedef union {
+ uint8_t bytes[16];
+ uint16_t shorts[8];
+ uint32_t raw[4];
+ } Lines;
+
+ template<int BITS,int PX> __attribute__ ((always_inline)) inline static void writeBits(register uint32_t & next_mark, register Lines & b, PixelController<RGB_ORDER,LANES, PMASK> &pixels) { // , register uint32_t & b2) {
+ register Lines b2;
+ transpose8x1(b.bytes,b2.bytes);
+ transpose8x1(b.bytes+8,b2.bytes+8);
+ register uint8_t d = pixels.template getd<PX>(pixels);
+ register uint8_t scale = pixels.template getscale<PX>(pixels);
+
+ for(register uint32_t i = 0; (i < LANES) && (i < 8); i++) {
+ while(ARM_DWT_CYCCNT < next_mark);
+ next_mark = ARM_DWT_CYCCNT + (T1+T2+T3)-3;
+ *FastPin<PORTD_FIRST_PIN>::sport() = PMASK_LO;
+ *FastPin<PORTC_FIRST_PIN>::sport() = PMASK_HI;
+
+ while((next_mark - ARM_DWT_CYCCNT) > (T2+T3+6));
+ *FastPin<PORTD_FIRST_PIN>::cport() = ((~b2.bytes[7-i]) & PMASK_LO);
+ *FastPin<PORTC_FIRST_PIN>::cport() = ((~b2.bytes[15-i]) & PMASK_HI);
+
+ while((next_mark - ARM_DWT_CYCCNT) > (T3));
+ *FastPin<PORTD_FIRST_PIN>::cport() = PMASK_LO;
+ *FastPin<PORTC_FIRST_PIN>::cport() = PMASK_HI;
+
+ b.bytes[i] = pixels.template loadAndScale<PX>(pixels,i,d,scale);
+ if(LANES==16 || (LANES>8 && ((i+8) < LANES))) {
+ b.bytes[i+8] = pixels.template loadAndScale<PX>(pixels,i+8,d,scale);
+ }
+ }
+ }
+
+
+
+ // This method is made static to force making register Y available to use for data on AVR - if the method is non-static, then
+ // gcc will use register Y for the this pointer.
+ static uint32_t showRGBInternal(PixelController<RGB_ORDER,LANES, PMASK> &allpixels) {
+ // Get access to the clock
+ ARM_DEMCR |= ARM_DEMCR_TRCENA;
+ ARM_DWT_CTRL |= ARM_DWT_CTRL_CYCCNTENA;
+ ARM_DWT_CYCCNT = 0;
+
+ // Setup the pixel controller and load/scale the first byte
+ allpixels.preStepFirstByteDithering();
+ register Lines b0;
+
+ allpixels.preStepFirstByteDithering();
+ for(int i = 0; i < LANES; i++) {
+ b0.bytes[i] = allpixels.loadAndScale0(i);
+ }
+
+ cli();
+ uint32_t next_mark = ARM_DWT_CYCCNT + (T1+T2+T3);
+
+ while(allpixels.has(1)) {
+ allpixels.stepDithering();
+ #if 0 && (FASTLED_ALLOW_INTERRUPTS == 1)
+ cli();
+ // if interrupts took longer than 45µs, punt on the current frame
+ if(ARM_DWT_CYCCNT > next_mark) {
+ if((ARM_DWT_CYCCNT-next_mark) > ((WAIT_TIME-INTERRUPT_THRESHOLD)*CLKS_PER_US)) { sei(); return ARM_DWT_CYCCNT; }
+ }
+ #endif
+
+ // Write first byte, read next byte
+ writeBits<8+XTRA0,1>(next_mark, b0, allpixels);
+
+ // Write second byte, read 3rd byte
+ writeBits<8+XTRA0,2>(next_mark, b0, allpixels);
+ allpixels.advanceData();
+
+ // Write third byte
+ writeBits<8+XTRA0,0>(next_mark, b0, allpixels);
+
+ #if 0 && (FASTLED_ALLOW_INTERRUPTS == 1)
+ sei();
+ #endif
+ };
+ sei();
+
+ return ARM_DWT_CYCCNT;
+ }
+};
+
+FASTLED_NAMESPACE_END
+
+#endif
+
+#endif
diff --git a/Библиотеки/FastLED-master/platforms/arm/k66/fastled_arm_k66.h b/Библиотеки/FastLED-master/platforms/arm/k66/fastled_arm_k66.h
new file mode 100644
index 0000000..7ef23c3
--- /dev/null
+++ b/Библиотеки/FastLED-master/platforms/arm/k66/fastled_arm_k66.h
@@ -0,0 +1,14 @@
+#ifndef __INC_FASTLED_ARM_K66_H
+#define __INC_FASTLED_ARM_K66_H
+
+// Include the k66 headers
+#include "bitswap.h"
+#include "fastled_delay.h"
+#include "fastpin_arm_k66.h"
+#include "fastspi_arm_k66.h"
+//#include "octows2811_controller.h"
+//#include "smartmatrix_t3.h"
+#include "clockless_arm_k66.h"
+#include "clockless_block_arm_k66.h"
+
+#endif \ No newline at end of file
diff --git a/Библиотеки/FastLED-master/platforms/arm/k66/fastpin_arm_k66.h b/Библиотеки/FastLED-master/platforms/arm/k66/fastpin_arm_k66.h
new file mode 100644
index 0000000..e201096
--- /dev/null
+++ b/Библиотеки/FastLED-master/platforms/arm/k66/fastpin_arm_k66.h
@@ -0,0 +1,128 @@
+#ifndef __FASTPIN_ARM_K66_H
+#define __FASTPIN_ARM_K66_H
+
+FASTLED_NAMESPACE_BEGIN
+
+#if defined(FASTLED_FORCE_SOFTWARE_PINS)
+#warning "Software pin support forced, pin access will be slightly slower."
+#define NO_HARDWARE_PIN_SUPPORT
+#undef HAS_HARDWARE_PIN_SUPPORT
+
+#else
+
+
+/// Template definition for teensy 3.0 style ARM pins, providing direct access to the various GPIO registers. Note that this
+/// uses the full port GPIO registers. In theory, in some way, bit-band register access -should- be faster, however I have found
+/// that something about the way gcc does register allocation results in the bit-band code being slower. It will need more fine tuning.
+/// The registers are data output, set output, clear output, toggle output, input, and direction
+template<uint8_t PIN, uint32_t _MASK, typename _PDOR, typename _PSOR, typename _PCOR, typename _PTOR, typename _PDIR, typename _PDDR> class _ARMPIN {
+public:
+ typedef volatile uint32_t * port_ptr_t;
+ typedef uint32_t port_t;
+
+ inline static void setOutput() { pinMode(PIN, OUTPUT); } // TODO: perform MUX config { _PDDR::r() |= _MASK; }
+ inline static void setInput() { pinMode(PIN, INPUT); } // TODO: preform MUX config { _PDDR::r() &= ~_MASK; }
+
+ inline static void hi() __attribute__ ((always_inline)) { _PSOR::r() = _MASK; }
+ inline static void lo() __attribute__ ((always_inline)) { _PCOR::r() = _MASK; }
+ inline static void set(register port_t val) __attribute__ ((always_inline)) { _PDOR::r() = val; }
+
+ inline static void strobe() __attribute__ ((always_inline)) { toggle(); toggle(); }
+
+ inline static void toggle() __attribute__ ((always_inline)) { _PTOR::r() = _MASK; }
+
+ inline static void hi(register port_ptr_t port) __attribute__ ((always_inline)) { hi(); }
+ inline static void lo(register port_ptr_t port) __attribute__ ((always_inline)) { lo(); }
+ inline static void fastset(register port_ptr_t port, register port_t val) __attribute__ ((always_inline)) { *port = val; }
+
+ inline static port_t hival() __attribute__ ((always_inline)) { return _PDOR::r() | _MASK; }
+ inline static port_t loval() __attribute__ ((always_inline)) { return _PDOR::r() & ~_MASK; }
+ inline static port_ptr_t port() __attribute__ ((always_inline)) { return &_PDOR::r(); }
+ inline static port_ptr_t sport() __attribute__ ((always_inline)) { return &_PSOR::r(); }
+ inline static port_ptr_t cport() __attribute__ ((always_inline)) { return &_PCOR::r(); }
+ inline static port_t mask() __attribute__ ((always_inline)) { return _MASK; }
+};
+
+/// Template definition for teensy 3.0 style ARM pins using bit banding, providing direct access to the various GPIO registers. GCC
+/// does a poor job of optimizing around these accesses so they are not being used just yet.
+template<uint8_t PIN, int _BIT, typename _PDOR, typename _PSOR, typename _PCOR, typename _PTOR, typename _PDIR, typename _PDDR> class _ARMPIN_BITBAND {
+public:
+ typedef volatile uint32_t * port_ptr_t;
+ typedef uint32_t port_t;
+
+ inline static void setOutput() { pinMode(PIN, OUTPUT); } // TODO: perform MUX config { _PDDR::r() |= _MASK; }
+ inline static void setInput() { pinMode(PIN, INPUT); } // TODO: preform MUX config { _PDDR::r() &= ~_MASK; }
+
+ inline static void hi() __attribute__ ((always_inline)) { *_PDOR::template rx<_BIT>() = 1; }
+ inline static void lo() __attribute__ ((always_inline)) { *_PDOR::template rx<_BIT>() = 0; }
+ inline static void set(register port_t val) __attribute__ ((always_inline)) { *_PDOR::template rx<_BIT>() = val; }
+
+ inline static void strobe() __attribute__ ((always_inline)) { toggle(); toggle(); }
+
+ inline static void toggle() __attribute__ ((always_inline)) { *_PTOR::template rx<_BIT>() = 1; }
+
+ inline static void hi(register port_ptr_t port) __attribute__ ((always_inline)) { hi(); }
+ inline static void lo(register port_ptr_t port) __attribute__ ((always_inline)) { lo(); }
+ inline static void fastset(register port_ptr_t port, register port_t val) __attribute__ ((always_inline)) { *_PDOR::template rx<_BIT>() = val; }
+
+ inline static port_t hival() __attribute__ ((always_inline)) { return 1; }
+ inline static port_t loval() __attribute__ ((always_inline)) { return 0; }
+ inline static port_ptr_t port() __attribute__ ((always_inline)) { return _PDOR::template rx<_BIT>(); }
+ inline static port_t mask() __attribute__ ((always_inline)) { return 1; }
+};
+
+// Macros for k20 pin access/definition
+#define GPIO_BITBAND_ADDR(reg, bit) (((uint32_t)&(reg) - 0x40000000) * 32 + (bit) * 4 + 0x42000000)
+#define GPIO_BITBAND_PTR(reg, bit) ((uint32_t *)GPIO_BITBAND_ADDR((reg), (bit)))
+
+#define _R(T) struct __gen_struct_ ## T
+#define _RD32(T) struct __gen_struct_ ## T { static __attribute__((always_inline)) inline reg32_t r() { return T; } \
+ template<int BIT> static __attribute__((always_inline)) inline ptr_reg32_t rx() { return GPIO_BITBAND_PTR(T, BIT); } };
+#define _IO32(L) _RD32(GPIO ## L ## _PDOR); _RD32(GPIO ## L ## _PSOR); _RD32(GPIO ## L ## _PCOR); _RD32(GPIO ## L ## _PTOR); _RD32(GPIO ## L ## _PDIR); _RD32(GPIO ## L ## _PDDR);
+
+#define _DEFPIN_ARM(PIN, BIT, L) template<> class FastPin<PIN> : public _ARMPIN<PIN, 1 << BIT, _R(GPIO ## L ## _PDOR), _R(GPIO ## L ## _PSOR), _R(GPIO ## L ## _PCOR), \
+ _R(GPIO ## L ## _PTOR), _R(GPIO ## L ## _PDIR), _R(GPIO ## L ## _PDDR)> {}; \
+ template<> class FastPinBB<PIN> : public _ARMPIN_BITBAND<PIN, BIT, _R(GPIO ## L ## _PDOR), _R(GPIO ## L ## _PSOR), _R(GPIO ## L ## _PCOR), \
+ _R(GPIO ## L ## _PTOR), _R(GPIO ## L ## _PDIR), _R(GPIO ## L ## _PDDR)> {};
+
+// Actual pin definitions
+#if defined(FASTLED_TEENSY3) && defined(CORE_TEENSY)
+
+_IO32(A); _IO32(B); _IO32(C); _IO32(D); _IO32(E);
+
+#define MAX_PIN 63
+_DEFPIN_ARM( 0, 16, B); _DEFPIN_ARM( 1, 17, B); _DEFPIN_ARM( 2, 0, D); _DEFPIN_ARM( 3, 12, A);
+_DEFPIN_ARM( 4, 13, A); _DEFPIN_ARM( 5, 7, D); _DEFPIN_ARM( 6, 4, D); _DEFPIN_ARM( 7, 2, D);
+_DEFPIN_ARM( 8, 3, D); _DEFPIN_ARM( 9, 3, C); _DEFPIN_ARM(10, 4, C); _DEFPIN_ARM(11, 6, C);
+_DEFPIN_ARM(12, 7, C); _DEFPIN_ARM(13, 5, C); _DEFPIN_ARM(14, 1, D); _DEFPIN_ARM(15, 0, C);
+_DEFPIN_ARM(16, 0, B); _DEFPIN_ARM(17, 1, B); _DEFPIN_ARM(18, 3, B); _DEFPIN_ARM(19, 2, B);
+_DEFPIN_ARM(20, 5, D); _DEFPIN_ARM(21, 6, D); _DEFPIN_ARM(22, 1, C); _DEFPIN_ARM(23, 2, C);
+_DEFPIN_ARM(24, 26, E); _DEFPIN_ARM(25, 5, A); _DEFPIN_ARM(26, 14, A); _DEFPIN_ARM(27, 15, A);
+_DEFPIN_ARM(28, 16, A); _DEFPIN_ARM(29, 18, B); _DEFPIN_ARM(30, 19, B); _DEFPIN_ARM(31, 10, B);
+_DEFPIN_ARM(32, 11, B); _DEFPIN_ARM(33, 24, E); _DEFPIN_ARM(34, 25, E); _DEFPIN_ARM(35, 8, C);
+_DEFPIN_ARM(36, 9, C); _DEFPIN_ARM(37, 10, C); _DEFPIN_ARM(38, 11, C); _DEFPIN_ARM(39, 17, A);
+_DEFPIN_ARM(40, 28, A); _DEFPIN_ARM(41, 29, A); _DEFPIN_ARM(42, 26, A); _DEFPIN_ARM(43, 20, B);
+_DEFPIN_ARM(44, 22, B); _DEFPIN_ARM(45, 23, B); _DEFPIN_ARM(46, 21, B); _DEFPIN_ARM(47, 8, D);
+_DEFPIN_ARM(48, 9, D); _DEFPIN_ARM(49, 4, B); _DEFPIN_ARM(50, 5, B); _DEFPIN_ARM(51, 14, D);
+_DEFPIN_ARM(52, 13, D); _DEFPIN_ARM(53, 12, D); _DEFPIN_ARM(54, 15, D); _DEFPIN_ARM(55, 11, D);
+_DEFPIN_ARM(56, 10, E); _DEFPIN_ARM(57, 11, E); _DEFPIN_ARM(58, 0, E); _DEFPIN_ARM(59, 1, E);
+_DEFPIN_ARM(60, 2, E); _DEFPIN_ARM(61, 3, E); _DEFPIN_ARM(62, 4, E); _DEFPIN_ARM(63, 5, E);
+
+
+
+#define SPI_DATA 11
+#define SPI_CLOCK 13
+
+#define SPI2_DATA 7
+#define SPI2_CLOCK 14
+
+#define FASTLED_TEENSY3
+#define ARM_HARDWARE_SPI
+#define HAS_HARDWARE_PIN_SUPPORT
+#endif
+
+#endif // FASTLED_FORCE_SOFTWARE_PINS
+
+FASTLED_NAMESPACE_END
+
+#endif // __INC_FASTPIN_ARM_K66
diff --git a/Библиотеки/FastLED-master/platforms/arm/k66/fastspi_arm_k66.h b/Библиотеки/FastLED-master/platforms/arm/k66/fastspi_arm_k66.h
new file mode 100644
index 0000000..b13f0dd
--- /dev/null
+++ b/Библиотеки/FastLED-master/platforms/arm/k66/fastspi_arm_k66.h
@@ -0,0 +1,464 @@
+#ifndef __INC_FASTSPI_ARM_H
+#define __INC_FASTSPI_ARM_H
+
+//
+// copied from k20 code
+// changed SPI1 define to KINETISK_SPI1
+// TODO: add third alternative MOSI pin (28) and CLOCK pin (27)
+// TODO: add alternative pins for SPI1
+// TODO: add SPI2 output
+//
+
+FASTLED_NAMESPACE_BEGIN
+
+#if defined(FASTLED_TEENSY3) && defined(CORE_TEENSY)
+
+// Version 1.20 renamed SPI_t to KINETISK_SPI_t
+#if TEENSYDUINO >= 120
+#define SPI_t KINETISK_SPI_t
+#endif
+
+#ifndef KINETISK_SPI0
+#define KINETISK_SPI0 SPI0
+#endif
+
+#ifndef SPI_PUSHR_CONT
+#define SPI_PUSHR_CONT SPIX.PUSHR_CONT
+#define SPI_PUSHR_CTAS(X) SPIX.PUSHR_CTAS(X)
+#define SPI_PUSHR_EOQ SPIX.PUSHR_EOQ
+#define SPI_PUSHR_CTCNT SPIX.PUSHR_CTCNT
+#define SPI_PUSHR_PCS(X) SPIX.PUSHR_PCS(X)
+#endif
+
+// Template function that, on compilation, expands to a constant representing the highest bit set in a byte. Right now,
+// if no bits are set (value is 0), it returns 0, which is also the value returned if the lowest bit is the only bit
+// set (the zero-th bit). Unclear if I will want this to change at some point.
+template<int VAL, int BIT> class BitWork {
+public:
+ static int highestBit() __attribute__((always_inline)) { return (VAL & 1 << BIT) ? BIT : BitWork<VAL, BIT-1>::highestBit(); }
+};
+template<int VAL> class BitWork<VAL, 0> {
+public:
+ static int highestBit() __attribute__((always_inline)) { return 0; }
+};
+
+#define MAX(A, B) (( (A) > (B) ) ? (A) : (B))
+
+#define USE_CONT 0
+// intra-frame backup data
+struct SPIState {
+ uint32_t _ctar0,_ctar1;
+ uint32_t pins[4];
+};
+
+// extern SPIState gState;
+
+
+// Templated function to translate a clock divider value into the prescalar, scalar, and clock doubling setting for the world.
+template <int VAL> void getScalars(uint32_t & preScalar, uint32_t & scalar, uint32_t & dbl) {
+ switch(VAL) {
+ // Handle the dbl clock cases
+ case 0: case 1:
+ case 2: preScalar = 0; scalar = 0; dbl = 1; break;
+ case 3: preScalar = 1; scalar = 0; dbl = 1; break;
+ case 5: preScalar = 2; scalar = 0; dbl = 1; break;
+ case 7: preScalar = 3; scalar = 0; dbl = 1; break;
+
+ // Handle the scalar value 6 cases (since it's not a power of two, it won't get caught
+ // below)
+ case 9: preScalar = 1; scalar = 2; dbl = 1; break;
+ case 18: case 19: preScalar = 1; scalar = 2; dbl = 0; break;
+
+ case 15: preScalar = 2; scalar = 2; dbl = 1; break;
+ case 30: case 31: preScalar = 2; scalar = 2; dbl = 0; break;
+
+ case 21: case 22: case 23: preScalar = 3; scalar = 2; dbl = 1; break;
+ case 42: case 43: case 44: case 45: case 46: case 47: preScalar = 3; scalar = 2; dbl = 0; break;
+ default: {
+ int p2 = BitWork<VAL/2, 15>::highestBit();
+ int p3 = BitWork<VAL/3, 15>::highestBit();
+ int p5 = BitWork<VAL/5, 15>::highestBit();
+ int p7 = BitWork<VAL/7, 15>::highestBit();
+
+ int w2 = 2 * (1 << p2);
+ int w3 = (VAL/3) > 0 ? 3 * (1 << p3) : 0;
+ int w5 = (VAL/5) > 0 ? 5 * (1 << p5) : 0;
+ int w7 = (VAL/7) > 0 ? 7 * (1 << p7) : 0;
+
+ int maxval = MAX(MAX(w2, w3), MAX(w5, w7));
+
+ if(w2 == maxval) { preScalar = 0; scalar = p2; }
+ else if(w3 == maxval) { preScalar = 1; scalar = p3; }
+ else if(w5 == maxval) { preScalar = 2; scalar = p5; }
+ else if(w7 == maxval) { preScalar = 3; scalar = p7; }
+
+ dbl = 0;
+ if(scalar == 0) { dbl = 1; }
+ else if(scalar < 3) { scalar--; }
+ }
+ }
+ return;
+}
+
+#define SPIX (*(SPI_t*)pSPIX)
+
+template <uint8_t _DATA_PIN, uint8_t _CLOCK_PIN, uint8_t _SPI_CLOCK_DIVIDER, uint32_t pSPIX>
+class ARMHardwareSPIOutput {
+ Selectable *m_pSelect;
+ SPIState gState;
+
+ // Borrowed from the teensy3 SPSR emulation code -- note, enabling pin 7 disables pin 11 (and vice versa),
+ // and likewise enabling pin 14 disables pin 13 (and vice versa)
+ inline void enable_pins(void) __attribute__((always_inline)) {
+ //serial_print("enable_pins\n");
+ switch(_DATA_PIN) {
+ case 7:
+ CORE_PIN7_CONFIG = PORT_PCR_DSE | PORT_PCR_MUX(2);
+ CORE_PIN11_CONFIG = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1);
+ break;
+ case 11:
+ CORE_PIN11_CONFIG = PORT_PCR_DSE | PORT_PCR_MUX(2);
+ CORE_PIN7_CONFIG = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1);
+ break;
+ }
+
+ switch(_CLOCK_PIN) {
+ case 13:
+ CORE_PIN13_CONFIG = PORT_PCR_DSE | PORT_PCR_MUX(2);
+ CORE_PIN14_CONFIG = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1);
+ break;
+ case 14:
+ CORE_PIN14_CONFIG = PORT_PCR_DSE | PORT_PCR_MUX(2);
+ CORE_PIN13_CONFIG = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1);
+ break;
+ }
+ }
+
+ // Borrowed from the teensy3 SPSR emulation code. We disable the pins that we're using, and restore the state on the pins that we aren't using
+ inline void disable_pins(void) __attribute__((always_inline)) {
+ switch(_DATA_PIN) {
+ case 7: CORE_PIN7_CONFIG = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1); CORE_PIN11_CONFIG = gState.pins[1]; break;
+ case 11: CORE_PIN11_CONFIG = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1); CORE_PIN7_CONFIG = gState.pins[0]; break;
+ }
+
+ switch(_CLOCK_PIN) {
+ case 13: CORE_PIN13_CONFIG = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1); CORE_PIN14_CONFIG = gState.pins[3]; break;
+ case 14: CORE_PIN14_CONFIG = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1); CORE_PIN13_CONFIG = gState.pins[2]; break;
+ }
+ }
+
+ static inline void update_ctars(uint32_t ctar0, uint32_t ctar1) __attribute__((always_inline)) {
+ if(SPIX.CTAR0 == ctar0 && SPIX.CTAR1 == ctar1) return;
+ uint32_t mcr = SPIX.MCR;
+ if(mcr & SPI_MCR_MDIS) {
+ SPIX.CTAR0 = ctar0;
+ SPIX.CTAR1 = ctar1;
+ } else {
+ SPIX.MCR = mcr | SPI_MCR_MDIS | SPI_MCR_HALT;
+ SPIX.CTAR0 = ctar0;
+ SPIX.CTAR1 = ctar1;
+ SPIX.MCR = mcr;
+ }
+ }
+
+ static inline void update_ctar0(uint32_t ctar) __attribute__((always_inline)) {
+ if (SPIX.CTAR0 == ctar) return;
+ uint32_t mcr = SPIX.MCR;
+ if (mcr & SPI_MCR_MDIS) {
+ SPIX.CTAR0 = ctar;
+ } else {
+ SPIX.MCR = mcr | SPI_MCR_MDIS | SPI_MCR_HALT;
+ SPIX.CTAR0 = ctar;
+
+ SPIX.MCR = mcr;
+ }
+ }
+
+ static inline void update_ctar1(uint32_t ctar) __attribute__((always_inline)) {
+ if (SPIX.CTAR1 == ctar) return;
+ uint32_t mcr = SPIX.MCR;
+ if (mcr & SPI_MCR_MDIS) {
+ SPIX.CTAR1 = ctar;
+ } else {
+ SPIX.MCR = mcr | SPI_MCR_MDIS | SPI_MCR_HALT;
+ SPIX.CTAR1 = ctar;
+ SPIX.MCR = mcr;
+
+ }
+ }
+
+ void setSPIRate() {
+ // Configure CTAR0, defaulting to 8 bits and CTAR1, defaulting to 16 bits
+ uint32_t _PBR = 0;
+ uint32_t _BR = 0;
+ uint32_t _CSSCK = 0;
+ uint32_t _DBR = 0;
+
+ // if(_SPI_CLOCK_DIVIDER >= 256) { _PBR = 0; _BR = _CSSCK = 7; _DBR = 0; } // osc/256
+ // else if(_SPI_CLOCK_DIVIDER >= 128) { _PBR = 0; _BR = _CSSCK = 6; _DBR = 0; } // osc/128
+ // else if(_SPI_CLOCK_DIVIDER >= 64) { _PBR = 0; _BR = _CSSCK = 5; _DBR = 0; } // osc/64
+ // else if(_SPI_CLOCK_DIVIDER >= 32) { _PBR = 0; _BR = _CSSCK = 4; _DBR = 0; } // osc/32
+ // else if(_SPI_CLOCK_DIVIDER >= 16) { _PBR = 0; _BR = _CSSCK = 3; _DBR = 0; } // osc/16
+ // else if(_SPI_CLOCK_DIVIDER >= 8) { _PBR = 0; _BR = _CSSCK = 1; _DBR = 0; } // osc/8
+ // else if(_SPI_CLOCK_DIVIDER >= 7) { _PBR = 3; _BR = _CSSCK = 0; _DBR = 1; } // osc/7
+ // else if(_SPI_CLOCK_DIVIDER >= 5) { _PBR = 2; _BR = _CSSCK = 0; _DBR = 1; } // osc/5
+ // else if(_SPI_CLOCK_DIVIDER >= 4) { _PBR = 0; _BR = _CSSCK = 0; _DBR = 0; } // osc/4
+ // else if(_SPI_CLOCK_DIVIDER >= 3) { _PBR = 1; _BR = _CSSCK = 0; _DBR = 1; } // osc/3
+ // else { _PBR = 0; _BR = _CSSCK = 0; _DBR = 1; } // osc/2
+
+ getScalars<_SPI_CLOCK_DIVIDER>(_PBR, _BR, _DBR);
+ _CSSCK = _BR;
+
+ uint32_t ctar0 = SPI_CTAR_FMSZ(7) | SPI_CTAR_PBR(_PBR) | SPI_CTAR_BR(_BR) | SPI_CTAR_CSSCK(_CSSCK);
+ uint32_t ctar1 = SPI_CTAR_FMSZ(15) | SPI_CTAR_PBR(_PBR) | SPI_CTAR_BR(_BR) | SPI_CTAR_CSSCK(_CSSCK);
+
+ #if USE_CONT == 1
+ ctar0 |= SPI_CTAR_CPHA | SPI_CTAR_CPOL;
+ ctar1 |= SPI_CTAR_CPHA | SPI_CTAR_CPOL;
+ #endif
+
+ if(_DBR) {
+ ctar0 |= SPI_CTAR_DBR;
+ ctar1 |= SPI_CTAR_DBR;
+ }
+
+ update_ctars(ctar0,ctar1);
+ }
+
+ void inline save_spi_state() __attribute__ ((always_inline)) {
+ // save ctar data
+ gState._ctar0 = SPIX.CTAR0;
+ gState._ctar1 = SPIX.CTAR1;
+
+ // save data for the not-us pins
+ gState.pins[0] = CORE_PIN7_CONFIG;
+ gState.pins[1] = CORE_PIN11_CONFIG;
+ gState.pins[2] = CORE_PIN13_CONFIG;
+ gState.pins[3] = CORE_PIN14_CONFIG;
+ }
+
+ void inline restore_spi_state() __attribute__ ((always_inline)) {
+ // restore ctar data
+ update_ctars(gState._ctar0,gState._ctar1);
+
+ // restore data for the not-us pins (not necessary because disable_pins will do this)
+ // CORE_PIN7_CONFIG = gState.pins[0];
+ // CORE_PIN11_CONFIG = gState.pins[1];
+ // CORE_PIN13_CONFIG = gState.pins[2];
+ // CORE_PIN14_CONFIG = gState.pins[3];
+ }
+
+
+public:
+ ARMHardwareSPIOutput() { m_pSelect = NULL; }
+ ARMHardwareSPIOutput(Selectable *pSelect) { m_pSelect = pSelect; }
+ void setSelect(Selectable *pSelect) { m_pSelect = pSelect; }
+
+
+ void init() {
+ // set the pins to output
+ FastPin<_DATA_PIN>::setOutput();
+ FastPin<_CLOCK_PIN>::setOutput();
+
+ // Enable SPI0 clock
+ uint32_t sim6 = SIM_SCGC6;
+ if((SPI_t*)pSPIX == &KINETISK_SPI0) {
+ if (!(sim6 & SIM_SCGC6_SPI0)) {
+ //serial_print("init1\n");
+ SIM_SCGC6 = sim6 | SIM_SCGC6_SPI0;
+ SPIX.CTAR0 = SPI_CTAR_FMSZ(7) | SPI_CTAR_PBR(1) | SPI_CTAR_BR(1);
+ }
+ } else if((SPI_t*)pSPIX == &KINETISK_SPI1) {
+ if (!(sim6 & SIM_SCGC6_SPI1)) {
+ //serial_print("init1\n");
+ SIM_SCGC6 = sim6 | SIM_SCGC6_SPI1;
+ SPIX.CTAR0 = SPI_CTAR_FMSZ(7) | SPI_CTAR_PBR(1) | SPI_CTAR_BR(1);
+ }
+ }
+
+ // Configure SPI as the master and enable
+ SPIX.MCR |= SPI_MCR_MSTR; // | SPI_MCR_CONT_SCKE);
+ SPIX.MCR &= ~(SPI_MCR_MDIS | SPI_MCR_HALT);
+
+ // pin/spi configuration happens on select
+ }
+
+ static void waitFully() __attribute__((always_inline)) {
+ // Wait for the last byte to get shifted into the register
+ cli();
+ while( (SPIX.SR & 0xF000) > 0) {
+ // reset the TCF flag
+ SPIX.SR |= SPI_SR_TCF;
+ }
+ sei();
+
+ // wait for the TCF flag to get set
+ while (!(SPIX.SR & SPI_SR_TCF));
+ SPIX.SR |= (SPI_SR_TCF | SPI_SR_EOQF);
+ }
+
+ static bool needwait() __attribute__((always_inline)) { return (SPIX.SR & 0x4000); }
+ static void wait() __attribute__((always_inline)) { while( (SPIX.SR & 0x4000) ); }
+ static void wait1() __attribute__((always_inline)) { while( (SPIX.SR & 0xF000) >= 0x2000); }
+
+ enum ECont { CONT, NOCONT };
+ enum EWait { PRE, POST, NONE };
+ enum ELast { NOTLAST, LAST };
+
+ #if USE_CONT == 1
+ #define CM CONT
+ #else
+ #define CM NOCONT
+ #endif
+ #define WM PRE
+
+ template<ECont CONT_STATE, EWait WAIT_STATE, ELast LAST_STATE> class Write {
+ public:
+ static void writeWord(uint16_t w) __attribute__((always_inline)) {
+ if(WAIT_STATE == PRE) { wait(); }
+ SPIX.PUSHR = ((LAST_STATE == LAST) ? SPI_PUSHR_EOQ : 0) |
+ ((CONT_STATE == CONT) ? SPI_PUSHR_CONT : 0) |
+ SPI_PUSHR_CTAS(1) | (w & 0xFFFF);
+ SPIX.SR |= SPI_SR_TCF;
+ if(WAIT_STATE == POST) { wait(); }
+ }
+
+ static void writeByte(uint8_t b) __attribute__((always_inline)) {
+ if(WAIT_STATE == PRE) { wait(); }
+ SPIX.PUSHR = ((LAST_STATE == LAST) ? SPI_PUSHR_EOQ : 0) |
+ ((CONT_STATE == CONT) ? SPI_PUSHR_CONT : 0) |
+ SPI_PUSHR_CTAS(0) | (b & 0xFF);
+ SPIX.SR |= SPI_SR_TCF;
+ if(WAIT_STATE == POST) { wait(); }
+ }
+ };
+
+ static void writeWord(uint16_t w) __attribute__((always_inline)) { wait(); SPIX.PUSHR = SPI_PUSHR_CTAS(1) | (w & 0xFFFF); SPIX.SR |= SPI_SR_TCF;}
+ static void writeWordNoWait(uint16_t w) __attribute__((always_inline)) { SPIX.PUSHR = SPI_PUSHR_CTAS(1) | (w & 0xFFFF); SPIX.SR |= SPI_SR_TCF;}
+
+ static void writeByte(uint8_t b) __attribute__((always_inline)) { wait(); SPIX.PUSHR = SPI_PUSHR_CTAS(0) | (b & 0xFF); SPIX.SR |= SPI_SR_TCF;}
+ static void writeBytePostWait(uint8_t b) __attribute__((always_inline)) { SPIX.PUSHR = SPI_PUSHR_CTAS(0) | (b & 0xFF);SPIX.SR |= SPI_SR_TCF; wait(); }
+ static void writeByteNoWait(uint8_t b) __attribute__((always_inline)) { SPIX.PUSHR = SPI_PUSHR_CTAS(0) | (b & 0xFF); SPIX.SR |= SPI_SR_TCF;}
+
+ static void writeWordCont(uint16_t w) __attribute__((always_inline)) { wait(); SPIX.PUSHR = SPI_PUSHR_CONT | SPI_PUSHR_CTAS(1) | (w & 0xFFFF); SPIX.SR |= SPI_SR_TCF;}
+ static void writeWordContNoWait(uint16_t w) __attribute__((always_inline)) { SPIX.PUSHR = SPI_PUSHR_CONT | SPI_PUSHR_CTAS(1) | (w & 0xFFFF); SPIX.SR |= SPI_SR_TCF;}
+
+ static void writeByteCont(uint8_t b) __attribute__((always_inline)) { wait(); SPIX.PUSHR = SPI_PUSHR_CONT | SPI_PUSHR_CTAS(0) | (b & 0xFF); SPIX.SR |= SPI_SR_TCF;}
+ static void writeByteContPostWait(uint8_t b) __attribute__((always_inline)) { SPIX.PUSHR = SPI_PUSHR_CONT | SPI_PUSHR_CTAS(0) | (b & 0xFF); SPIX.SR |= SPI_SR_TCF;wait(); }
+ static void writeByteContNoWait(uint8_t b) __attribute__((always_inline)) { SPIX.PUSHR = SPI_PUSHR_CONT | SPI_PUSHR_CTAS(0) | (b & 0xFF); SPIX.SR |= SPI_SR_TCF;}
+
+ // not the most efficient mechanism in the world - but should be enough for sm16716 and friends
+ template <uint8_t BIT> inline static void writeBit(uint8_t b) {
+ uint32_t ctar1_save = SPIX.CTAR1;
+
+ // Clear out the FMSZ bits, reset them for 1 bit transferd for the start bit
+ uint32_t ctar1 = (ctar1_save & (~SPI_CTAR_FMSZ(15))) | SPI_CTAR_FMSZ(0);
+ update_ctar1(ctar1);
+
+ writeWord( (b & (1 << BIT)) != 0);
+
+ update_ctar1(ctar1_save);
+ }
+
+ void inline select() __attribute__((always_inline)) {
+ save_spi_state();
+ if(m_pSelect != NULL) { m_pSelect->select(); }
+ setSPIRate();
+ enable_pins();
+ }
+
+ void inline release() __attribute__((always_inline)) {
+ disable_pins();
+ if(m_pSelect != NULL) { m_pSelect->release(); }
+ restore_spi_state();
+ }
+
+ static void writeBytesValueRaw(uint8_t value, int len) {
+ while(len--) { Write<CM, WM, NOTLAST>::writeByte(value); }
+ }
+
+ void writeBytesValue(uint8_t value, int len) {
+ select();
+ while(len--) {
+ writeByte(value);
+ }
+ waitFully();
+ release();
+ }
+
+ // Write a block of n uint8_ts out
+ template <class D> void writeBytes(register uint8_t *data, int len) {
+ uint8_t *end = data + len;
+ select();
+ // could be optimized to write 16bit words out instead of 8bit bytes
+ while(data != end) {
+ writeByte(D::adjust(*data++));
+ }
+ D::postBlock(len);
+ waitFully();
+ release();
+ }
+
+ void writeBytes(register uint8_t *data, int len) { writeBytes<DATA_NOP>(data, len); }
+
+ // write a block of uint8_ts out in groups of three. len is the total number of uint8_ts to write out. The template
+ // parameters indicate how many uint8_ts to skip at the beginning and/or end of each grouping
+ template <uint8_t FLAGS, class D, EOrder RGB_ORDER> void writePixels(PixelController<RGB_ORDER> pixels) {
+ select();
+ int len = pixels.mLen;
+
+ // Setup the pixel controller
+ if((FLAGS & FLAG_START_BIT) == 0) {
+ //If no start bit stupiditiy, write out as many 16-bit blocks as we can
+ while(pixels.has(2)) {
+ // Load and write out the first two bytes
+ if(WM == NONE) { wait1(); }
+ Write<CM, WM, NOTLAST>::writeWord(D::adjust(pixels.loadAndScale0()) << 8 | D::adjust(pixels.loadAndScale1()));
+
+ // Load and write out the next two bytes (step dithering, advance data in between since we
+ // cross pixels here)
+ Write<CM, WM, NOTLAST>::writeWord(D::adjust(pixels.loadAndScale2()) << 8 | D::adjust(pixels.stepAdvanceAndLoadAndScale0()));
+
+ // Load and write out the next two bytes
+ Write<CM, WM, NOTLAST>::writeWord(D::adjust(pixels.loadAndScale1()) << 8 | D::adjust(pixels.loadAndScale2()));
+ pixels.stepDithering();
+ pixels.advanceData();
+ }
+
+ if(pixels.has(1)) {
+ if(WM == NONE) { wait1(); }
+ // write out the rest as alternating 16/8-bit blocks (likely to be just one)
+ Write<CM, WM, NOTLAST>::writeWord(D::adjust(pixels.loadAndScale0()) << 8 | D::adjust(pixels.loadAndScale1()));
+ Write<CM, WM, NOTLAST>::writeByte(D::adjust(pixels.loadAndScale2()));
+ }
+
+ D::postBlock(len);
+ waitFully();
+ } else if(FLAGS & FLAG_START_BIT) {
+ uint32_t ctar1_save = SPIX.CTAR1;
+
+ // Clear out the FMSZ bits, reset them for 9 bits transferd for the start bit
+ uint32_t ctar1 = (ctar1_save & (~SPI_CTAR_FMSZ(15))) | SPI_CTAR_FMSZ(8);
+ update_ctar1(ctar1);
+
+ while(pixels.has(1)) {
+ writeWord( 0x100 | D::adjust(pixels.loadAndScale0()));
+ writeByte(D::adjust(pixels.loadAndScale1()));
+ writeByte(D::adjust(pixels.loadAndScale2()));
+ pixels.advanceData();
+ pixels.stepDithering();
+ }
+ D::postBlock(len);
+ waitFully();
+
+ // restore ctar1
+ update_ctar1(ctar1_save);
+ }
+ release();
+ }
+};
+#endif
+
+FASTLED_NAMESPACE_END
+
+#endif
diff --git a/Библиотеки/FastLED-master/platforms/arm/k66/led_sysdefs_arm_k66.h b/Библиотеки/FastLED-master/platforms/arm/k66/led_sysdefs_arm_k66.h
new file mode 100644
index 0000000..0b0c701
--- /dev/null
+++ b/Библиотеки/FastLED-master/platforms/arm/k66/led_sysdefs_arm_k66.h
@@ -0,0 +1,46 @@
+#ifndef __INC_LED_SYSDEFS_ARM_K66_H
+#define __INC_LED_SYSDEFS_ARM_K66_H
+
+#define FASTLED_TEENSY3
+#define FASTLED_ARM
+
+#ifndef INTERRUPT_THRESHOLD
+#define INTERRUPT_THRESHOLD 1
+#endif
+
+// Default to allowing interrupts
+#ifndef FASTLED_ALLOW_INTERRUPTS
+#define FASTLED_ALLOW_INTERRUPTS 1
+#endif
+
+#if FASTLED_ALLOW_INTERRUPTS == 1
+#define FASTLED_ACCURATE_CLOCK
+#endif
+
+#if (F_CPU == 192000000)
+#define CLK_DBL 1
+#endif
+
+// Get some system include files
+#include <avr/io.h>
+#include <avr/interrupt.h> // for cli/se definitions
+
+// Define the register types
+#if defined(ARDUINO) // && ARDUINO < 150
+typedef volatile uint8_t RoReg; /**< Read only 8-bit register (volatile const unsigned int) */
+typedef volatile uint8_t RwReg; /**< Read-Write 8-bit register (volatile unsigned int) */
+#endif
+
+extern volatile uint32_t systick_millis_count;
+# define MS_COUNTER systick_millis_count
+
+
+// Default to using PROGMEM, since TEENSY3 provides it
+// even though all it does is ignore it. Just being
+// conservative here in case TEENSY3 changes.
+#ifndef FASTLED_USE_PROGMEM
+#define FASTLED_USE_PROGMEM 1
+#endif
+
+
+#endif
diff --git a/Библиотеки/FastLED-master/platforms/arm/kl26/clockless_arm_kl26.h b/Библиотеки/FastLED-master/platforms/arm/kl26/clockless_arm_kl26.h
new file mode 100644
index 0000000..7138d0c
--- /dev/null
+++ b/Библиотеки/FastLED-master/platforms/arm/kl26/clockless_arm_kl26.h
@@ -0,0 +1,65 @@
+#ifndef __INC_CLOCKLESS_ARM_KL26
+#define __INC_CLOCKLESS_ARM_KL26
+
+#include "platforms/arm/common/m0clockless.h"
+FASTLED_NAMESPACE_BEGIN
+#define FASTLED_HAS_CLOCKLESS 1
+
+template <uint8_t DATA_PIN, int T1, int T2, int T3, EOrder RGB_ORDER = RGB, int XTRA0 = 0, bool FLIP = false, int WAIT_TIME = 50>
+class ClocklessController : public CPixelLEDController<RGB_ORDER> {
+ typedef typename FastPinBB<DATA_PIN>::port_ptr_t data_ptr_t;
+ typedef typename FastPinBB<DATA_PIN>::port_t data_t;
+
+ data_t mPinMask;
+ data_ptr_t mPort;
+ CMinWait<WAIT_TIME> mWait;
+public:
+ virtual void init() {
+ FastPinBB<DATA_PIN>::setOutput();
+ mPinMask = FastPinBB<DATA_PIN>::mask();
+ mPort = FastPinBB<DATA_PIN>::port();
+ }
+
+ virtual uint16_t getMaxRefreshRate() const { return 400; }
+
+ virtual void showPixels(PixelController<RGB_ORDER> & pixels) {
+ mWait.wait();
+ cli();
+ uint32_t clocks = showRGBInternal(pixels);
+ if(!clocks) {
+ sei(); delayMicroseconds(WAIT_TIME); cli();
+ clocks = showRGBInternal(pixels);
+ }
+ long microsTaken = CLKS_TO_MICROS(clocks * ((T1 + T2 + T3) * 24));
+ MS_COUNTER += (microsTaken / 1000);
+ sei();
+ mWait.mark();
+ }
+
+ // This method is made static to force making register Y available to use for data on AVR - if the method is non-static, then
+ // gcc will use register Y for the this pointer.
+ static uint32_t showRGBInternal(PixelController<RGB_ORDER> pixels) {
+ struct M0ClocklessData data;
+ data.d[0] = pixels.d[0];
+ data.d[1] = pixels.d[1];
+ data.d[2] = pixels.d[2];
+ data.s[0] = pixels.mScale[0];
+ data.s[1] = pixels.mScale[1];
+ data.s[2] = pixels.mScale[2];
+ data.e[0] = pixels.e[0];
+ data.e[1] = pixels.e[1];
+ data.e[2] = pixels.e[2];
+ data.adj = pixels.mAdvance;
+
+ typename FastPin<DATA_PIN>::port_ptr_t portBase = FastPin<DATA_PIN>::port();
+ return showLedData<4,8,T1,T2,T3,RGB_ORDER, WAIT_TIME>(portBase, FastPin<DATA_PIN>::mask(), pixels.mData, pixels.mLen, &data);
+ // return 0; // 0x00FFFFFF - _VAL;
+ }
+
+
+};
+
+FASTLED_NAMESPACE_END
+
+
+#endif // __INC_CLOCKLESS_ARM_KL26
diff --git a/Библиотеки/FastLED-master/platforms/arm/kl26/fastled_arm_kl26.h b/Библиотеки/FastLED-master/platforms/arm/kl26/fastled_arm_kl26.h
new file mode 100644
index 0000000..9a93caa
--- /dev/null
+++ b/Библиотеки/FastLED-master/platforms/arm/kl26/fastled_arm_kl26.h
@@ -0,0 +1,10 @@
+#ifndef __INC_FASTLED_ARM_KL26_H
+#define __INC_FASTLED_ARM_KL26_H
+
+// Include the k20 headers
+#include "fastled_delay.h"
+#include "fastpin_arm_kl26.h"
+#include "fastspi_arm_kl26.h"
+#include "clockless_arm_kl26.h"
+
+#endif
diff --git a/Библиотеки/FastLED-master/platforms/arm/kl26/fastpin_arm_kl26.h b/Библиотеки/FastLED-master/platforms/arm/kl26/fastpin_arm_kl26.h
new file mode 100644
index 0000000..4c30cd7
--- /dev/null
+++ b/Библиотеки/FastLED-master/platforms/arm/kl26/fastpin_arm_kl26.h
@@ -0,0 +1,88 @@
+#ifndef __FASTPIN_ARM_KL26_H
+#define __FASTPIN_ARM_KL26_H
+
+FASTLED_NAMESPACE_BEGIN
+
+#if defined(FASTLED_FORCE_SOFTWARE_PINS)
+#warning "Software pin support forced, pin access will be sloightly slower."
+#define NO_HARDWARE_PIN_SUPPORT
+#undef HAS_HARDWARE_PIN_SUPPORT
+
+#else
+
+
+/// Template definition for teensy LC style ARM pins, providing direct access to the various GPIO registers. Note that this
+/// uses the full port GPIO registers. In theory, in some way, bit-band register access -should- be faster, however I have found
+/// that something about the way gcc does register allocation results in the bit-band code being slower. It will need more fine tuning.
+/// The registers are data output, set output, clear output, toggle output, input, and direction
+template<uint8_t PIN, uint32_t _MASK, typename _PDOR, typename _PSOR, typename _PCOR, typename _PTOR, typename _PDIR, typename _PDDR> class _ARMPIN {
+public:
+ typedef volatile uint32_t * port_ptr_t;
+ typedef uint32_t port_t;
+
+ inline static void setOutput() { pinMode(PIN, OUTPUT); } // TODO: perform MUX config { _PDDR::r() |= _MASK; }
+ inline static void setInput() { pinMode(PIN, INPUT); } // TODO: preform MUX config { _PDDR::r() &= ~_MASK; }
+
+ inline static void hi() __attribute__ ((always_inline)) { _PSOR::r() = _MASK; }
+ inline static void lo() __attribute__ ((always_inline)) { _PCOR::r() = _MASK; }
+ inline static void set(register port_t val) __attribute__ ((always_inline)) { _PDOR::r() = val; }
+
+ inline static void strobe() __attribute__ ((always_inline)) { toggle(); toggle(); }
+
+ inline static void toggle() __attribute__ ((always_inline)) { _PTOR::r() = _MASK; }
+
+ inline static void hi(register port_ptr_t port) __attribute__ ((always_inline)) { hi(); }
+ inline static void lo(register port_ptr_t port) __attribute__ ((always_inline)) { lo(); }
+ inline static void fastset(register port_ptr_t port, register port_t val) __attribute__ ((always_inline)) { *port = val; }
+
+ inline static port_t hival() __attribute__ ((always_inline)) { return _PDOR::r() | _MASK; }
+ inline static port_t loval() __attribute__ ((always_inline)) { return _PDOR::r() & ~_MASK; }
+ inline static port_ptr_t port() __attribute__ ((always_inline)) { return &_PDOR::r(); }
+ inline static port_ptr_t sport() __attribute__ ((always_inline)) { return &_PSOR::r(); }
+ inline static port_ptr_t cport() __attribute__ ((always_inline)) { return &_PCOR::r(); }
+ inline static port_t mask() __attribute__ ((always_inline)) { return _MASK; }
+};
+
+// Macros for kl26 pin access/definition
+#define GPIO_BITBAND_ADDR(reg, bit) (((uint32_t)&(reg) - 0x40000000) * 32 + (bit) * 4 + 0x42000000)
+#define GPIO_BITBAND_PTR(reg, bit) ((uint32_t *)GPIO_BITBAND_ADDR((reg), (bit)))
+
+#define _R(T) struct __gen_struct_ ## T
+#define _RD32(T) struct __gen_struct_ ## T { static __attribute__((always_inline)) inline reg32_t r() { return T; } \
+template<int BIT> static __attribute__((always_inline)) inline ptr_reg32_t rx() { return GPIO_BITBAND_PTR(T, BIT); } };
+#define _IO32(L) _RD32(FGPIO ## L ## _PDOR); _RD32(FGPIO ## L ## _PSOR); _RD32(FGPIO ## L ## _PCOR); _RD32(GPIO ## L ## _PTOR); _RD32(FGPIO ## L ## _PDIR); _RD32(FGPIO ## L ## _PDDR);
+
+#define _DEFPIN_ARM(PIN, BIT, L) template<> class FastPin<PIN> : public _ARMPIN<PIN, 1 << BIT, _R(FGPIO ## L ## _PDOR), _R(FGPIO ## L ## _PSOR), _R(FGPIO ## L ## _PCOR), \
+_R(GPIO ## L ## _PTOR), _R(FGPIO ## L ## _PDIR), _R(FGPIO ## L ## _PDDR)> {}; \
+/* template<> class FastPinBB<PIN> : public _ARMPIN_BITBAND<PIN, BIT, _R(GPIO ## L ## _PDOR), _R(GPIO ## L ## _PSOR), _R(GPIO ## L ## _PCOR), \
+_R(GPIO ## L ## _PTOR), _R(GPIO ## L ## _PDIR), _R(GPIO ## L ## _PDDR)> {}; */
+
+// Actual pin definitions
+#if defined(FASTLED_TEENSYLC) && defined(CORE_TEENSY)
+
+_IO32(A); _IO32(B); _IO32(C); _IO32(D); _IO32(E);
+
+#define MAX_PIN 26
+_DEFPIN_ARM(0, 16, B); _DEFPIN_ARM(1, 17, B); _DEFPIN_ARM(2, 0, D); _DEFPIN_ARM(3, 1, A);
+_DEFPIN_ARM(4, 2, A); _DEFPIN_ARM(5, 7, D); _DEFPIN_ARM(6, 4, D); _DEFPIN_ARM(7, 2, D);
+_DEFPIN_ARM(8, 3, D); _DEFPIN_ARM(9, 3, C); _DEFPIN_ARM(10, 4, C); _DEFPIN_ARM(11, 6, C);
+_DEFPIN_ARM(12, 7, C); _DEFPIN_ARM(13, 5, C); _DEFPIN_ARM(14, 1, D); _DEFPIN_ARM(15, 0, C);
+_DEFPIN_ARM(16, 0, B); _DEFPIN_ARM(17, 1, B); _DEFPIN_ARM(18, 3, B); _DEFPIN_ARM(19, 2, B);
+_DEFPIN_ARM(20, 5, D); _DEFPIN_ARM(21, 6, D); _DEFPIN_ARM(22, 1, C); _DEFPIN_ARM(23, 2, C);
+_DEFPIN_ARM(24, 20, E); _DEFPIN_ARM(25, 21, E); _DEFPIN_ARM(26, 30, E);
+
+#define SPI_DATA 11
+#define SPI_CLOCK 13
+// #define SPI1 (*(SPI_t *)0x4002D000)
+
+#define SPI2_DATA 0
+#define SPI2_CLOCK 20
+
+#define HAS_HARDWARE_PIN_SUPPORT
+#endif
+
+#endif // FASTLED_FORCE_SOFTWARE_PINS
+
+FASTLED_NAMESPACE_END
+
+#endif // __INC_FASTPIN_ARM_K20
diff --git a/Библиотеки/FastLED-master/platforms/arm/kl26/fastspi_arm_kl26.h b/Библиотеки/FastLED-master/platforms/arm/kl26/fastspi_arm_kl26.h
new file mode 100644
index 0000000..869b605
--- /dev/null
+++ b/Библиотеки/FastLED-master/platforms/arm/kl26/fastspi_arm_kl26.h
@@ -0,0 +1,252 @@
+#ifndef __INC_FASTSPI_ARM_KL26_H
+#define __INC_FASTSPI_ARM_KL26_h
+
+FASTLED_NAMESPACE_BEGIN
+
+template <int VAL> void getScalars(uint8_t & sppr, uint8_t & spr) {
+ if(VAL > 4096) { sppr=7; spr=8; }
+ else if(VAL > 3584) { sppr=6; spr=8; }
+ else if(VAL > 3072) { sppr=5; spr=8; }
+ else if(VAL > 2560) { sppr=4; spr=8; }
+ else if(VAL > 2048) { sppr=7; spr=7; }
+ else if(VAL > 2048) { sppr=3; spr=8; }
+ else if(VAL > 1792) { sppr=6; spr=7; }
+ else if(VAL > 1536) { sppr=5; spr=7; }
+ else if(VAL > 1536) { sppr=2; spr=8; }
+ else if(VAL > 1280) { sppr=4; spr=7; }
+ else if(VAL > 1024) { sppr=7; spr=6; }
+ else if(VAL > 1024) { sppr=3; spr=7; }
+ else if(VAL > 1024) { sppr=1; spr=8; }
+ else if(VAL > 896) { sppr=6; spr=6; }
+ else if(VAL > 768) { sppr=5; spr=6; }
+ else if(VAL > 768) { sppr=2; spr=7; }
+ else if(VAL > 640) { sppr=4; spr=6; }
+ else if(VAL > 512) { sppr=7; spr=5; }
+ else if(VAL > 512) { sppr=3; spr=6; }
+ else if(VAL > 512) { sppr=1; spr=7; }
+ else if(VAL > 512) { sppr=0; spr=8; }
+ else if(VAL > 448) { sppr=6; spr=5; }
+ else if(VAL > 384) { sppr=5; spr=5; }
+ else if(VAL > 384) { sppr=2; spr=6; }
+ else if(VAL > 320) { sppr=4; spr=5; }
+ else if(VAL > 256) { sppr=7; spr=4; }
+ else if(VAL > 256) { sppr=3; spr=5; }
+ else if(VAL > 256) { sppr=1; spr=6; }
+ else if(VAL > 256) { sppr=0; spr=7; }
+ else if(VAL > 224) { sppr=6; spr=4; }
+ else if(VAL > 192) { sppr=5; spr=4; }
+ else if(VAL > 192) { sppr=2; spr=5; }
+ else if(VAL > 160) { sppr=4; spr=4; }
+ else if(VAL > 128) { sppr=7; spr=3; }
+ else if(VAL > 128) { sppr=3; spr=4; }
+ else if(VAL > 128) { sppr=1; spr=5; }
+ else if(VAL > 128) { sppr=0; spr=6; }
+ else if(VAL > 112) { sppr=6; spr=3; }
+ else if(VAL > 96) { sppr=5; spr=3; }
+ else if(VAL > 96) { sppr=2; spr=4; }
+ else if(VAL > 80) { sppr=4; spr=3; }
+ else if(VAL > 64) { sppr=7; spr=2; }
+ else if(VAL > 64) { sppr=3; spr=3; }
+ else if(VAL > 64) { sppr=1; spr=4; }
+ else if(VAL > 64) { sppr=0; spr=5; }
+ else if(VAL > 56) { sppr=6; spr=2; }
+ else if(VAL > 48) { sppr=5; spr=2; }
+ else if(VAL > 48) { sppr=2; spr=3; }
+ else if(VAL > 40) { sppr=4; spr=2; }
+ else if(VAL > 32) { sppr=7; spr=1; }
+ else if(VAL > 32) { sppr=3; spr=2; }
+ else if(VAL > 32) { sppr=1; spr=3; }
+ else if(VAL > 32) { sppr=0; spr=4; }
+ else if(VAL > 28) { sppr=6; spr=1; }
+ else if(VAL > 24) { sppr=5; spr=1; }
+ else if(VAL > 24) { sppr=2; spr=2; }
+ else if(VAL > 20) { sppr=4; spr=1; }
+ else if(VAL > 16) { sppr=7; spr=0; }
+ else if(VAL > 16) { sppr=3; spr=1; }
+ else if(VAL > 16) { sppr=1; spr=2; }
+ else if(VAL > 16) { sppr=0; spr=3; }
+ else if(VAL > 14) { sppr=6; spr=0; }
+ else if(VAL > 12) { sppr=5; spr=0; }
+ else if(VAL > 12) { sppr=2; spr=1; }
+ else if(VAL > 10) { sppr=4; spr=0; }
+ else if(VAL > 8) { sppr=3; spr=0; }
+ else if(VAL > 8) { sppr=1; spr=1; }
+ else if(VAL > 8) { sppr=0; spr=2; }
+ else if(VAL > 6) { sppr=2; spr=0; }
+ else if(VAL > 4) { sppr=1; spr=0; }
+ else if(VAL > 4) { sppr=0; spr=1; }
+ else /* if(VAL > 2) */ { sppr=0; spr=0; }
+}
+
+
+#define SPIX (*(KINETISL_SPI_t*)pSPIX)
+#define ARM_HARDWARE_SPI
+
+template <uint8_t _DATA_PIN, uint8_t _CLOCK_PIN, uint8_t _SPI_CLOCK_DIVIDER, uint32_t pSPIX>
+class ARMHardwareSPIOutput {
+ Selectable *m_pSelect;
+
+ static inline void enable_pins(void) __attribute__((always_inline)) {
+ switch(_DATA_PIN) {
+ case 0: CORE_PIN0_CONFIG = PORT_PCR_MUX(2); break;
+ case 1: CORE_PIN1_CONFIG = PORT_PCR_MUX(5); break;
+ case 7: CORE_PIN7_CONFIG = PORT_PCR_MUX(2); break;
+ case 8: CORE_PIN8_CONFIG = PORT_PCR_MUX(5); break;
+ case 11: CORE_PIN11_CONFIG = PORT_PCR_MUX(2); break;
+ case 12: CORE_PIN12_CONFIG = PORT_PCR_MUX(5); break;
+ case 21: CORE_PIN21_CONFIG = PORT_PCR_MUX(2); break;
+ }
+
+ switch(_CLOCK_PIN) {
+ case 13: CORE_PIN13_CONFIG = PORT_PCR_MUX(2); break;
+ case 14: CORE_PIN14_CONFIG = PORT_PCR_MUX(2); break;
+ case 20: CORE_PIN20_CONFIG = PORT_PCR_MUX(2); break;
+ }
+ }
+
+ static inline void disable_pins(void) __attribute((always_inline)) {
+ switch(_DATA_PIN) {
+ case 0: CORE_PIN0_CONFIG = PORT_PCR_SRE | PORT_PCR_MUX(1); break;
+ case 1: CORE_PIN1_CONFIG = PORT_PCR_SRE | PORT_PCR_MUX(1); break;
+ case 7: CORE_PIN7_CONFIG = PORT_PCR_SRE | PORT_PCR_MUX(1); break;
+ case 8: CORE_PIN8_CONFIG = PORT_PCR_SRE | PORT_PCR_MUX(1); break;
+ case 11: CORE_PIN11_CONFIG = PORT_PCR_SRE | PORT_PCR_MUX(1); break;
+ case 12: CORE_PIN12_CONFIG = PORT_PCR_SRE | PORT_PCR_MUX(1); break;
+ case 21: CORE_PIN21_CONFIG = PORT_PCR_SRE | PORT_PCR_MUX(1); break;
+ }
+
+ switch(_CLOCK_PIN) {
+ case 13: CORE_PIN13_CONFIG = PORT_PCR_SRE | PORT_PCR_MUX(1); break;
+ case 14: CORE_PIN14_CONFIG = PORT_PCR_SRE | PORT_PCR_MUX(1); break;
+ case 20: CORE_PIN20_CONFIG = PORT_PCR_SRE | PORT_PCR_MUX(1); break;
+ }
+ }
+
+ void setSPIRate() {
+ uint8_t sppr, spr;
+ getScalars<_SPI_CLOCK_DIVIDER>(sppr, spr);
+
+ // Set the speed
+ SPIX.BR = SPI_BR_SPPR(sppr) | SPI_BR_SPR(spr);
+
+ // Also, force 8 bit transfers (don't want to juggle 8/16 since that flushes the world)
+ SPIX.C2 = 0;
+ SPIX.C1 |= SPI_C1_SPE;
+ }
+
+public:
+ ARMHardwareSPIOutput() { m_pSelect = NULL; }
+ ARMHardwareSPIOutput(Selectable *pSelect) { m_pSelect = pSelect; }
+
+ // set the object representing the selectable
+ void setSelect(Selectable *pSelect) { m_pSelect = pSelect; }
+
+ // initialize the SPI subssytem
+ void init() {
+ FastPin<_DATA_PIN>::setOutput();
+ FastPin<_CLOCK_PIN>::setOutput();
+
+ // Enable the SPI clocks
+ uint32_t sim4 = SIM_SCGC4;
+ if ((pSPIX == 0x40076000) && !(sim4 & SIM_SCGC4_SPI0)) {
+ SIM_SCGC4 = sim4 | SIM_SCGC4_SPI0;
+ }
+
+ if ( (pSPIX == 0x40077000) && !(sim4 & SIM_SCGC4_SPI1)) {
+ SIM_SCGC4 = sim4 | SIM_SCGC4_SPI1;
+ }
+
+ SPIX.C1 = SPI_C1_MSTR | SPI_C1_SPE;
+ SPIX.C2 = 0;
+ SPIX.BR = SPI_BR_SPPR(1) | SPI_BR_SPR(0);
+ }
+
+ // latch the CS select
+ void inline select() __attribute__((always_inline)) {
+ if(m_pSelect != NULL) { m_pSelect->select(); }
+ setSPIRate();
+ enable_pins();
+ }
+
+
+ // release the CS select
+ void inline release() __attribute__((always_inline)) {
+ disable_pins();
+ if(m_pSelect != NULL) { m_pSelect->release(); }
+ }
+
+ // Wait for the world to be clear
+ static void wait() __attribute__((always_inline)) { while(!(SPIX.S & SPI_S_SPTEF)); }
+
+ // wait until all queued up data has been written
+ void waitFully() { wait(); }
+
+ // not the most efficient mechanism in the world - but should be enough for sm16716 and friends
+ template <uint8_t BIT> inline static void writeBit(uint8_t b) { /* TODO */ }
+
+ // write a byte out via SPI (returns immediately on writing register)
+ static void writeByte(uint8_t b) __attribute__((always_inline)) { wait(); SPIX.DL = b; }
+ // write a word out via SPI (returns immediately on writing register)
+ static void writeWord(uint16_t w) __attribute__((always_inline)) { writeByte(w>>8); writeByte(w & 0xFF); }
+
+ // A raw set of writing byte values, assumes setup/init/waiting done elsewhere (static for use by adjustment classes)
+ static void writeBytesValueRaw(uint8_t value, int len) {
+ while(len--) { writeByte(value); }
+ }
+
+ // A full cycle of writing a value for len bytes, including select, release, and waiting
+ void writeBytesValue(uint8_t value, int len) {
+ setSPIRate();
+ select();
+ while(len--) {
+ writeByte(value);
+ }
+ waitFully();
+ release();
+ }
+
+ // A full cycle of writing a raw block of data out, including select, release, and waiting
+ template <class D> void writeBytes(register uint8_t *data, int len) {
+ setSPIRate();
+ uint8_t *end = data + len;
+ select();
+ // could be optimized to write 16bit words out instead of 8bit bytes
+ while(data != end) {
+ writeByte(D::adjust(*data++));
+ }
+ D::postBlock(len);
+ waitFully();
+ release();
+ }
+
+ void writeBytes(register uint8_t *data, int len) { writeBytes<DATA_NOP>(data, len); }
+
+
+ template <uint8_t FLAGS, class D, EOrder RGB_ORDER> void writePixels(PixelController<RGB_ORDER> pixels) {
+ int len = pixels.mLen;
+
+ select();
+ while(pixels.has(1)) {
+ if(FLAGS & FLAG_START_BIT) {
+ writeBit<0>(1);
+ writeByte(D::adjust(pixels.loadAndScale0()));
+ writeByte(D::adjust(pixels.loadAndScale1()));
+ writeByte(D::adjust(pixels.loadAndScale2()));
+ } else {
+ writeByte(D::adjust(pixels.loadAndScale0()));
+ writeByte(D::adjust(pixels.loadAndScale1()));
+ writeByte(D::adjust(pixels.loadAndScale2()));
+ }
+
+ pixels.advanceData();
+ pixels.stepDithering();
+ }
+ D::postBlock(len);
+ release();
+ }
+
+};
+
+FASTLED_NAMESPACE_END
+
+#endif
diff --git a/Библиотеки/FastLED-master/platforms/arm/kl26/led_sysdefs_arm_kl26.h b/Библиотеки/FastLED-master/platforms/arm/kl26/led_sysdefs_arm_kl26.h
new file mode 100644
index 0000000..466d729
--- /dev/null
+++ b/Библиотеки/FastLED-master/platforms/arm/kl26/led_sysdefs_arm_kl26.h
@@ -0,0 +1,47 @@
+#ifndef __INC_LED_SYSDEFS_ARM_KL26_H
+#define __INC_LED_SYSDEFS_ARM_KL26_H
+
+#define FASTLED_TEENSYLC
+#define FASTLED_ARM
+#define FASTLED_ARM_M0_PLUS
+
+#ifndef INTERRUPT_THRESHOLD
+#define INTERRUPT_THRESHOLD 1
+#endif
+
+#define FASTLED_SPI_BYTE_ONLY
+
+// Default to allowing interrupts
+#ifndef FASTLED_ALLOW_INTERRUPTS
+#define FASTLED_ALLOW_INTERRUPTS 1
+#endif
+
+#if FASTLED_ALLOW_INTERRUPTS == 1
+#define FASTLED_ACCURATE_CLOCK
+#endif
+
+#if (F_CPU == 96000000)
+#define CLK_DBL 1
+#endif
+
+// Get some system include files
+#include <avr/io.h>
+#include <avr/interrupt.h> // for cli/se definitions
+
+// Define the register types
+#if defined(ARDUINO) // && ARDUINO < 150
+typedef volatile uint8_t RoReg; /**< Read only 8-bit register (volatile const unsigned int) */
+typedef volatile uint8_t RwReg; /**< Read-Write 8-bit register (volatile unsigned int) */
+#endif
+
+extern volatile uint32_t systick_millis_count;
+# define MS_COUNTER systick_millis_count
+
+// Default to using PROGMEM since TEENSYLC provides it
+// even though all it does is ignore it. Just being
+// conservative here in case TEENSYLC changes.
+#ifndef FASTLED_USE_PROGMEM
+#define FASTLED_USE_PROGMEM 1
+#endif
+
+#endif
diff --git a/Библиотеки/FastLED-master/platforms/arm/nrf51/clockless_arm_nrf51.h b/Библиотеки/FastLED-master/platforms/arm/nrf51/clockless_arm_nrf51.h
new file mode 100644
index 0000000..da81e9f
--- /dev/null
+++ b/Библиотеки/FastLED-master/platforms/arm/nrf51/clockless_arm_nrf51.h
@@ -0,0 +1,83 @@
+#ifndef __INC_CLOCKLESS_ARM_NRF51
+#define __INC_CLOCKLESS_ARM_NRF51
+
+#if defined(NRF51)
+
+#include "nrf51_bitfields.h"
+#define FASTLED_HAS_CLOCKLESS 1
+
+#if (FASTLED_ALLOW_INTERRUPTS==1)
+#define SEI_CHK LED_TIMER->CC[0] = (WAIT_TIME * (F_CPU/1000000)); LED_TIMER->TASKS_CLEAR; LED_TIMER->EVENTS_COMPARE[0] = 0;
+#define CLI_CHK cli(); if(LED_TIMER->EVENTS_COMPARE[0]) { LED_TIMER->TASKS_STOP = 1; return 0; }
+#define INNER_SEI sei();
+#else
+#define SEI_CHK
+#define CLI_CHK
+#define INNER_SEI delaycycles<1>();
+#endif
+
+
+#include "platforms/arm/common/m0clockless.h"
+template <uint8_t DATA_PIN, int T1, int T2, int T3, EOrder RGB_ORDER = RGB, int XTRA0 = 0, bool FLIP = false, int WAIT_TIME = 75>
+class ClocklessController : public CPixelLEDController<RGB_ORDER> {
+ typedef typename FastPinBB<DATA_PIN>::port_ptr_t data_ptr_t;
+ typedef typename FastPinBB<DATA_PIN>::port_t data_t;
+
+ data_t mPinMask;
+ data_ptr_t mPort;
+ CMinWait<WAIT_TIME> mWait;
+public:
+ virtual void init() {
+ FastPinBB<DATA_PIN>::setOutput();
+ mPinMask = FastPinBB<DATA_PIN>::mask();
+ mPort = FastPinBB<DATA_PIN>::port();
+ }
+
+ virtual uint16_t getMaxRefreshRate() const { return 400; }
+
+ virtual void showPixels(PixelController<RGB_ORDER> & pixels) {
+ mWait.wait();
+ cli();
+ if(!showRGBInternal(pixels)) {
+ sei(); delayMicroseconds(WAIT_TIME); cli();
+ showRGBInternal(pixels);
+ }
+ sei();
+ mWait.mark();
+ }
+
+ // This method is made static to force making register Y available to use for data on AVR - if the method is non-static, then
+ // gcc will use register Y for the this pointer.
+ static uint32_t showRGBInternal(PixelController<RGB_ORDER> pixels) {
+ struct M0ClocklessData data;
+ data.d[0] = pixels.d[0];
+ data.d[1] = pixels.d[1];
+ data.d[2] = pixels.d[2];
+ data.s[0] = pixels.mScale[0];
+ data.s[1] = pixels.mScale[1];
+ data.s[2] = pixels.mScale[2];
+ data.e[0] = pixels.e[0];
+ data.e[1] = pixels.e[1];
+ data.e[2] = pixels.e[2];
+ data.adj = pixels.mAdvance;
+
+ typename FastPin<DATA_PIN>::port_ptr_t portBase = FastPin<DATA_PIN>::port();
+
+ // timer mode w/prescaler of 0
+ LED_TIMER->MODE = TIMER_MODE_MODE_Timer;
+ LED_TIMER->PRESCALER = 0;
+ LED_TIMER->EVENTS_COMPARE[0] = 0;
+ LED_TIMER->BITMODE = TIMER_BITMODE_BITMODE_16Bit;
+ LED_TIMER->SHORTS = TIMER_SHORTS_COMPARE0_CLEAR_Msk;
+ LED_TIMER->TASKS_START = 1;
+
+ int ret = showLedData<4,8,T1,T2,T3,RGB_ORDER,WAIT_TIME>(portBase, FastPin<DATA_PIN>::mask(), pixels.mData, pixels.mLen, &data);
+
+ LED_TIMER->TASKS_STOP = 1;
+ return ret; // 0x00FFFFFF - _VAL;
+ }
+};
+
+
+#endif // NRF51
+#endif // __INC_CLOCKLESS_ARM_NRF51
diff --git a/Библиотеки/FastLED-master/platforms/arm/nrf51/fastled_arm_nrf51.h b/Библиотеки/FastLED-master/platforms/arm/nrf51/fastled_arm_nrf51.h
new file mode 100644
index 0000000..bfdefc3
--- /dev/null
+++ b/Библиотеки/FastLED-master/platforms/arm/nrf51/fastled_arm_nrf51.h
@@ -0,0 +1,11 @@
+#ifndef __INC_FASTLED_ARM_NRF51_H
+#define __INC_FASTLED_ARM_NRF51_H
+
+// Include the k20 headers
+#include "bitswap.h"
+#include "fastled_delay.h"
+#include "fastpin_arm_nrf51.h"
+#include "fastspi_arm_nrf51.h"
+#include "clockless_arm_nrf51.h"
+
+#endif
diff --git a/Библиотеки/FastLED-master/platforms/arm/nrf51/fastpin_arm_nrf51.h b/Библиотеки/FastLED-master/platforms/arm/nrf51/fastpin_arm_nrf51.h
new file mode 100644
index 0000000..4125f9a
--- /dev/null
+++ b/Библиотеки/FastLED-master/platforms/arm/nrf51/fastpin_arm_nrf51.h
@@ -0,0 +1,119 @@
+#ifndef __FASTPIN_ARM_NRF51_H
+#define __FASTPIN_ARM_NRF51_H
+
+#if defined(NRF51)
+/// Template definition for teensy 3.0 style ARM pins, providing direct access to the various GPIO registers. Note that this
+/// uses the full port GPIO registers. In theory, in some way, bit-band register access -should- be faster, however I have found
+/// that something about the way gcc does register allocation results in the bit-band code being slower. It will need more fine tuning.
+/// The registers are data output, set output, clear output, toggle output, input, and direction
+#if 0
+template<uint8_t PIN, uint32_t _MASK, typename _DIRSET, typename _DIRCLR, typename _OUTSET, typename _OUTCLR, typename _OUT> class _ARMPIN {
+public:
+ typedef volatile uint32_t * port_ptr_t;
+ typedef uint32_t port_t;
+
+ inline static void setOutput() { _DIRSET::r() = _MASK; }
+ inline static void setInput() { _DIRCLR::r() = _MASK; }
+
+ inline static void hi() __attribute__ ((always_inline)) { _OUTSET::r() = _MASK; }
+ inline static void lo() __attribute__ ((always_inline)) { _OUTCLR::r() = _MASK; }
+ inline static void set(register port_t val) __attribute__ ((always_inline)) { _OUT::r() = val; }
+
+ inline static void strobe() __attribute__ ((always_inline)) { toggle(); toggle(); }
+
+ inline static void toggle() __attribute__ ((always_inline)) { _OUT::r() ^= _MASK; }
+
+ inline static void hi(register port_ptr_t port) __attribute__ ((always_inline)) { hi(); }
+ inline static void lo(register port_ptr_t port) __attribute__ ((always_inline)) { lo(); }
+ inline static void fastset(register port_ptr_t port, register port_t val) __attribute__ ((always_inline)) { *port = val; }
+
+ inline static port_t hival() __attribute__ ((always_inline)) { return _OUT::r() | _MASK; }
+ inline static port_t loval() __attribute__ ((always_inline)) { return _OUT::r() & ~_MASK; }
+ inline static port_ptr_t port() __attribute__ ((always_inline)) { return &_OUT::r(); }
+ inline static port_t mask() __attribute__ ((always_inline)) { return _MASK; }
+};
+
+#define ADDR(X) *(volatile uint32_t*)X
+#define NR_GPIO_ADDR(base,offset) (*(volatile uint32_t *))((uint32_t)(base + offset))
+#define NR_DIRSET ADDR(0x50000518UL) // NR_GPIO_ADDR(NRF_GPIO_BASE, 0x518)
+#define NR_DIRCLR ADDR(0x5000051CUL) // NR_GPIO_ADDR(NRF_GPIO_BASE, 0x51C)
+#define NR_OUTSET ADDR(0x50000508UL) // NR_GPIO_ADDR(NRF_GPIO_BASE, 0x508)
+#define NR_OUTCLR ADDR(0x5000050CUL) // NR_GPIO_ADDR(NRF_GPIO_BASE, 0x50C)
+#define NR_OUT ADDR(0x50000504UL) // NR_GPIO_ADDR(NRF_GPIO_BASE, 0x504)
+
+#define _RD32_NRF(T) struct __gen_struct_ ## T { static __attribute__((always_inline)) inline reg32_t r() { return T; }};
+
+_RD32_NRF(NR_DIRSET);
+_RD32_NRF(NR_DIRCLR);
+_RD32_NRF(NR_OUTSET);
+_RD32_NRF(NR_OUTCLR);
+_RD32_NRF(NR_OUT);
+
+#define _DEFPIN_ARM(PIN) template<> class FastPin<PIN> : public _ARMPIN<PIN, 1 << PIN, \
+ _R(NR_DIRSET), _R(NR_DIRCLR), _R(NR_OUTSET), _R(NR_OUTCLR), _R(NR_OUT)> {};
+#else
+
+typedef struct { /*!< GPIO Structure */
+ // __I uint32_t RESERVED0[321];
+ __IO uint32_t OUT; /*!< Write GPIO port. */
+ __IO uint32_t OUTSET; /*!< Set individual bits in GPIO port. */
+ __IO uint32_t OUTCLR; /*!< Clear individual bits in GPIO port. */
+ __I uint32_t IN; /*!< Read GPIO port. */
+ __IO uint32_t DIR; /*!< Direction of GPIO pins. */
+ __IO uint32_t DIRSET; /*!< DIR set register. */
+ __IO uint32_t DIRCLR; /*!< DIR clear register. */
+ __I uint32_t RESERVED1[120];
+ __IO uint32_t PIN_CNF[32]; /*!< Configuration of GPIO pins. */
+} FL_NRF_GPIO_Type;
+
+#define FL_NRF_GPIO_BASE 0x50000504UL
+#define FL_NRF_GPIO ((FL_NRF_GPIO_Type *) FL_NRF_GPIO_BASE)
+
+template<uint8_t PIN, uint32_t _MASK> class _ARMPIN {
+public:
+ typedef volatile uint32_t * port_ptr_t;
+ typedef uint32_t port_t;
+
+ inline static void setOutput() { FL_NRF_GPIO->DIRSET = _MASK; }
+ inline static void setInput() { FL_NRF_GPIO->DIRCLR = _MASK; }
+
+ inline static void hi() __attribute__ ((always_inline)) { FL_NRF_GPIO->OUTSET = _MASK; }
+ inline static void lo() __attribute__ ((always_inline)) { FL_NRF_GPIO->OUTCLR= _MASK; }
+ inline static void set(register port_t val) __attribute__ ((always_inline)) { FL_NRF_GPIO->OUT = val; }
+
+ inline static void strobe() __attribute__ ((always_inline)) { toggle(); toggle(); }
+
+ inline static void toggle() __attribute__ ((always_inline)) { FL_NRF_GPIO->OUT ^= _MASK; }
+
+ inline static void hi(register port_ptr_t port) __attribute__ ((always_inline)) { hi(); }
+ inline static void lo(register port_ptr_t port) __attribute__ ((always_inline)) { lo(); }
+ inline static void fastset(register port_ptr_t port, register port_t val) __attribute__ ((always_inline)) { *port = val; }
+
+ inline static port_t hival() __attribute__ ((always_inline)) { return FL_NRF_GPIO->OUT | _MASK; }
+ inline static port_t loval() __attribute__ ((always_inline)) { return FL_NRF_GPIO->OUT & ~_MASK; }
+ inline static port_ptr_t port() __attribute__ ((always_inline)) { return &FL_NRF_GPIO->OUT; }
+ inline static port_t mask() __attribute__ ((always_inline)) { return _MASK; }
+
+ inline static bool isset() __attribute__ ((always_inline)) { return (FL_NRF_GPIO->IN & _MASK) != 0; }
+};
+
+
+#define _DEFPIN_ARM(PIN) template<> class FastPin<PIN> : public _ARMPIN<PIN, 1 << PIN> {};
+#endif
+
+// Actual pin definitions
+#define MAX_PIN 31
+_DEFPIN_ARM(0); _DEFPIN_ARM(1); _DEFPIN_ARM(2); _DEFPIN_ARM(3);
+_DEFPIN_ARM(4); _DEFPIN_ARM(5); _DEFPIN_ARM(6); _DEFPIN_ARM(7);
+_DEFPIN_ARM(8); _DEFPIN_ARM(9); _DEFPIN_ARM(10); _DEFPIN_ARM(11);
+_DEFPIN_ARM(12); _DEFPIN_ARM(13); _DEFPIN_ARM(14); _DEFPIN_ARM(15);
+_DEFPIN_ARM(16); _DEFPIN_ARM(17); _DEFPIN_ARM(18); _DEFPIN_ARM(19);
+_DEFPIN_ARM(20); _DEFPIN_ARM(21); _DEFPIN_ARM(22); _DEFPIN_ARM(23);
+_DEFPIN_ARM(24); _DEFPIN_ARM(25); _DEFPIN_ARM(26); _DEFPIN_ARM(27);
+_DEFPIN_ARM(28); _DEFPIN_ARM(29); _DEFPIN_ARM(30); _DEFPIN_ARM(31);
+
+#define HAS_HARDWARE_PIN_SUPPORT
+
+#endif
+
+#endif
diff --git a/Библиотеки/FastLED-master/platforms/arm/nrf51/fastspi_arm_nrf51.h b/Библиотеки/FastLED-master/platforms/arm/nrf51/fastspi_arm_nrf51.h
new file mode 100644
index 0000000..539fd65
--- /dev/null
+++ b/Библиотеки/FastLED-master/platforms/arm/nrf51/fastspi_arm_nrf51.h
@@ -0,0 +1,150 @@
+#ifndef __INC_FASTSPI_NRF_H
+#define __INC_FASTSPI_NRF_H
+
+#ifdef NRF51
+
+#ifndef FASTLED_FORCE_SOFTWARE_SPI
+#define FASTLED_ALL_PINS_HARDWARE_SPI
+
+// A nop/stub class, mostly to show the SPI methods that are needed/used by the various SPI chipset implementations. Should
+// be used as a definition for the set of methods that the spi implementation classes should use (since C++ doesn't support the
+// idea of interfaces - it's possible this could be done with virtual classes, need to decide if i want that overhead)
+template <uint8_t _DATA_PIN, uint8_t _CLOCK_PIN, uint8_t _SPI_CLOCK_DIVIDER>
+class NRF51SPIOutput {
+
+ struct saveData {
+ uint32_t sck;
+ uint32_t mosi;
+ uint32_t miso;
+ uint32_t freq;
+ uint32_t enable;
+ } mSavedData;
+
+ void saveSPIData() {
+ mSavedData.sck = NRF_SPI0->PSELSCK;
+ mSavedData.mosi = NRF_SPI0->PSELMOSI;
+ mSavedData.miso = NRF_SPI0->PSELMISO;
+ mSavedData.freq = NRF_SPI0->FREQUENCY;
+ mSavedData.enable = NRF_SPI0->ENABLE;
+ }
+
+ void restoreSPIData() {
+ NRF_SPI0->PSELSCK = mSavedData.sck;
+ NRF_SPI0->PSELMOSI = mSavedData.mosi;
+ NRF_SPI0->PSELMISO = mSavedData.miso;
+ NRF_SPI0->FREQUENCY = mSavedData.freq;
+ mSavedData.enable = NRF_SPI0->ENABLE;
+ }
+
+public:
+ NRF51SPIOutput() { FastPin<_DATA_PIN>::setOutput(); FastPin<_CLOCK_PIN>::setOutput(); }
+ NRF51SPIOutput(Selectable *pSelect) { FastPin<_DATA_PIN>::setOutput(); FastPin<_CLOCK_PIN>::setOutput(); }
+
+ // set the object representing the selectable
+ void setSelect(Selectable *pSelect) { /* TODO */ }
+
+ // initialize the SPI subssytem
+ void init() {
+ FastPin<_DATA_PIN>::setOutput();
+ FastPin<_CLOCK_PIN>::setOutput();
+ NRF_SPI0->PSELSCK = _CLOCK_PIN;
+ NRF_SPI0->PSELMOSI = _DATA_PIN;
+ NRF_SPI0->PSELMISO = 0xFFFFFFFF;
+ NRF_SPI0->FREQUENCY = 0x80000000;
+ NRF_SPI0->ENABLE = 1;
+ NRF_SPI0->EVENTS_READY = 0;
+ }
+
+ // latch the CS select
+ void select() { saveSPIData(); init(); }
+
+ // release the CS select
+ void release() { shouldWait(); restoreSPIData(); }
+
+ static bool shouldWait(bool wait = false) __attribute__((always_inline)) __attribute__((always_inline)) {
+ // static bool sWait=false;
+ // bool oldWait = sWait;
+ // sWait = wait;
+ // never going to bother with waiting since we're always running the spi clock at max speed on the rfduino
+ // TODO: When we set clock rate, implement/fix waiting properly, otherwise the world hangs up
+ return false;
+ }
+
+ // wait until all queued up data has been written
+ static void waitFully() __attribute__((always_inline)){ if(shouldWait()) { while(NRF_SPI0->EVENTS_READY==0); } NRF_SPI0->INTENCLR; }
+ static void wait() __attribute__((always_inline)){ if(shouldWait()) { while(NRF_SPI0->EVENTS_READY==0); } NRF_SPI0->INTENCLR; }
+
+ // write a byte out via SPI (returns immediately on writing register)
+ static void writeByte(uint8_t b) __attribute__((always_inline)) { wait(); NRF_SPI0->TXD = b; NRF_SPI0->INTENCLR; shouldWait(true); }
+
+ // write a word out via SPI (returns immediately on writing register)
+ static void writeWord(uint16_t w) __attribute__((always_inline)){ writeByte(w>>8); writeByte(w & 0xFF); }
+
+ // A raw set of writing byte values, assumes setup/init/waiting done elsewhere (static for use by adjustment classes)
+ static void writeBytesValueRaw(uint8_t value, int len) { while(len--) { writeByte(value); } }
+
+ // A full cycle of writing a value for len bytes, including select, release, and waiting
+ void writeBytesValue(uint8_t value, int len) {
+ select();
+ while(len--) {
+ writeByte(value);
+ }
+ waitFully();
+ release();
+ }
+
+ // A full cycle of writing a raw block of data out, including select, release, and waiting
+ template<class D> void writeBytes(uint8_t *data, int len) {
+ uint8_t *end = data + len;
+ select();
+ while(data != end) {
+ writeByte(D::adjust(*data++));
+ }
+ D::postBlock(len);
+ waitFully();
+ release();
+ }
+
+ void writeBytes(uint8_t *data, int len) {
+ writeBytes<DATA_NOP>(data, len);
+ }
+
+ // write a single bit out, which bit from the passed in byte is determined by template parameter
+ template <uint8_t BIT> inline static void writeBit(uint8_t b) {
+ waitFully();
+ NRF_SPI0->ENABLE = 0;
+ if(b & 1<<BIT) {
+ FastPin<_DATA_PIN>::hi();
+ } else {
+ FastPin<_DATA_PIN>::lo();
+ }
+ FastPin<_CLOCK_PIN>::toggle();
+ FastPin<_CLOCK_PIN>::toggle();
+ NRF_SPI0->ENABLE = 1;
+ }
+
+ template <uint8_t FLAGS, class D, EOrder RGB_ORDER> void writePixels(PixelController<RGB_ORDER> pixels) {
+ select();
+ int len = pixels.mLen;
+ while(pixels.has(1)) {
+ if(FLAGS & FLAG_START_BIT) {
+ writeBit<0>(1);
+ }
+ writeByte(D::adjust(pixels.loadAndScale0()));
+ writeByte(D::adjust(pixels.loadAndScale1()));
+ writeByte(D::adjust(pixels.loadAndScale2()));
+
+ pixels.advanceData();
+ pixels.stepDithering();
+ }
+ D::postBlock(len);
+ waitFully();
+ release();
+ }
+
+};
+
+#endif
+#endif
+
+#endif
diff --git a/Библиотеки/FastLED-master/platforms/arm/nrf51/led_sysdefs_arm_nrf51.h b/Библиотеки/FastLED-master/platforms/arm/nrf51/led_sysdefs_arm_nrf51.h
new file mode 100644
index 0000000..7a83d11
--- /dev/null
+++ b/Библиотеки/FastLED-master/platforms/arm/nrf51/led_sysdefs_arm_nrf51.h
@@ -0,0 +1,46 @@
+#ifndef __LED_SYSDEFS_ARM_NRF51
+#define __LED_SYSDEFS_ARM_NRF51
+
+#ifndef NRF51
+#define NRF51
+#endif
+
+#define LED_TIMER NRF_TIMER1
+#define FASTLED_NO_PINMAP
+#define FASTLED_HAS_CLOCKLESS
+
+#define FASTLED_SPI_BYTE_ONLY
+
+#define FASTLED_ARM
+#define FASTLED_ARM_M0
+
+#ifndef F_CPU
+#define F_CPU 16000000
+#endif
+
+#include <stdint.h>
+#include "nrf51.h"
+#include "core_cm0.h"
+
+typedef volatile uint32_t RoReg;
+typedef volatile uint32_t RwReg;
+typedef uint32_t prog_uint32_t;
+typedef uint8_t boolean;
+
+#define PROGMEM
+#define NO_PROGMEM
+#define NEED_CXX_BITS
+
+// Default to NOT using PROGMEM here
+#ifndef FASTLED_USE_PROGMEM
+#define FASTLED_USE_PROGMEM 0
+#endif
+
+#ifndef FASTLED_ALLOW_INTERRUPTS
+#define FASTLED_ALLOW_INTERRUPTS 1
+#endif
+
+#define cli() __disable_irq();
+#define sei() __enable_irq();
+
+#endif
diff --git a/Библиотеки/FastLED-master/platforms/arm/sam/clockless_arm_sam.h b/Библиотеки/FastLED-master/platforms/arm/sam/clockless_arm_sam.h
new file mode 100644
index 0000000..0fc621d
--- /dev/null
+++ b/Библиотеки/FastLED-master/platforms/arm/sam/clockless_arm_sam.h
@@ -0,0 +1,120 @@
+#ifndef __INC_CLOCKLESS_ARM_SAM_H
+#define __INC_CLOCKLESS_ARM_SAM_H
+
+FASTLED_NAMESPACE_BEGIN
+
+// Definition for a single channel clockless controller for the sam family of arm chips, like that used in the due and rfduino
+// See clockless.h for detailed info on how the template parameters are used.
+
+#if defined(__SAM3X8E__)
+
+
+#define TADJUST 0
+#define TOTAL ( (T1+TADJUST) + (T2+TADJUST) + (T3+TADJUST) )
+
+#define FASTLED_HAS_CLOCKLESS 1
+
+template <uint8_t DATA_PIN, int T1, int T2, int T3, EOrder RGB_ORDER = RGB, int XTRA0 = 0, bool FLIP = false, int WAIT_TIME = 50>
+class ClocklessController : public CPixelLEDController<RGB_ORDER> {
+ typedef typename FastPinBB<DATA_PIN>::port_ptr_t data_ptr_t;
+ typedef typename FastPinBB<DATA_PIN>::port_t data_t;
+
+ data_t mPinMask;
+ data_ptr_t mPort;
+ CMinWait<WAIT_TIME> mWait;
+public:
+ virtual void init() {
+ FastPinBB<DATA_PIN>::setOutput();
+ mPinMask = FastPinBB<DATA_PIN>::mask();
+ mPort = FastPinBB<DATA_PIN>::port();
+ }
+
+ virtual uint16_t getMaxRefreshRate() const { return 400; }
+
+protected:
+
+ virtual void showPixels(PixelController<RGB_ORDER> & pixels) {
+ mWait.wait();
+ if(!showRGBInternal(pixels)) {
+ sei(); delayMicroseconds(WAIT_TIME); cli();
+ showRGBInternal(pixels);
+ }
+ mWait.mark();
+ }
+
+ template<int BITS> __attribute__ ((always_inline)) inline static void writeBits(register uint32_t & next_mark, register data_ptr_t port, register uint8_t & b) {
+ // Make sure we don't slot into a wrapping spot, this will delay up to 12.5µs for WS2812
+ // bool bShift=0;
+ // while(VAL < (TOTAL*10)) { bShift=true; }
+ // if(bShift) { next_mark = (VAL-TOTAL); };
+
+ for(register uint32_t i = BITS; i > 0; i--) {
+ // wait to start the bit, then set the pin high
+ while(DUE_TIMER_VAL < next_mark);
+ next_mark = (DUE_TIMER_VAL+TOTAL);
+ *port = 1;
+
+ // how long we want to wait next depends on whether or not our bit is set to 1 or 0
+ if(b&0x80) {
+ // we're a 1, wait until there's less than T3 clocks left
+ while((next_mark - DUE_TIMER_VAL) > (T3));
+ } else {
+ // we're a 0, wait until there's less than (T2+T3+slop) clocks left in this bit
+ while((next_mark - DUE_TIMER_VAL) > (T2+T3+6+TADJUST+TADJUST));
+ }
+ *port=0;
+ b <<= 1;
+ }
+ }
+
+#define FORCE_REFERENCE(var) asm volatile( "" : : "r" (var) )
+ // This method is made static to force making register Y available to use for data on AVR - if the method is non-static, then
+ // gcc will use register Y for the this pointer.
+ static uint32_t showRGBInternal(PixelController<RGB_ORDER> pixels) {
+ // Setup and start the clock
+ TC_Configure(DUE_TIMER,DUE_TIMER_CHANNEL,TC_CMR_TCCLKS_TIMER_CLOCK1);
+ pmc_enable_periph_clk(DUE_TIMER_ID);
+ TC_Start(DUE_TIMER,DUE_TIMER_CHANNEL);
+
+ register data_ptr_t port asm("r7") = FastPinBB<DATA_PIN>::port(); FORCE_REFERENCE(port);
+ *port = 0;
+
+ // Setup the pixel controller and load/scale the first byte
+ pixels.preStepFirstByteDithering();
+ uint8_t b = pixels.loadAndScale0();
+
+ uint32_t next_mark = (DUE_TIMER_VAL + (TOTAL));
+ while(pixels.has(1)) {
+ pixels.stepDithering();
+
+ #if (FASTLED_ALLOW_INTERRUPTS == 1)
+ cli();
+ if(DUE_TIMER_VAL > next_mark) {
+ if((DUE_TIMER_VAL - next_mark) > ((WAIT_TIME-INTERRUPT_THRESHOLD)*CLKS_PER_US)) { sei(); TC_Stop(DUE_TIMER,DUE_TIMER_CHANNEL); return 0; }
+ }
+ #endif
+
+ writeBits<8+XTRA0>(next_mark, port, b);
+
+ b = pixels.loadAndScale1();
+ writeBits<8+XTRA0>(next_mark, port,b);
+
+ b = pixels.loadAndScale2();
+ writeBits<8+XTRA0>(next_mark, port,b);
+
+ b = pixels.advanceAndLoadAndScale0();
+ #if (FASTLED_ALLOW_INTERRUPTS == 1)
+ sei();
+ #endif
+ };
+
+ TC_Stop(DUE_TIMER,DUE_TIMER_CHANNEL);
+ return DUE_TIMER_VAL;
+ }
+};
+
+#endif
+
+FASTLED_NAMESPACE_END
+
+#endif
diff --git a/Библиотеки/FastLED-master/platforms/arm/sam/clockless_block_arm_sam.h b/Библиотеки/FastLED-master/platforms/arm/sam/clockless_block_arm_sam.h
new file mode 100644
index 0000000..355f945
--- /dev/null
+++ b/Библиотеки/FastLED-master/platforms/arm/sam/clockless_block_arm_sam.h
@@ -0,0 +1,184 @@
+ #ifndef __INC_BLOCK_CLOCKLESS_H
+#define __INC_BLOCK_CLOCKLESS_H
+
+FASTLED_NAMESPACE_BEGIN
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// Base template for clockless controllers. These controllers have 3 control points in their cycle for each bit. The first point
+// is where the line is raised hi. The second pointsnt is where the line is dropped low for a zero. The third point is where the
+// line is dropped low for a one. T1, T2, and T3 correspond to the timings for those three in clock cycles.
+//
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+#if defined(__SAM3X8E__)
+#define PORT_MASK (((1<<LANES)-1) & ((FIRST_PIN==2) ? 0xFF : 0xFF))
+
+#define FASTLED_HAS_BLOCKLESS 1
+
+#define PORTD_FIRST_PIN 25
+#define PORTA_FIRST_PIN 69
+#define PORTB_FIRST_PIN 90
+
+typedef union {
+ uint8_t bytes[8];
+ uint32_t raw[2];
+} Lines;
+
+#define TADJUST 0
+#define TOTAL ( (T1+TADJUST) + (T2+TADJUST) + (T3+TADJUST) )
+#define T1_MARK (TOTAL - (T1+TADJUST))
+#define T2_MARK (T1_MARK - (T2+TADJUST))
+template <uint8_t LANES, int FIRST_PIN, int T1, int T2, int T3, EOrder RGB_ORDER = RGB, int XTRA0 = 0, bool FLIP = false, int WAIT_TIME = 50>
+class InlineBlockClocklessController : public CPixelLEDController<RGB_ORDER, LANES, PORT_MASK> {
+ typedef typename FastPin<FIRST_PIN>::port_ptr_t data_ptr_t;
+ typedef typename FastPin<FIRST_PIN>::port_t data_t;
+
+ data_t mPinMask;
+ data_ptr_t mPort;
+ CMinWait<WAIT_TIME> mWait;
+public:
+ virtual int size() { return CLEDController::size() * LANES; }
+ virtual void init() {
+ static_assert(LANES <= 8, "Maximum of 8 lanes for Due parallel controllers!");
+ if(FIRST_PIN == PORTA_FIRST_PIN) {
+ switch(LANES) {
+ case 8: FastPin<31>::setOutput();
+ case 7: FastPin<58>::setOutput();
+ case 6: FastPin<100>::setOutput();
+ case 5: FastPin<59>::setOutput();
+ case 4: FastPin<60>::setOutput();
+ case 3: FastPin<61>::setOutput();
+ case 2: FastPin<68>::setOutput();
+ case 1: FastPin<69>::setOutput();
+ }
+ } else if(FIRST_PIN == PORTD_FIRST_PIN) {
+ switch(LANES) {
+ case 8: FastPin<11>::setOutput();
+ case 7: FastPin<29>::setOutput();
+ case 6: FastPin<15>::setOutput();
+ case 5: FastPin<14>::setOutput();
+ case 4: FastPin<28>::setOutput();
+ case 3: FastPin<27>::setOutput();
+ case 2: FastPin<26>::setOutput();
+ case 1: FastPin<25>::setOutput();
+ }
+ } else if(FIRST_PIN == PORTB_FIRST_PIN) {
+ switch(LANES) {
+ case 8: FastPin<97>::setOutput();
+ case 7: FastPin<96>::setOutput();
+ case 6: FastPin<95>::setOutput();
+ case 5: FastPin<94>::setOutput();
+ case 4: FastPin<93>::setOutput();
+ case 3: FastPin<92>::setOutput();
+ case 2: FastPin<91>::setOutput();
+ case 1: FastPin<90>::setOutput();
+ }
+ }
+ mPinMask = FastPin<FIRST_PIN>::mask();
+ mPort = FastPin<FIRST_PIN>::port();
+ }
+
+ virtual uint16_t getMaxRefreshRate() const { return 400; }
+
+ virtual void showPixels(PixelController<RGB_ORDER, LANES, PORT_MASK> & pixels) {
+ mWait.wait();
+ showRGBInternal(pixels);
+ sei();
+ mWait.mark();
+ }
+
+ static uint32_t showRGBInternal(PixelController<RGB_ORDER, LANES, PORT_MASK> &allpixels) {
+ // Serial.println("Entering show");
+
+ int nLeds = allpixels.mLen;
+
+ // Setup the pixel controller and load/scale the first byte
+ Lines b0,b1,b2;
+
+ allpixels.preStepFirstByteDithering();
+ for(uint8_t i = 0; i < LANES; i++) {
+ b0.bytes[i] = allpixels.loadAndScale0(i);
+ }
+
+ // Setup and start the clock
+ TC_Configure(DUE_TIMER,DUE_TIMER_CHANNEL,TC_CMR_TCCLKS_TIMER_CLOCK1);
+ pmc_enable_periph_clk(DUE_TIMER_ID);
+ TC_Start(DUE_TIMER,DUE_TIMER_CHANNEL);
+
+ #if (FASTLED_ALLOW_INTERRUPTS == 1)
+ cli();
+ #endif
+ uint32_t next_mark = (DUE_TIMER_VAL + (TOTAL));
+ while(nLeds--) {
+ allpixels.stepDithering();
+ #if (FASTLED_ALLOW_INTERRUPTS == 1)
+ cli();
+ if(DUE_TIMER_VAL > next_mark) {
+ if((DUE_TIMER_VAL - next_mark) > ((WAIT_TIME-INTERRUPT_THRESHOLD)*CLKS_PER_US)) {
+ sei(); TC_Stop(DUE_TIMER,DUE_TIMER_CHANNEL); return DUE_TIMER_VAL;
+ }
+ }
+ #endif
+
+ // Write first byte, read next byte
+ writeBits<8+XTRA0,1>(next_mark, b0, b1, allpixels);
+
+ // Write second byte, read 3rd byte
+ writeBits<8+XTRA0,2>(next_mark, b1, b2, allpixels);
+
+ allpixels.advanceData();
+ // Write third byte
+ writeBits<8+XTRA0,0>(next_mark, b2, b0, allpixels);
+
+ #if (FASTLED_ALLOW_INTERRUPTS == 1)
+ sei();
+ #endif
+ }
+
+ return DUE_TIMER_VAL;
+ }
+
+ template<int BITS,int PX> __attribute__ ((always_inline)) inline static void writeBits(register uint32_t & next_mark, register Lines & b, Lines & b3, PixelController<RGB_ORDER,LANES, PORT_MASK> &pixels) { // , register uint32_t & b2) {
+ Lines b2;
+ transpose8x1(b.bytes,b2.bytes);
+
+ register uint8_t d = pixels.template getd<PX>(pixels);
+ register uint8_t scale = pixels.template getscale<PX>(pixels);
+
+ for(uint32_t i = 0; (i < LANES) && (i<8); i++) {
+ while(DUE_TIMER_VAL < next_mark);
+ next_mark = (DUE_TIMER_VAL+TOTAL);
+
+ *FastPin<FIRST_PIN>::sport() = PORT_MASK;
+
+ while((next_mark - DUE_TIMER_VAL) > (T2+T3+6));
+ *FastPin<FIRST_PIN>::cport() = (~b2.bytes[7-i]) & PORT_MASK;
+
+ while((next_mark - (DUE_TIMER_VAL)) > T3);
+ *FastPin<FIRST_PIN>::cport() = PORT_MASK;
+
+ b3.bytes[i] = pixels.template loadAndScale<PX>(pixels,i,d,scale);
+ }
+
+ for(uint32_t i = LANES; i < 8; i++) {
+ while(DUE_TIMER_VAL < next_mark);
+ next_mark = (DUE_TIMER_VAL+TOTAL);
+ *FastPin<FIRST_PIN>::sport() = PORT_MASK;
+
+ while((next_mark - DUE_TIMER_VAL) > (T2+T3+6));
+ *FastPin<FIRST_PIN>::cport() = (~b2.bytes[7-i]) & PORT_MASK;
+
+ while((next_mark - DUE_TIMER_VAL) > T3);
+ *FastPin<FIRST_PIN>::cport() = PORT_MASK;
+ }
+ }
+
+
+};
+
+#endif
+
+FASTLED_NAMESPACE_END
+
+#endif
diff --git a/Библиотеки/FastLED-master/platforms/arm/sam/fastled_arm_sam.h b/Библиотеки/FastLED-master/platforms/arm/sam/fastled_arm_sam.h
new file mode 100644
index 0000000..fd61c14
--- /dev/null
+++ b/Библиотеки/FastLED-master/platforms/arm/sam/fastled_arm_sam.h
@@ -0,0 +1,11 @@
+#ifndef __INC_FASTLED_ARM_SAM_H
+#define __INC_FASTLED_ARM_SAM_H
+
+// Include the sam headers
+#include "fastled_delay.h"
+#include "fastpin_arm_sam.h"
+#include "fastspi_arm_sam.h"
+#include "clockless_arm_sam.h"
+#include "clockless_block_arm_sam.h"
+
+#endif
diff --git a/Библиотеки/FastLED-master/platforms/arm/sam/fastpin_arm_sam.h b/Библиотеки/FastLED-master/platforms/arm/sam/fastpin_arm_sam.h
new file mode 100644
index 0000000..2bb7804
--- /dev/null
+++ b/Библиотеки/FastLED-master/platforms/arm/sam/fastpin_arm_sam.h
@@ -0,0 +1,137 @@
+#ifndef __INC_FASTPIN_ARM_SAM_H
+#define __INC_FASTPIN_ARM_SAM_H
+
+FASTLED_NAMESPACE_BEGIN
+
+#if defined(FASTLED_FORCE_SOFTWARE_PINS)
+#warning "Software pin support forced, pin access will be sloightly slower."
+#define NO_HARDWARE_PIN_SUPPORT
+#undef HAS_HARDWARE_PIN_SUPPORT
+
+#else
+
+
+/// Template definition for arduino due style ARM pins, providing direct access to the various GPIO registers. Note that this
+/// uses the full port GPIO registers. In theory, in some way, bit-band register access -should- be faster, however I have found
+/// that something about the way gcc does register allocation results in the bit-band code being slower. It will need more fine tuning.
+/// The registers are data register, set output register, clear output register, set data direction register
+template<uint8_t PIN, uint32_t _MASK, typename _PDOR, typename _PSOR, typename _PCOR, typename _PDDR> class _DUEPIN {
+public:
+ typedef volatile uint32_t * port_ptr_t;
+ typedef uint32_t port_t;
+
+ inline static void setOutput() { pinMode(PIN, OUTPUT); } // TODO: perform MUX config { _PDDR::r() |= _MASK; }
+ inline static void setInput() { pinMode(PIN, INPUT); } // TODO: preform MUX config { _PDDR::r() &= ~_MASK; }
+
+ inline static void hi() __attribute__ ((always_inline)) { _PSOR::r() = _MASK; }
+ inline static void lo() __attribute__ ((always_inline)) { _PCOR::r() = _MASK; }
+ inline static void set(register port_t val) __attribute__ ((always_inline)) { _PDOR::r() = val; }
+
+ inline static void strobe() __attribute__ ((always_inline)) { toggle(); toggle(); }
+
+ inline static void toggle() __attribute__ ((always_inline)) { _PDOR::r() ^= _MASK; }
+
+ inline static void hi(register port_ptr_t port) __attribute__ ((always_inline)) { hi(); }
+ inline static void lo(register port_ptr_t port) __attribute__ ((always_inline)) { lo(); }
+ inline static void fastset(register port_ptr_t port, register port_t val) __attribute__ ((always_inline)) { *port = val; }
+
+ inline static port_t hival() __attribute__ ((always_inline)) { return _PDOR::r() | _MASK; }
+ inline static port_t loval() __attribute__ ((always_inline)) { return _PDOR::r() & ~_MASK; }
+ inline static port_ptr_t port() __attribute__ ((always_inline)) { return &_PDOR::r(); }
+ inline static port_ptr_t sport() __attribute__ ((always_inline)) { return &_PSOR::r(); }
+ inline static port_ptr_t cport() __attribute__ ((always_inline)) { return &_PCOR::r(); }
+ inline static port_t mask() __attribute__ ((always_inline)) { return _MASK; }
+};
+
+
+/// Template definition for DUE style ARM pins using bit banding, providing direct access to the various GPIO registers. GCC
+/// does a poor job of optimizing around these accesses so they are not being used just yet.
+template<uint8_t PIN, uint32_t _BIT, typename _PDOR, typename _PSOR, typename _PCOR, typename _PDDR> class _DUEPIN_BITBAND {
+public:
+ typedef volatile uint32_t * port_ptr_t;
+ typedef uint32_t port_t;
+
+ inline static void setOutput() { pinMode(PIN, OUTPUT); } // TODO: perform MUX config { _PDDR::r() |= _MASK; }
+ inline static void setInput() { pinMode(PIN, INPUT); } // TODO: preform MUX config { _PDDR::r() &= ~_MASK; }
+
+ inline static void hi() __attribute__ ((always_inline)) { *_PDOR::template rx<_BIT>() = 1; }
+ inline static void lo() __attribute__ ((always_inline)) { *_PDOR::template rx<_BIT>() = 0; }
+ inline static void set(register port_t val) __attribute__ ((always_inline)) { *_PDOR::template rx<_BIT>() = val; }
+
+ inline static void strobe() __attribute__ ((always_inline)) { toggle(); toggle(); }
+
+ inline static void toggle() __attribute__ ((always_inline)) { *_PDOR::template rx<_BIT>() ^= 1; }
+
+ inline static void hi(register port_ptr_t port) __attribute__ ((always_inline)) { hi(); }
+ inline static void lo(register port_ptr_t port) __attribute__ ((always_inline)) { lo(); }
+ inline static void fastset(register port_ptr_t port, register port_t val) __attribute__ ((always_inline)) { *port = val; }
+
+ inline static port_t hival() __attribute__ ((always_inline)) { return 1; }
+ inline static port_t loval() __attribute__ ((always_inline)) { return 0; }
+ inline static port_ptr_t port() __attribute__ ((always_inline)) { return _PDOR::template rx<_BIT>(); }
+ inline static port_t mask() __attribute__ ((always_inline)) { return 1; }
+};
+
+#define GPIO_BITBAND_ADDR(reg, bit) (((uint32_t)&(reg) - 0x40000000) * 32 + (bit) * 4 + 0x42000000)
+#define GPIO_BITBAND_PTR(reg, bit) ((uint32_t *)GPIO_BITBAND_ADDR((reg), (bit)))
+
+#define _R(T) struct __gen_struct_ ## T
+#define _RD32(T) struct __gen_struct_ ## T { static __attribute__((always_inline)) inline reg32_t r() { return T; } \
+ template<int BIT> static __attribute__((always_inline)) inline ptr_reg32_t rx() { return GPIO_BITBAND_PTR(T, BIT); } };
+#define DUE_IO32(L) _RD32(REG_PIO ## L ## _ODSR); _RD32(REG_PIO ## L ## _SODR); _RD32(REG_PIO ## L ## _CODR); _RD32(REG_PIO ## L ## _OER);
+
+#define _DEFPIN_DUE(PIN, BIT, L) template<> class FastPin<PIN> : public _DUEPIN<PIN, 1 << BIT, _R(REG_PIO ## L ## _ODSR), _R(REG_PIO ## L ## _SODR), _R(REG_PIO ## L ## _CODR), \
+ _R(GPIO ## L ## _OER)> {}; \
+ template<> class FastPinBB<PIN> : public _DUEPIN_BITBAND<PIN, BIT, _R(REG_PIO ## L ## _ODSR), _R(REG_PIO ## L ## _SODR), _R(REG_PIO ## L ## _CODR), \
+ _R(GPIO ## L ## _OER)> {};
+
+#if defined(__SAM3X8E__)
+
+DUE_IO32(A);
+DUE_IO32(B);
+DUE_IO32(C);
+DUE_IO32(D);
+
+#define MAX_PIN 78
+_DEFPIN_DUE(0, 8, A); _DEFPIN_DUE(1, 9, A); _DEFPIN_DUE(2, 25, B); _DEFPIN_DUE(3, 28, C);
+_DEFPIN_DUE(4, 26, C); _DEFPIN_DUE(5, 25, C); _DEFPIN_DUE(6, 24, C); _DEFPIN_DUE(7, 23, C);
+_DEFPIN_DUE(8, 22, C); _DEFPIN_DUE(9, 21, C); _DEFPIN_DUE(10, 29, C); _DEFPIN_DUE(11, 7, D);
+_DEFPIN_DUE(12, 8, D); _DEFPIN_DUE(13, 27, B); _DEFPIN_DUE(14, 4, D); _DEFPIN_DUE(15, 5, D);
+_DEFPIN_DUE(16, 13, A); _DEFPIN_DUE(17, 12, A); _DEFPIN_DUE(18, 11, A); _DEFPIN_DUE(19, 10, A);
+_DEFPIN_DUE(20, 12, B); _DEFPIN_DUE(21, 13, B); _DEFPIN_DUE(22, 26, B); _DEFPIN_DUE(23, 14, A);
+_DEFPIN_DUE(24, 15, A); _DEFPIN_DUE(25, 0, D); _DEFPIN_DUE(26, 1, D); _DEFPIN_DUE(27, 2, D);
+_DEFPIN_DUE(28, 3, D); _DEFPIN_DUE(29, 6, D); _DEFPIN_DUE(30, 9, D); _DEFPIN_DUE(31, 7, A);
+_DEFPIN_DUE(32, 10, D); _DEFPIN_DUE(33, 1, C); _DEFPIN_DUE(34, 2, C); _DEFPIN_DUE(35, 3, C);
+_DEFPIN_DUE(36, 4, C); _DEFPIN_DUE(37, 5, C); _DEFPIN_DUE(38, 6, C); _DEFPIN_DUE(39, 7, C);
+_DEFPIN_DUE(40, 8, C); _DEFPIN_DUE(41, 9, C); _DEFPIN_DUE(42, 19, A); _DEFPIN_DUE(43, 20, A);
+_DEFPIN_DUE(44, 19, C); _DEFPIN_DUE(45, 18, C); _DEFPIN_DUE(46, 17, C); _DEFPIN_DUE(47, 16, C);
+_DEFPIN_DUE(48, 15, C); _DEFPIN_DUE(49, 14, C); _DEFPIN_DUE(50, 13, C); _DEFPIN_DUE(51, 12, C);
+_DEFPIN_DUE(52, 21, B); _DEFPIN_DUE(53, 14, B); _DEFPIN_DUE(54, 16, A); _DEFPIN_DUE(55, 24, A);
+_DEFPIN_DUE(56, 23, A); _DEFPIN_DUE(57, 22, A); _DEFPIN_DUE(58, 6, A); _DEFPIN_DUE(59, 4, A);
+_DEFPIN_DUE(60, 3, A); _DEFPIN_DUE(61, 2, A); _DEFPIN_DUE(62, 17, B); _DEFPIN_DUE(63, 18, B);
+_DEFPIN_DUE(64, 19, B); _DEFPIN_DUE(65, 20, B); _DEFPIN_DUE(66, 15, B); _DEFPIN_DUE(67, 16, B);
+_DEFPIN_DUE(68, 1, A); _DEFPIN_DUE(69, 0, A); _DEFPIN_DUE(70, 17, A); _DEFPIN_DUE(71, 18, A);
+_DEFPIN_DUE(72, 30, C); _DEFPIN_DUE(73, 21, A); _DEFPIN_DUE(74, 25, A); _DEFPIN_DUE(75, 26, A);
+_DEFPIN_DUE(76, 27, A); _DEFPIN_DUE(77, 28, A); _DEFPIN_DUE(78, 23, B);
+
+// digix pins
+_DEFPIN_DUE(90, 0, B); _DEFPIN_DUE(91, 1, B); _DEFPIN_DUE(92, 2, B); _DEFPIN_DUE(93, 3, B);
+_DEFPIN_DUE(94, 4, B); _DEFPIN_DUE(95, 5, B); _DEFPIN_DUE(96, 6, B); _DEFPIN_DUE(97, 7, B);
+_DEFPIN_DUE(98, 8, B); _DEFPIN_DUE(99, 9, B); _DEFPIN_DUE(100, 5, A); _DEFPIN_DUE(101, 22, B);
+_DEFPIN_DUE(102, 23, B); _DEFPIN_DUE(103, 24, B); _DEFPIN_DUE(104, 27, C); _DEFPIN_DUE(105, 20, C);
+_DEFPIN_DUE(106, 11, C); _DEFPIN_DUE(107, 10, C); _DEFPIN_DUE(108, 21, A); _DEFPIN_DUE(109, 30, C);
+_DEFPIN_DUE(110, 29, B); _DEFPIN_DUE(111, 30, B); _DEFPIN_DUE(112, 31, B); _DEFPIN_DUE(113, 28, B);
+
+#define SPI_DATA 75
+#define SPI_CLOCK 76
+#define ARM_HARDWARE_SPI
+#define HAS_HARDWARE_PIN_SUPPORT
+
+#endif
+
+#endif // FASTLED_FORCE_SOFTWARE_PINS
+
+FASTLED_NAMESPACE_END
+
+
+#endif // __INC_FASTPIN_ARM_SAM_H
diff --git a/Библиотеки/FastLED-master/platforms/arm/sam/fastspi_arm_sam.h b/Библиотеки/FastLED-master/platforms/arm/sam/fastspi_arm_sam.h
new file mode 100644
index 0000000..eb9abe4
--- /dev/null
+++ b/Библиотеки/FastLED-master/platforms/arm/sam/fastspi_arm_sam.h
@@ -0,0 +1,163 @@
+#ifndef __INC_FASTSPI_ARM_SAM_H
+#define __INC_FASTSPI_ARM_SAM_H
+
+FASTLED_NAMESPACE_BEGIN
+
+#if defined(__SAM3X8E__)
+#define m_SPI ((Spi*)SPI0)
+
+template <uint8_t _DATA_PIN, uint8_t _CLOCK_PIN, uint8_t _SPI_CLOCK_DIVIDER>
+class SAMHardwareSPIOutput {
+ Selectable *m_pSelect;
+
+ static inline void waitForEmpty() { while ((m_SPI->SPI_SR & SPI_SR_TDRE) == 0); }
+
+ void enableConfig() { m_SPI->SPI_WPMR &= ~SPI_WPMR_WPEN; }
+ void disableConfig() { m_SPI->SPI_WPMR |= SPI_WPMR_WPEN; }
+
+ void enableSPI() { m_SPI->SPI_CR = SPI_CR_SPIEN; }
+ void disableSPI() { m_SPI->SPI_CR = SPI_CR_SPIDIS; }
+ void resetSPI() { m_SPI->SPI_CR = SPI_CR_SWRST; }
+
+ static inline void readyTransferBits(register uint32_t bits) {
+ bits -= 8;
+ // don't change the number of transfer bits while data is still being transferred from TDR to the shift register
+ waitForEmpty();
+ m_SPI->SPI_CSR[0] = SPI_CSR_NCPHA | SPI_CSR_CSAAT | (bits << SPI_CSR_BITS_Pos) | SPI_CSR_DLYBCT(1) | SPI_CSR_SCBR(_SPI_CLOCK_DIVIDER);
+ }
+
+ template<int BITS> static inline void writeBits(uint16_t w) {
+ waitForEmpty();
+ m_SPI->SPI_TDR = (uint32_t)w | SPI_PCS(0);
+ }
+
+public:
+ SAMHardwareSPIOutput() { m_pSelect = NULL; }
+ SAMHardwareSPIOutput(Selectable *pSelect) { m_pSelect = pSelect; }
+
+ // set the object representing the selectable
+ void setSelect(Selectable *pSelect) { /* TODO */ }
+
+ // initialize the SPI subssytem
+ void init() {
+ // m_SPI = SPI0;
+
+ // set the output pins master out, master in, clock. Note doing this here because I still don't
+ // know how I want to expose this type of functionality in FastPin.
+ PIO_Configure(PIOA, PIO_PERIPH_A, FastPin<_DATA_PIN>::mask(), PIO_DEFAULT);
+ PIO_Configure(PIOA, PIO_PERIPH_A, FastPin<_DATA_PIN-1>::mask(), PIO_DEFAULT);
+ PIO_Configure(PIOA, PIO_PERIPH_A, FastPin<_CLOCK_PIN>::mask(), PIO_DEFAULT);
+
+ release();
+
+ // Configure the SPI clock, divider between 1-255
+ // SCBR = _SPI_CLOCK_DIVIDER
+ pmc_enable_periph_clk(ID_SPI0);
+ disableSPI();
+
+ // reset twice (what the sam code does, not sure why?)
+ resetSPI();
+ resetSPI();
+
+ // Configure SPI as master, enable
+ // Bits we want in MR: master, disable mode fault detection, variable peripheral select
+ m_SPI->SPI_MR = SPI_MR_MSTR | SPI_MR_MODFDIS | SPI_MR_PS;
+
+ enableSPI();
+
+ // Send everything out in 8 bit chunks, other sizes appear to work, poorly...
+ readyTransferBits(8);
+ }
+
+ // latch the CS select
+ void inline select() __attribute__((always_inline)) { if(m_pSelect != NULL) { m_pSelect->select(); } }
+
+ // release the CS select
+ void inline release() __attribute__((always_inline)) { if(m_pSelect != NULL) { m_pSelect->release(); } }
+
+ // wait until all queued up data has been written
+ void waitFully() { while((m_SPI->SPI_SR & SPI_SR_TXEMPTY) == 0); }
+
+ // write a byte out via SPI (returns immediately on writing register)
+ static void writeByte(uint8_t b) {
+ writeBits<8>(b);
+ }
+
+ // write a word out via SPI (returns immediately on writing register)
+ static void writeWord(uint16_t w) {
+ writeBits<16>(w);
+ }
+
+ // A raw set of writing byte values, assumes setup/init/waiting done elsewhere
+ static void writeBytesValueRaw(uint8_t value, int len) {
+ while(len--) { writeByte(value); }
+ }
+
+ // A full cycle of writing a value for len bytes, including select, release, and waiting
+ void writeBytesValue(uint8_t value, int len) {
+ select(); writeBytesValueRaw(value, len); release();
+ }
+
+ template <class D> void writeBytes(register uint8_t *data, int len) {
+ uint8_t *end = data + len;
+ select();
+ // could be optimized to write 16bit words out instead of 8bit bytes
+ while(data != end) {
+ writeByte(D::adjust(*data++));
+ }
+ D::postBlock(len);
+ waitFully();
+ release();
+ }
+
+ void writeBytes(register uint8_t *data, int len) { writeBytes<DATA_NOP>(data, len); }
+
+ // write a single bit out, which bit from the passed in byte is determined by template parameter
+ // not the most efficient mechanism in the world - but should be enough for sm16716 and friends
+ template <uint8_t BIT> inline void writeBit(uint8_t b) {
+ // need to wait for all exisiting data to go out the door, first
+ waitFully();
+ disableSPI();
+ if(b & (1 << BIT)) {
+ FastPin<_DATA_PIN>::hi();
+ } else {
+ FastPin<_DATA_PIN>::lo();
+ }
+
+ FastPin<_CLOCK_PIN>::hi();
+ FastPin<_CLOCK_PIN>::lo();
+ enableSPI();
+ }
+
+ // write a block of uint8_ts out in groups of three. len is the total number of uint8_ts to write out. The template
+ // parameters indicate how many uint8_ts to skip at the beginning and/or end of each grouping
+ template <uint8_t FLAGS, class D, EOrder RGB_ORDER> void writePixels(PixelController<RGB_ORDER> pixels) {
+ select();
+ int len = pixels.mLen;
+
+ if(FLAGS & FLAG_START_BIT) {
+ while(pixels.has(1)) {
+ writeBits<9>((1<<8) | D::adjust(pixels.loadAndScale0()));
+ writeByte(D::adjust(pixels.loadAndScale1()));
+ writeByte(D::adjust(pixels.loadAndScale2()));
+ pixels.advanceData();
+ pixels.stepDithering();
+ }
+ } else {
+ while(pixels.has(1)) {
+ writeByte(D::adjust(pixels.loadAndScale0()));
+ writeByte(D::adjust(pixels.loadAndScale1()));
+ writeByte(D::adjust(pixels.loadAndScale2()));
+ pixels.advanceData();
+ pixels.stepDithering();
+ }
+ }
+ D::postBlock(len);
+ release();
+ }
+};
+
+#endif
+
+FASTLED_NAMESPACE_END
+#endif
diff --git a/Библиотеки/FastLED-master/platforms/arm/sam/led_sysdefs_arm_sam.h b/Библиотеки/FastLED-master/platforms/arm/sam/led_sysdefs_arm_sam.h
new file mode 100644
index 0000000..a482864
--- /dev/null
+++ b/Библиотеки/FastLED-master/platforms/arm/sam/led_sysdefs_arm_sam.h
@@ -0,0 +1,39 @@
+#ifndef __INC_LED_SYSDEFS_ARM_SAM_H
+#define __INC_LED_SYSDEFS_ARM_SAM_H
+
+
+#define FASTLED_ARM
+
+// Setup DUE timer defines/channels/etc...
+#ifndef DUE_TIMER_CHANNEL
+#define DUE_TIMER_GROUP 0
+#endif
+
+#ifndef DUE_TIMER_CHANNEL
+#define DUE_TIMER_CHANNEL 0
+#endif
+
+#define DUE_TIMER ((DUE_TIMER_GROUP==0) ? TC0 : ((DUE_TIMER_GROUP==1) ? TC1 : TC2))
+#define DUE_TIMER_ID (ID_TC0 + (DUE_TIMER_GROUP*3) + DUE_TIMER_CHANNEL)
+#define DUE_TIMER_VAL (DUE_TIMER->TC_CHANNEL[DUE_TIMER_CHANNEL].TC_CV << 1)
+#define DUE_TIMER_RUNNING ((DUE_TIMER->TC_CHANNEL[DUE_TIMER_CHANNEL].TC_SR & TC_SR_CLKSTA) != 0)
+
+#ifndef INTERRUPT_THRESHOLD
+#define INTERRUPT_THRESHOLD 1
+#endif
+
+// Default to allowing interrupts
+#ifndef FASTLED_ALLOW_INTERRUPTS
+#define FASTLED_ALLOW_INTERRUPTS 1
+#endif
+
+#if FASTLED_ALLOW_INTERRUPTS == 1
+#define FASTLED_ACCURATE_CLOCK
+#endif
+
+// reusing/abusing cli/sei defs for due
+#define cli() __disable_irq(); __disable_fault_irq();
+#define sei() __enable_irq(); __enable_fault_irq();
+
+
+#endif
diff --git a/Библиотеки/FastLED-master/platforms/arm/stm32/clockless_arm_stm32.h b/Библиотеки/FastLED-master/platforms/arm/stm32/clockless_arm_stm32.h
new file mode 100644
index 0000000..e4b4de0
--- /dev/null
+++ b/Библиотеки/FastLED-master/platforms/arm/stm32/clockless_arm_stm32.h
@@ -0,0 +1,126 @@
+#ifndef __INC_CLOCKLESS_ARM_STM32_H
+#define __INC_CLOCKLESS_ARM_STM32_H
+
+FASTLED_NAMESPACE_BEGIN
+// Definition for a single channel clockless controller for the stm32 family of chips, like that used in the spark core
+// See clockless.h for detailed info on how the template parameters are used.
+
+#define FASTLED_HAS_CLOCKLESS 1
+
+template <int DATA_PIN, int T1, int T2, int T3, EOrder RGB_ORDER = RGB, int XTRA0 = 0, bool FLIP = false, int WAIT_TIME = 50>
+class ClocklessController : public CPixelLEDController<RGB_ORDER> {
+ typedef typename FastPin<DATA_PIN>::port_ptr_t data_ptr_t;
+ typedef typename FastPin<DATA_PIN>::port_t data_t;
+
+ data_t mPinMask;
+ data_ptr_t mPort;
+ CMinWait<WAIT_TIME> mWait;
+public:
+ virtual void init() {
+ FastPin<DATA_PIN>::setOutput();
+ mPinMask = FastPin<DATA_PIN>::mask();
+ mPort = FastPin<DATA_PIN>::port();
+ }
+
+ virtual uint16_t getMaxRefreshRate() const { return 400; }
+
+protected:
+
+ virtual void showPixels(PixelController<RGB_ORDER> & pixels) {
+ mWait.wait();
+ if(!showRGBInternal(pixels)) {
+ sei(); delayMicroseconds(WAIT_TIME); cli();
+ showRGBInternal(pixels);
+ }
+ mWait.mark();
+ }
+
+#define _CYCCNT (*(volatile uint32_t*)(0xE0001004UL))
+
+ template<int BITS> __attribute__ ((always_inline)) inline static void writeBits(register uint32_t & next_mark, register data_ptr_t port, register data_t hi, register data_t lo, register uint8_t & b) {
+ for(register uint32_t i = BITS-1; i > 0; i--) {
+ while(_CYCCNT < (T1+T2+T3-20));
+ FastPin<DATA_PIN>::fastset(port, hi);
+ _CYCCNT = 4;
+ if(b&0x80) {
+ while(_CYCCNT < (T1+T2-20));
+ FastPin<DATA_PIN>::fastset(port, lo);
+ } else {
+ while(_CYCCNT < (T1-10));
+ FastPin<DATA_PIN>::fastset(port, lo);
+ }
+ b <<= 1;
+ }
+
+ while(_CYCCNT < (T1+T2+T3-20));
+ FastPin<DATA_PIN>::fastset(port, hi);
+ _CYCCNT = 4;
+
+ if(b&0x80) {
+ while(_CYCCNT < (T1+T2-20));
+ FastPin<DATA_PIN>::fastset(port, lo);
+ } else {
+ while(_CYCCNT < (T1-10));
+ FastPin<DATA_PIN>::fastset(port, lo);
+ }
+ }
+
+ // This method is made static to force making register Y available to use for data on AVR - if the method is non-static, then
+ // gcc will use register Y for the this pointer.
+ static uint32_t showRGBInternal(PixelController<RGB_ORDER> pixels) {
+ // Get access to the clock
+ CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
+ DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;
+ DWT->CYCCNT = 0;
+
+ register data_ptr_t port = FastPin<DATA_PIN>::port();
+ register data_t hi = *port | FastPin<DATA_PIN>::mask();;
+ register data_t lo = *port & ~FastPin<DATA_PIN>::mask();;
+ *port = lo;
+
+ // Setup the pixel controller and load/scale the first byte
+ pixels.preStepFirstByteDithering();
+ register uint8_t b = pixels.loadAndScale0();
+
+ cli();
+
+ uint32_t next_mark = (T1+T2+T3);
+
+ DWT->CYCCNT = 0;
+ while(pixels.has(1)) {
+ pixels.stepDithering();
+ #if (FASTLED_ALLOW_INTERRUPTS == 1)
+ cli();
+ // if interrupts took longer than 45µs, punt on the current frame
+ if(DWT->CYCCNT > next_mark) {
+ if((DWT->CYCCNT-next_mark) > ((WAIT_TIME-INTERRUPT_THRESHOLD)*CLKS_PER_US)) { sei(); return 0; }
+ }
+
+ hi = *port | FastPin<DATA_PIN>::mask();
+ lo = *port & ~FastPin<DATA_PIN>::mask();
+ #endif
+
+ // Write first byte, read next byte
+ writeBits<8+XTRA0>(next_mark, port, hi, lo, b);
+ b = pixels.loadAndScale1();
+
+ // Write second byte, read 3rd byte
+ writeBits<8+XTRA0>(next_mark, port, hi, lo, b);
+ b = pixels.loadAndScale2();
+
+ // Write third byte, read 1st byte of next pixel
+ writeBits<8+XTRA0>(next_mark, port, hi, lo, b);
+ b = pixels.advanceAndLoadAndScale0();
+ #if (FASTLED_ALLOW_INTERRUPTS == 1)
+ sei();
+ #endif
+ };
+
+ sei();
+ return DWT->CYCCNT;
+ }
+};
+
+FASTLED_NAMESPACE_END
+
+ #endif
diff --git a/Библиотеки/FastLED-master/platforms/arm/stm32/fastled_arm_stm32.h b/Библиотеки/FastLED-master/platforms/arm/stm32/fastled_arm_stm32.h
new file mode 100644
index 0000000..e790bfe
--- /dev/null
+++ b/Библиотеки/FastLED-master/platforms/arm/stm32/fastled_arm_stm32.h
@@ -0,0 +1,10 @@
+#ifndef __INC_FASTLED_ARM_SAM_H
+#define __INC_FASTLED_ARM_SAM_H
+
+// Include the sam headers
+#include "fastled_delay.h"
+#include "fastpin_arm_stm32.h"
+// #include "fastspi_arm_stm32.h"
+#include "clockless_arm_stm32.h"
+
+#endif
diff --git a/Библиотеки/FastLED-master/platforms/arm/stm32/fastpin_arm_stm32.h b/Библиотеки/FastLED-master/platforms/arm/stm32/fastpin_arm_stm32.h
new file mode 100644
index 0000000..63729bb
--- /dev/null
+++ b/Библиотеки/FastLED-master/platforms/arm/stm32/fastpin_arm_stm32.h
@@ -0,0 +1,105 @@
+#ifndef __FASTPIN_ARM_STM32_H
+#define __FASTPIN_ARM_STM32_H
+
+FASTLED_NAMESPACE_BEGIN
+
+#if defined(FASTLED_FORCE_SOFTWARE_PINS)
+#warning "Software pin support forced, pin access will be sloightly slower."
+#define NO_HARDWARE_PIN_SUPPORT
+#undef HAS_HARDWARE_PIN_SUPPORT
+
+#else
+
+/// Template definition for STM32 style ARM pins, providing direct access to the various GPIO registers. Note that this
+/// uses the full port GPIO registers. In theory, in some way, bit-band register access -should- be faster, however I have found
+/// that something about the way gcc does register allocation results in the bit-band code being slower. It will need more fine tuning.
+/// The registers are data output, set output, clear output, toggle output, input, and direction
+
+template<uint8_t PIN, uint8_t _BIT, uint32_t _MASK, typename _GPIO> class _ARMPIN {
+public:
+ typedef volatile uint32_t * port_ptr_t;
+ typedef uint32_t port_t;
+
+ #if 0
+ inline static void setOutput() {
+ if(_BIT<8) {
+ _CRL::r() = (_CRL::r() & (0xF << (_BIT*4)) | (0x1 << (_BIT*4));
+ } else {
+ _CRH::r() = (_CRH::r() & (0xF << ((_BIT-8)*4))) | (0x1 << ((_BIT-8)*4));
+ }
+ }
+ inline static void setInput() { /* TODO */ } // TODO: preform MUX config { _PDDR::r() &= ~_MASK; }
+ #endif
+
+ inline static void setOutput() { pinMode(PIN, OUTPUT); } // TODO: perform MUX config { _PDDR::r() |= _MASK; }
+ inline static void setInput() { pinMode(PIN, INPUT); } // TODO: preform MUX config { _PDDR::r() &= ~_MASK; }
+
+ inline static void hi() __attribute__ ((always_inline)) { _GPIO::r()->BSRR = _MASK; }
+ inline static void lo() __attribute__ ((always_inline)) { _GPIO::r()->BRR = _MASK; }
+ // inline static void lo() __attribute__ ((always_inline)) { _GPIO::r()->BSRR = (_MASK<<16); }
+ inline static void set(register port_t val) __attribute__ ((always_inline)) { _GPIO::r()->ODR = val; }
+
+ inline static void strobe() __attribute__ ((always_inline)) { toggle(); toggle(); }
+
+ inline static void toggle() __attribute__ ((always_inline)) { if(_GPIO::r()->ODR & _MASK) { lo(); } else { hi(); } }
+
+ inline static void hi(register port_ptr_t port) __attribute__ ((always_inline)) { hi(); }
+ inline static void lo(register port_ptr_t port) __attribute__ ((always_inline)) { lo(); }
+ inline static void fastset(register port_ptr_t port, register port_t val) __attribute__ ((always_inline)) { *port = val; }
+
+ inline static port_t hival() __attribute__ ((always_inline)) { return _GPIO::r()->ODR | _MASK; }
+ inline static port_t loval() __attribute__ ((always_inline)) { return _GPIO::r()->ODR & ~_MASK; }
+ inline static port_ptr_t port() __attribute__ ((always_inline)) { return &_GPIO::r()->ODR; }
+ inline static port_ptr_t sport() __attribute__ ((always_inline)) { return &_GPIO::r()->BSRR; }
+ inline static port_ptr_t cport() __attribute__ ((always_inline)) { return &_GPIO::r()->BRR; }
+ inline static port_t mask() __attribute__ ((always_inline)) { return _MASK; }
+};
+
+#define _R(T) struct __gen_struct_ ## T
+#define _RD32(T) struct __gen_struct_ ## T { static __attribute__((always_inline)) inline volatile GPIO_TypeDef * r() { return T; } };
+
+#define _IO32(L) _RD32(GPIO ## L)
+
+#define _DEFPIN_ARM(PIN, BIT, L) template<> class FastPin<PIN> : public _ARMPIN<PIN, BIT, 1 << BIT, _R(GPIO ## L)> {};
+
+// Actual pin definitions
+#if defined(SPARK)
+
+_IO32(A); _IO32(B); _IO32(C); _IO32(D); _IO32(E); _IO32(F); _IO32(G);
+
+
+#define MAX_PIN 19
+_DEFPIN_ARM(0, 7, B);
+_DEFPIN_ARM(1, 6, B);
+_DEFPIN_ARM(2, 5, B);
+_DEFPIN_ARM(3, 4, B);
+_DEFPIN_ARM(4, 3, B);
+_DEFPIN_ARM(5, 15, A);
+_DEFPIN_ARM(6, 14, A);
+_DEFPIN_ARM(7, 13, A);
+_DEFPIN_ARM(8, 8, A);
+_DEFPIN_ARM(9, 9, A);
+_DEFPIN_ARM(10, 0, A);
+_DEFPIN_ARM(11, 1, A);
+_DEFPIN_ARM(12, 4, A);
+_DEFPIN_ARM(13, 5, A);
+_DEFPIN_ARM(14, 6, A);
+_DEFPIN_ARM(15, 7, A);
+_DEFPIN_ARM(16, 0, B);
+_DEFPIN_ARM(17, 1, B);
+_DEFPIN_ARM(18, 3, A);
+_DEFPIN_ARM(19, 2, A);
+
+
+#define SPI_DATA 15
+#define SPI_CLOCK 13
+
+#define HAS_HARDWARE_PIN_SUPPORT
+
+#endif
+
+#endif // FASTLED_FORCE_SOFTWARE_PINS
+
+FASTLED_NAMESPACE_END
+
+#endif // __INC_FASTPIN_ARM_STM32
diff --git a/Библиотеки/FastLED-master/platforms/arm/stm32/led_sysdefs_arm_stm32.h b/Библиотеки/FastLED-master/platforms/arm/stm32/led_sysdefs_arm_stm32.h
new file mode 100644
index 0000000..c15e001
--- /dev/null
+++ b/Библиотеки/FastLED-master/platforms/arm/stm32/led_sysdefs_arm_stm32.h
@@ -0,0 +1,47 @@
+#ifndef __INC_LED_SYSDEFS_ARM_SAM_H
+#define __INC_LED_SYSDEFS_ARM_SAM_H
+
+#include "application.h"
+
+#define FASTLED_NAMESPACE_BEGIN namespace NSFastLED {
+#define FASTLED_NAMESPACE_END }
+#define FASTLED_USING_NAMESPACE using namespace NSFastLED;
+
+#define FASTLED_ARM
+
+#ifndef INTERRUPT_THRESHOLD
+#define INTERRUPT_THRESHOLD 1
+#endif
+
+// Default to allowing interrupts
+#ifndef FASTLED_ALLOW_INTERRUPTS
+#define FASTLED_ALLOW_INTERRUPTS 0
+#endif
+
+#if FASTLED_ALLOW_INTERRUPTS == 1
+#define FASTLED_ACCURATE_CLOCK
+#endif
+
+// reusing/abusing cli/sei defs for due
+#define cli() __disable_irq(); __disable_fault_irq();
+#define sei() __enable_irq(); __enable_fault_irq();
+
+// pgmspace definitions
+#define PROGMEM
+#define pgm_read_dword(addr) (*(const unsigned long *)(addr))
+#define pgm_read_dword_near(addr) pgm_read_dword(addr)
+
+// Default to NOT using PROGMEM here
+#ifndef FASTLED_USE_PROGMEM
+#define FASTLED_USE_PROGMEM 0
+#endif
+
+// data type defs
+typedef volatile uint8_t RoReg; /**< Read only 8-bit register (volatile const unsigned int) */
+typedef volatile uint8_t RwReg; /**< Read-Write 8-bit register (volatile unsigned int) */
+
+#define FASTLED_NO_PINMAP
+
+#define F_CPU 72000000
+
+#endif
diff --git a/Библиотеки/FastLED-master/platforms/avr/clockless_trinket.h b/Библиотеки/FastLED-master/platforms/avr/clockless_trinket.h
new file mode 100644
index 0000000..a883aea
--- /dev/null
+++ b/Библиотеки/FastLED-master/platforms/avr/clockless_trinket.h
@@ -0,0 +1,464 @@
+#ifndef __INC_CLOCKLESS_TRINKET_H
+#define __INC_CLOCKLESS_TRINKET_H
+
+#include "controller.h"
+#include "lib8tion.h"
+#include <avr/interrupt.h> // for cli/se definitions
+
+FASTLED_NAMESPACE_BEGIN
+
+#if defined(FASTLED_AVR)
+
+// Scaling macro choice
+#ifndef TRINKET_SCALE
+#define TRINKET_SCALE 1
+// whether or not to use dithering
+#define DITHER 1
+#endif
+
+#if (F_CPU==8000000)
+#define FASTLED_SLOW_CLOCK_ADJUST // asm __volatile__ ("mov r0,r0\n\t");
+#else
+#define FASTLED_SLOW_CLOCK_ADJUST
+#endif
+
+#define US_PER_TICK (64 / (F_CPU/1000000))
+
+// Variations on the functions in delay.h - w/a loop var passed in to preserve registers across calls by the optimizer/compiler
+template<int CYCLES> inline void _dc(register uint8_t & loopvar);
+
+template<int _LOOP, int PAD> __attribute__((always_inline)) inline void _dc_AVR(register uint8_t & loopvar) {
+ _dc<PAD>(loopvar);
+ // The convolution in here is to ensure that the state of the carry flag coming into the delay loop is preserved
+ asm __volatile__ ( "BRCS L_PC%=\n\t"
+ " LDI %[loopvar], %[_LOOP]\n\tL_%=: DEC %[loopvar]\n\t BRNE L_%=\n\tBREQ L_DONE%=\n\t"
+ "L_PC%=: LDI %[loopvar], %[_LOOP]\n\tLL_%=: DEC %[loopvar]\n\t BRNE LL_%=\n\tBSET 0\n\t"
+ "L_DONE%=:\n\t"
+ :
+ [loopvar] "+a" (loopvar) : [_LOOP] "M" (_LOOP) : );
+}
+
+template<int CYCLES> __attribute__((always_inline)) inline void _dc(register uint8_t & loopvar) {
+ _dc_AVR<CYCLES/6,CYCLES%6>(loopvar);
+}
+template<> __attribute__((always_inline)) inline void _dc<-6>(register uint8_t & ) {}
+template<> __attribute__((always_inline)) inline void _dc<-5>(register uint8_t & ) {}
+template<> __attribute__((always_inline)) inline void _dc<-4>(register uint8_t & ) {}
+template<> __attribute__((always_inline)) inline void _dc<-3>(register uint8_t & ) {}
+template<> __attribute__((always_inline)) inline void _dc<-2>(register uint8_t & ) {}
+template<> __attribute__((always_inline)) inline void _dc<-1>(register uint8_t & ) {}
+template<> __attribute__((always_inline)) inline void _dc< 0>(register uint8_t & ) {}
+template<> __attribute__((always_inline)) inline void _dc< 1>(register uint8_t & ) {asm __volatile__("mov r0,r0":::);}
+template<> __attribute__((always_inline)) inline void _dc< 2>(register uint8_t & ) {asm __volatile__("rjmp .+0":::);}
+template<> __attribute__((always_inline)) inline void _dc< 3>(register uint8_t & loopvar) { _dc<2>(loopvar); _dc<1>(loopvar); }
+template<> __attribute__((always_inline)) inline void _dc< 4>(register uint8_t & loopvar) { _dc<2>(loopvar); _dc<2>(loopvar); }
+template<> __attribute__((always_inline)) inline void _dc< 5>(register uint8_t & loopvar) { _dc<2>(loopvar); _dc<3>(loopvar); }
+template<> __attribute__((always_inline)) inline void _dc< 6>(register uint8_t & loopvar) { _dc<2>(loopvar); _dc<2>(loopvar); _dc<2>(loopvar);}
+template<> __attribute__((always_inline)) inline void _dc< 7>(register uint8_t & loopvar) { _dc<4>(loopvar); _dc<3>(loopvar); }
+template<> __attribute__((always_inline)) inline void _dc< 8>(register uint8_t & loopvar) { _dc<4>(loopvar); _dc<4>(loopvar); }
+template<> __attribute__((always_inline)) inline void _dc< 9>(register uint8_t & loopvar) { _dc<5>(loopvar); _dc<4>(loopvar); }
+template<> __attribute__((always_inline)) inline void _dc<10>(register uint8_t & loopvar) { _dc<6>(loopvar); _dc<4>(loopvar); }
+template<> __attribute__((always_inline)) inline void _dc<11>(register uint8_t & loopvar) { _dc<10>(loopvar); _dc<1>(loopvar); }
+template<> __attribute__((always_inline)) inline void _dc<12>(register uint8_t & loopvar) { _dc<10>(loopvar); _dc<2>(loopvar); }
+template<> __attribute__((always_inline)) inline void _dc<13>(register uint8_t & loopvar) { _dc<10>(loopvar); _dc<3>(loopvar); }
+template<> __attribute__((always_inline)) inline void _dc<14>(register uint8_t & loopvar) { _dc<10>(loopvar); _dc<4>(loopvar); }
+template<> __attribute__((always_inline)) inline void _dc<15>(register uint8_t & loopvar) { _dc<10>(loopvar); _dc<5>(loopvar); }
+template<> __attribute__((always_inline)) inline void _dc<16>(register uint8_t & loopvar) { _dc<10>(loopvar); _dc<6>(loopvar); }
+template<> __attribute__((always_inline)) inline void _dc<17>(register uint8_t & loopvar) { _dc<10>(loopvar); _dc<7>(loopvar); }
+template<> __attribute__((always_inline)) inline void _dc<18>(register uint8_t & loopvar) { _dc<10>(loopvar); _dc<8>(loopvar); }
+template<> __attribute__((always_inline)) inline void _dc<19>(register uint8_t & loopvar) { _dc<10>(loopvar); _dc<9>(loopvar); }
+template<> __attribute__((always_inline)) inline void _dc<20>(register uint8_t & loopvar) { _dc<10>(loopvar); _dc<10>(loopvar); }
+
+#define DINTPIN(T,ADJ,PINADJ) (T-(PINADJ+ADJ)>0) ? _dc<T-(PINADJ+ADJ)>(loopvar) : _dc<0>(loopvar);
+#define DINT(T,ADJ) if(AVR_PIN_CYCLES(DATA_PIN)==1) { DINTPIN(T,ADJ,1) } else { DINTPIN(T,ADJ,2); }
+#define D1(ADJ) DINT(T1,ADJ)
+#define D2(ADJ) DINT(T2,ADJ)
+#define D3(ADJ) DINT(T3,ADJ)
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// Base template for clockless controllers. These controllers have 3 control points in their cycle for each bit. The first point
+// is where the line is raised hi. The second point is where the line is dropped low for a zero. The third point is where the
+// line is dropped low for a one. T1, T2, and T3 correspond to the timings for those three in clock cycles.
+//
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+#if (!defined(NO_CORRECTION) || (NO_CORRECTION == 0)) && (FASTLED_ALLOW_INTERRUPTS == 0)
+static uint8_t gTimeErrorAccum256ths;
+#endif
+
+#define FASTLED_HAS_CLOCKLESS 1
+
+template <uint8_t DATA_PIN, int T1, int T2, int T3, EOrder RGB_ORDER = RGB, int XTRA0 = 0, bool FLIP = false, int WAIT_TIME = 10>
+class ClocklessController : public CPixelLEDController<RGB_ORDER> {
+ static_assert(T1 >= 2 && T2 >= 2 && T3 >= 3, "Not enough cycles - use a higher clock speed");
+
+ typedef typename FastPin<DATA_PIN>::port_ptr_t data_ptr_t;
+ typedef typename FastPin<DATA_PIN>::port_t data_t;
+
+ CMinWait<WAIT_TIME> mWait;
+public:
+ virtual void init() {
+ FastPin<DATA_PIN>::setOutput();
+ }
+
+ virtual uint16_t getMaxRefreshRate() const { return 400; }
+
+protected:
+
+ virtual void showPixels(PixelController<RGB_ORDER> & pixels) {
+
+ mWait.wait();
+ cli();
+
+ showRGBInternal(pixels);
+
+ // Adjust the timer
+#if (!defined(NO_CORRECTION) || (NO_CORRECTION == 0)) && (FASTLED_ALLOW_INTERRUPTS == 0)
+ uint32_t microsTaken = (uint32_t)pixels.size() * (uint32_t)CLKS_TO_MICROS(24 * (T1 + T2 + T3));
+
+ // adust for approximate observed actal runtime (as of January 2015)
+ // roughly 9.6 cycles per pixel, which is 0.6us/pixel at 16MHz
+ // microsTaken += nLeds * 0.6 * CLKS_TO_MICROS(16);
+ microsTaken += scale16by8(pixels.size(),(0.6 * 256) + 1) * CLKS_TO_MICROS(16);
+
+ // if less than 1000us, there is NO timer impact,
+ // this is because the ONE interrupt that might come in while interrupts
+ // are disabled is queued up, and it will be serviced as soon as
+ // interrupts are re-enabled.
+ // This actually should technically also account for the runtime of the
+ // interrupt handler itself, but we're just not going to worry about that.
+ if( microsTaken > 1000) {
+
+ // Since up to one timer tick will be queued, we don't need
+ // to adjust the MS_COUNTER for that one.
+ microsTaken -= 1000;
+
+ // Now convert microseconds to 256ths of a second, approximately like this:
+ // 250ths = (us/4)
+ // 256ths = 250ths * (263/256);
+ uint16_t x256ths = microsTaken >> 2;
+ x256ths += scale16by8(x256ths,7);
+
+ x256ths += gTimeErrorAccum256ths;
+ MS_COUNTER += (x256ths >> 8);
+ gTimeErrorAccum256ths = x256ths & 0xFF;
+ }
+
+#if 0
+ // For pixel counts of 30 and under at 16Mhz, no correction is necessary.
+ // For pixel counts of 15 and under at 8Mhz, no correction is necessary.
+ //
+ // This code, below, is smaller, and quicker clock correction, which drifts much
+ // more significantly, but is a few bytes smaller. Presented here for consideration
+ // as an alternate on the ATtiny, which can't have more than about 150 pixels MAX
+ // anyway, meaning that microsTaken will never be more than about 4,500, which fits in
+ // a 16-bit variable. The difference between /1000 and /1024 only starts showing
+ // up in the range of about 100 pixels, so many ATtiny projects won't even
+ // see a clock difference due to the approximation there.
+ uint16_t microsTaken = (uint32_t)nLeds * (uint32_t)CLKS_TO_MICROS((24) * (T1 + T2 + T3));
+ MS_COUNTER += (microsTaken >> 10);
+#endif
+
+#endif
+
+ sei();
+ mWait.mark();
+ }
+#define USE_ASM_MACROS
+
+// The variables that our various asm statemetns use. The same block of variables needs to be declared for
+// all the asm blocks because GCC is pretty stupid and it would clobber variables happily or optimize code away too aggressively
+#define ASM_VARS : /* write variables */ \
+ [count] "+x" (count), \
+ [data] "+z" (data), \
+ [b1] "+a" (b1), \
+ [d0] "+r" (d0), \
+ [d1] "+r" (d1), \
+ [d2] "+r" (d2), \
+ [loopvar] "+a" (loopvar), \
+ [scale_base] "+a" (scale_base) \
+ : /* use variables */ \
+ [ADV] "r" (advanceBy), \
+ [b0] "a" (b0), \
+ [hi] "r" (hi), \
+ [lo] "r" (lo), \
+ [s0] "r" (s0), \
+ [s1] "r" (s1), \
+ [s2] "r" (s2), \
+ [e0] "r" (e0), \
+ [e1] "r" (e1), \
+ [e2] "r" (e2), \
+ [PORT] "M" (FastPin<DATA_PIN>::port()-0x20), \
+ [O0] "M" (RGB_BYTE0(RGB_ORDER)), \
+ [O1] "M" (RGB_BYTE1(RGB_ORDER)), \
+ [O2] "M" (RGB_BYTE2(RGB_ORDER)) \
+ : "cc" /* clobber registers */
+
+
+// Note: the code in the else in HI1/LO1 will be turned into an sts (2 cycle, 2 word) opcode
+// 1 cycle, write hi to the port
+#define HI1 FASTLED_SLOW_CLOCK_ADJUST if((int)(FastPin<DATA_PIN>::port())-0x20 < 64) { asm __volatile__("out %[PORT], %[hi]" ASM_VARS ); } else { *FastPin<DATA_PIN>::port()=hi; }
+// 1 cycle, write lo to the port
+#define LO1 if((int)(FastPin<DATA_PIN>::port())-0x20 < 64) { asm __volatile__("out %[PORT], %[lo]" ASM_VARS ); } else { *FastPin<DATA_PIN>::port()=lo; }
+
+// 2 cycles, sbrs on flipping the line to lo if we're pushing out a 0
+#define QLO2(B, N) asm __volatile__("sbrs %[" #B "], " #N ASM_VARS ); LO1;
+// load a byte from ram into the given var with the given offset
+#define LD2(B,O) asm __volatile__("ldd %[" #B "], Z + %[" #O "]\n\t" ASM_VARS );
+// 4 cycles - load a byte from ram into the scaling scratch space with the given offset, clear the target var, clear carry
+#define LDSCL4(B,O) asm __volatile__("ldd %[scale_base], Z + %[" #O "]\n\tclr %[" #B "]\n\tclc\n\t" ASM_VARS );
+
+#if (DITHER==1)
+// apply dithering value before we do anything with scale_base
+#define PRESCALE4(D) asm __volatile__("cpse %[scale_base], __zero_reg__\n\t add %[scale_base],%[" #D "]\n\tbrcc L_%=\n\tldi %[scale_base], 0xFF\n\tL_%=:\n\t" ASM_VARS);
+
+// Do the add for the prescale
+#define PRESCALEA2(D) asm __volatile__("cpse %[scale_base], __zero_reg__\n\t add %[scale_base],%[" #D "]\n\t" ASM_VARS);
+
+// Do the clamp for the prescale, clear carry when we're done - NOTE: Must ensure carry flag state is preserved!
+#define PRESCALEB4(D) asm __volatile__("brcc L_%=\n\tldi %[scale_base], 0xFF\n\tL_%=:\n\tneg %[" #D "]\n\tCLC" ASM_VARS);
+
+// Clamp for prescale, increment data, since we won't ever wrap 65k, this also effectively clears carry for us
+#define PSBIDATA4(D) asm __volatile__("brcc L_%=\n\tldi %[scale_base], 0xFF\n\tL_%=:\n\tadd %A[data], %[ADV]\n\tadc %B[data], __zero_reg__\n\t" ASM_VARS);
+
+#else
+#define PRESCALE4(D) _dc<4>(loopvar);
+#define PRESCALEA2(D) _dc<2>(loopvar);
+#define PRESCALEB4(D) _dc<4>(loopvar);
+#define PSBIDATA4(D) asm __volatile__( "add %A[data], %[ADV]\n\tadc %B[data], __zero_reg__\n\trjmp .+0\n\t" ASM_VARS );
+#endif
+
+// 2 cycles - perform one step of the scaling (if a given bit is set in scale, add scale-base to the scratch space)
+#define _SCALE02(B, N) "sbrc %[s0], " #N "\n\tadd %[" #B "], %[scale_base]\n\t"
+#define _SCALE12(B, N) "sbrc %[s1], " #N "\n\tadd %[" #B "], %[scale_base]\n\t"
+#define _SCALE22(B, N) "sbrc %[s2], " #N "\n\tadd %[" #B "], %[scale_base]\n\t"
+#define SCALE02(B,N) asm __volatile__( _SCALE02(B,N) ASM_VARS );
+#define SCALE12(B,N) asm __volatile__( _SCALE12(B,N) ASM_VARS );
+#define SCALE22(B,N) asm __volatile__( _SCALE22(B,N) ASM_VARS );
+
+// 1 cycle - rotate right, pulling in from carry
+#define _ROR1(B) "ror %[" #B "]\n\t"
+#define ROR1(B) asm __volatile__( _ROR1(B) ASM_VARS);
+
+// 1 cycle, clear the carry bit
+#define _CLC1 "clc\n\t"
+#define CLC1 asm __volatile__( _CLC1 ASM_VARS );
+
+// 2 cycles, rortate right, pulling in from carry then clear the carry bit
+#define RORCLC2(B) asm __volatile__( _ROR1(B) _CLC1 ASM_VARS );
+
+// 4 cycles, rotate, clear carry, scale next bit
+#define RORSC04(B, N) asm __volatile__( _ROR1(B) _CLC1 _SCALE02(B, N) ASM_VARS );
+#define RORSC14(B, N) asm __volatile__( _ROR1(B) _CLC1 _SCALE12(B, N) ASM_VARS );
+#define RORSC24(B, N) asm __volatile__( _ROR1(B) _CLC1 _SCALE22(B, N) ASM_VARS );
+
+// 4 cycles, scale bit, rotate, clear carry
+#define SCROR04(B, N) asm __volatile__( _SCALE02(B,N) _ROR1(B) _CLC1 ASM_VARS );
+#define SCROR14(B, N) asm __volatile__( _SCALE12(B,N) _ROR1(B) _CLC1 ASM_VARS );
+#define SCROR24(B, N) asm __volatile__( _SCALE22(B,N) _ROR1(B) _CLC1 ASM_VARS );
+
+/////////////////////////////////////////////////////////////////////////////////////
+// Loop life cycle
+
+// dither adjustment macro - should be kept in sync w/what's in stepDithering
+// #define ADJDITHER2(D, E) D = E - D;
+#define _NEGD1(D) "neg %[" #D "]\n\t"
+#define _ADJD1(D,E) "add %[" #D "], %[" #E "]\n\t"
+#define ADJDITHER2(D, E) asm __volatile__ ( _NEGD1(D) _ADJD1(D, E) ASM_VARS);
+#define ADDDE1(D, E) asm __volatile__ ( _ADJD1(D, E) ASM_VARS );
+
+// #define xstr(a) str(a)
+// #define str(a) #a
+// #define ADJDITHER2(D,E) asm __volatile__("subi %[" #D "], " xstr(DUSE) "\n\tand %[" #D "], %[" #E "]\n\t" ASM_VARS);
+
+// define the beginning of the loop
+#define LOOP asm __volatile__("1:" ASM_VARS );
+// define the end of the loop
+#define DONE asm __volatile__("2:" ASM_VARS );
+
+// 2 cycles - increment the data pointer
+#define IDATA2 asm __volatile__("add %A[data], %[ADV]\n\tadc %B[data], __zero_reg__\n\t" ASM_VARS );
+#define IDATACLC3 asm __volatile__("add %A[data], %[ADV]\n\tadc %B[data], __zero_reg__\n\t" _CLC1 ASM_VARS );
+
+// 1 cycle mov
+#define _MOV1(B1, B2) "mov %[" #B1 "], %[" #B2 "]\n\t"
+
+#define MOV1(B1, B2) asm __volatile__( _MOV1(B1,B2) ASM_VARS );
+
+// 3 cycle mov - skip if scale fix is happening
+#if (FASTLED_SCALE8_FIXED == 1)
+#define _MOV_FIX03(B1, B2) "mov %[" #B1 "], %[scale_base]\n\tcpse %[s0], __zero_reg__\n\t" _MOV1(B1, B2)
+#define _MOV_FIX13(B1, B2) "mov %[" #B1 "], %[scale_base]\n\tcpse %[s1], __zero_reg__\n\t" _MOV1(B1, B2)
+#define _MOV_FIX23(B1, B2) "mov %[" #B1 "], %[scale_base]\n\tcpse %[s2], __zero_reg__\n\t" _MOV1(B1, B2)
+#else
+// if we haven't fixed scale8, just do the move and nop the 2 cycles that would be used to
+// do the fixed adjustment
+#define _MOV_FIX03(B1, B2) _MOV1(B1, B2) "rjmp .+0\n\t"
+#define _MOV_FIX13(B1, B2) _MOV1(B1, B2) "rjmp .+0\n\t"
+#define _MOV_FIX23(B1, B2) _MOV1(B1, B2) "rjmp .+0\n\t"
+#endif
+
+// 3 cycle mov + negate D for dither adjustment
+#define MOV_NEGD04(B1, B2, D) asm __volatile( _MOV_FIX03(B1, B2) _NEGD1(D) ASM_VARS );
+#define MOV_ADDDE04(B1, B2, D, E) asm __volatile( _MOV_FIX03(B1, B2) _ADJD1(D, E) ASM_VARS );
+#define MOV_NEGD14(B1, B2, D) asm __volatile( _MOV_FIX13(B1, B2) _NEGD1(D) ASM_VARS );
+#define MOV_ADDDE14(B1, B2, D, E) asm __volatile( _MOV_FIX13(B1, B2) _ADJD1(D, E) ASM_VARS );
+#define MOV_NEGD24(B1, B2, D) asm __volatile( _MOV_FIX23(B1, B2) _NEGD1(D) ASM_VARS );
+
+// 2 cycles - decrement the counter
+#define DCOUNT2 asm __volatile__("sbiw %[count], 1" ASM_VARS );
+// 2 cycles - jump to the beginning of the loop
+#define JMPLOOP2 asm __volatile__("rjmp 1b" ASM_VARS );
+// 2 cycles - jump out of the loop
+#define BRLOOP1 asm __volatile__("brne 3\n\trjmp 2f\n\t3:" ASM_VARS );
+
+// 5 cycles 2 sbiw, 3 for the breq/rjmp
+#define ENDLOOP5 asm __volatile__("sbiw %[count], 1\n\tbreq L_%=\n\trjmp 1b\n\tL_%=:\n\t" ASM_VARS);
+
+// NOP using the variables, forcing a move
+#define DNOP asm __volatile__("mov r0,r0" ASM_VARS);
+
+#define DADVANCE 3
+#define DUSE (0xFF - (DADVANCE-1))
+
+ // This method is made static to force making register Y available to use for data on AVR - if the method is non-static, then
+ // gcc will use register Y for the this pointer.
+ static void /*__attribute__((optimize("O0")))*/ /*__attribute__ ((always_inline))*/ showRGBInternal(PixelController<RGB_ORDER> & pixels) {
+ uint8_t *data = (uint8_t*)pixels.mData;
+ data_ptr_t port = FastPin<DATA_PIN>::port();
+ data_t mask = FastPin<DATA_PIN>::mask();
+ uint8_t scale_base = 0;
+
+ // register uint8_t *end = data + nLeds;
+ data_t hi = *port | mask;
+ data_t lo = *port & ~mask;
+ *port = lo;
+
+ // the byte currently being written out
+ uint8_t b0 = 0;
+ // the byte currently being worked on to write the next out
+ uint8_t b1 = 0;
+
+ // Setup the pixel controller
+ pixels.preStepFirstByteDithering();
+
+ // pull the dithering/adjustment values out of the pixels object for direct asm access
+ uint8_t advanceBy = pixels.advanceBy();
+ uint16_t count = pixels.mLen;
+
+ uint8_t s0 = pixels.mScale.raw[RO(0)];
+ uint8_t s1 = pixels.mScale.raw[RO(1)];
+ uint8_t s2 = pixels.mScale.raw[RO(2)];
+#if (FASTLED_SCALE8_FIXED==1)
+ s0++; s1++; s2++;
+#endif
+ uint8_t d0 = pixels.d[RO(0)];
+ uint8_t d1 = pixels.d[RO(1)];
+ uint8_t d2 = pixels.d[RO(2)];
+ uint8_t e0 = pixels.e[RO(0)];
+ uint8_t e1 = pixels.e[RO(1)];
+ uint8_t e2 = pixels.e[RO(2)];
+
+ uint8_t loopvar=0;
+
+ // This has to be done in asm to keep gcc from messing up the asm code further down
+ b0 = data[RO(0)];
+ {
+ LDSCL4(b0,O0) PRESCALEA2(d0)
+ PRESCALEB4(d0) SCALE02(b0,0)
+ RORSC04(b0,1) ROR1(b0) CLC1
+ SCROR04(b0,2) SCALE02(b0,3)
+ RORSC04(b0,4) ROR1(b0) CLC1
+ SCROR04(b0,5) SCALE02(b0,6)
+ RORSC04(b0,7) ROR1(b0) CLC1
+ MOV_ADDDE04(b1,b0,d0,e0)
+ MOV1(b0,b1)
+ }
+
+ {
+ // while(--count)
+ {
+ // Loop beginning
+ DNOP;
+ LOOP;
+
+ // Sum of the clock counts across each row should be 10 for 8Mhz, WS2811
+ // The values in the D1/D2/D3 indicate how many cycles the previous column takes
+ // to allow things to line back up.
+ //
+ // While writing out byte 0, we're loading up byte 1, applying the dithering adjustment,
+ // then scaling it using 8 cycles of shift/add interleaved in between writing the bits
+ // out. When doing byte 1, we're doing the above for byte 2. When we're doing byte 2,
+ // we're cycling back around and doing the above for byte 0.
+
+ // Inline scaling - RGB ordering
+ // DNOP
+ HI1 D1(1) QLO2(b0, 7) LDSCL4(b1,O1) D2(4) LO1 PRESCALEA2(d1) D3(2)
+ HI1 D1(1) QLO2(b0, 6) PRESCALEB4(d1) D2(4) LO1 SCALE12(b1,0) D3(2)
+ HI1 D1(1) QLO2(b0, 5) RORSC14(b1,1) D2(4) LO1 RORCLC2(b1) D3(2)
+ HI1 D1(1) QLO2(b0, 4) SCROR14(b1,2) D2(4) LO1 SCALE12(b1,3) D3(2)
+ HI1 D1(1) QLO2(b0, 3) RORSC14(b1,4) D2(4) LO1 RORCLC2(b1) D3(2)
+ HI1 D1(1) QLO2(b0, 2) SCROR14(b1,5) D2(4) LO1 SCALE12(b1,6) D3(2)
+ HI1 D1(1) QLO2(b0, 1) RORSC14(b1,7) D2(4) LO1 RORCLC2(b1) D3(2)
+ HI1 D1(1) QLO2(b0, 0)
+ switch(XTRA0) {
+ case 4: D2(0) LO1 D3(0) HI1 D1(1) QLO2(b0,0)
+ case 3: D2(0) LO1 D3(0) HI1 D1(1) QLO2(b0,0)
+ case 2: D2(0) LO1 D3(0) HI1 D1(1) QLO2(b0,0)
+ case 1: D2(0) LO1 D3(0) HI1 D1(1) QLO2(b0,0)
+ }
+ MOV_ADDDE14(b0,b1,d1,e1) D2(4) LO1 D3(0)
+
+ HI1 D1(1) QLO2(b0, 7) LDSCL4(b1,O2) D2(4) LO1 PRESCALEA2(d2) D3(2)
+ HI1 D1(1) QLO2(b0, 6) PSBIDATA4(d2) D2(4) LO1 SCALE22(b1,0) D3(2)
+ HI1 D1(1) QLO2(b0, 5) RORSC24(b1,1) D2(4) LO1 RORCLC2(b1) D3(2)
+ HI1 D1(1) QLO2(b0, 4) SCROR24(b1,2) D2(4) LO1 SCALE22(b1,3) D3(2)
+ HI1 D1(1) QLO2(b0, 3) RORSC24(b1,4) D2(4) LO1 RORCLC2(b1) D3(2)
+ HI1 D1(1) QLO2(b0, 2) SCROR24(b1,5) D2(4) LO1 SCALE22(b1,6) D3(2)
+ HI1 D1(1) QLO2(b0, 1) RORSC24(b1,7) D2(4) LO1 RORCLC2(b1) D3(2)
+ HI1 D1(1) QLO2(b0, 0)
+ switch(XTRA0) {
+ case 4: D2(0) LO1 D3(0) HI1 D1(1) QLO2(b0,0)
+ case 3: D2(0) LO1 D3(0) HI1 D1(1) QLO2(b0,0)
+ case 2: D2(0) LO1 D3(0) HI1 D1(1) QLO2(b0,0)
+ case 1: D2(0) LO1 D3(0) HI1 D1(1) QLO2(b0,0)
+ }
+
+ // Because Prescale on the middle byte also increments the data counter,
+ // we have to do both halves of updating d2 here - negating it (in the
+ // MOV_NEGD24 macro) and then adding E back into it
+ MOV_NEGD24(b0,b1,d2) D2(4) LO1 ADDDE1(d2,e2) D3(1)
+ HI1 D1(1) QLO2(b0, 7) LDSCL4(b1,O0) D2(4) LO1 PRESCALEA2(d0) D3(2)
+ HI1 D1(1) QLO2(b0, 6) PRESCALEB4(d0) D2(4) LO1 SCALE02(b1,0) D3(2)
+ HI1 D1(1) QLO2(b0, 5) RORSC04(b1,1) D2(4) LO1 RORCLC2(b1) D3(2)
+ HI1 D1(1) QLO2(b0, 4) SCROR04(b1,2) D2(4) LO1 SCALE02(b1,3) D3(2)
+ HI1 D1(1) QLO2(b0, 3) RORSC04(b1,4) D2(4) LO1 RORCLC2(b1) D3(2)
+ HI1 D1(1) QLO2(b0, 2) SCROR04(b1,5) D2(4) LO1 SCALE02(b1,6) D3(2)
+ HI1 D1(1) QLO2(b0, 1) RORSC04(b1,7) D2(4) LO1 RORCLC2(b1) D3(2)
+ HI1 D1(1) QLO2(b0, 0)
+ switch(XTRA0) {
+ case 4: D2(0) LO1 D3(0) HI1 D1(1) QLO2(b0,0)
+ case 3: D2(0) LO1 D3(0) HI1 D1(1) QLO2(b0,0)
+ case 2: D2(0) LO1 D3(0) HI1 D1(1) QLO2(b0,0)
+ case 1: D2(0) LO1 D3(0) HI1 D1(1) QLO2(b0,0)
+ }
+ MOV_ADDDE04(b0,b1,d0,e0) D2(4) LO1 D3(5)
+ ENDLOOP5
+ }
+ DONE;
+ }
+
+ #if (FASTLED_ALLOW_INTERRUPTS == 1)
+ // stop using the clock juggler
+ TCCR0A &= ~0x30;
+ #endif
+ }
+
+};
+
+#endif
+
+FASTLED_NAMESPACE_END
+
+#endif
diff --git a/Библиотеки/FastLED-master/platforms/avr/fastled_avr.h b/Библиотеки/FastLED-master/platforms/avr/fastled_avr.h
new file mode 100644
index 0000000..f5b5ee5
--- /dev/null
+++ b/Библиотеки/FastLED-master/platforms/avr/fastled_avr.h
@@ -0,0 +1,14 @@
+#ifndef __INC_FASTLED_AVR_H
+#define __INC_FASTLED_AVR_H
+
+#include "fastled_delay.h"
+#include "fastpin_avr.h"
+#include "fastspi_avr.h"
+#include "clockless_trinket.h"
+
+// Default to using PROGMEM
+#ifndef FASTLED_USE_PROGMEM
+#define FASTLED_USE_PROGMEM 1
+#endif
+
+#endif
diff --git a/Библиотеки/FastLED-master/platforms/avr/fastpin_avr.h b/Библиотеки/FastLED-master/platforms/avr/fastpin_avr.h
new file mode 100644
index 0000000..1fe8415
--- /dev/null
+++ b/Библиотеки/FastLED-master/platforms/avr/fastpin_avr.h
@@ -0,0 +1,330 @@
+#ifndef __INC_FASTPIN_AVR_H
+#define __INC_FASTPIN_AVR_H
+
+FASTLED_NAMESPACE_BEGIN
+
+#if defined(FASTLED_FORCE_SOFTWARE_PINS)
+#warning "Software pin support forced, pin access will be sloightly slower."
+#define NO_HARDWARE_PIN_SUPPORT
+#undef HAS_HARDWARE_PIN_SUPPORT
+
+#else
+
+#define AVR_PIN_CYCLES(_PIN) ((((int)FastPin<_PIN>::port())-0x20 < 64) ? 1 : 2)
+
+/// Class definition for a Pin where we know the port registers at compile time for said pin. This allows us to make
+/// a lot of optimizations, as the inlined hi/lo methods will devolve to a single io register write/bitset.
+template<uint8_t PIN, uint8_t _MASK, typename _PORT, typename _DDR, typename _PIN> class _AVRPIN {
+public:
+ typedef volatile uint8_t * port_ptr_t;
+ typedef uint8_t port_t;
+
+ inline static void setOutput() { _DDR::r() |= _MASK; }
+ inline static void setInput() { _DDR::r() &= ~_MASK; }
+
+ inline static void hi() __attribute__ ((always_inline)) { _PORT::r() |= _MASK; }
+ inline static void lo() __attribute__ ((always_inline)) { _PORT::r() &= ~_MASK; }
+ inline static void set(register uint8_t val) __attribute__ ((always_inline)) { _PORT::r() = val; }
+
+ inline static void strobe() __attribute__ ((always_inline)) { toggle(); toggle(); }
+
+ inline static void toggle() __attribute__ ((always_inline)) { _PIN::r() = _MASK; }
+
+ inline static void hi(register port_ptr_t /*port*/) __attribute__ ((always_inline)) { hi(); }
+ inline static void lo(register port_ptr_t /*port*/) __attribute__ ((always_inline)) { lo(); }
+ inline static void fastset(register port_ptr_t /*port*/, register uint8_t val) __attribute__ ((always_inline)) { set(val); }
+
+ inline static port_t hival() __attribute__ ((always_inline)) { return _PORT::r() | _MASK; }
+ inline static port_t loval() __attribute__ ((always_inline)) { return _PORT::r() & ~_MASK; }
+ inline static port_ptr_t port() __attribute__ ((always_inline)) { return &_PORT::r(); }
+ inline static port_t mask() __attribute__ ((always_inline)) { return _MASK; }
+};
+
+
+
+/// AVR definitions for pins. Getting around the fact that I can't pass GPIO register addresses in as template arguments by instead creating
+/// a custom type for each GPIO register with a single, static, aggressively inlined function that returns that specific GPIO register. A similar
+/// trick is used a bit further below for the ARM GPIO registers (of which there are far more than on AVR!)
+typedef volatile uint8_t & reg8_t;
+#define _R(T) struct __gen_struct_ ## T
+#define _RD8(T) struct __gen_struct_ ## T { static inline reg8_t r() { return T; }};
+#define _IO(L) _RD8(DDR ## L); _RD8(PORT ## L); _RD8(PIN ## L);
+#define _DEFPIN_AVR(_PIN, MASK, L) template<> class FastPin<_PIN> : public _AVRPIN<_PIN, MASK, _R(PORT ## L), _R(DDR ## L), _R(PIN ## L)> {};
+
+#if defined(__AVR_ATtiny85__) || defined(__AVR_ATtiny45__)
+_IO(B);
+
+#define MAX_PIN 5
+
+_DEFPIN_AVR(0, 0x01, B); _DEFPIN_AVR(1, 0x02, B); _DEFPIN_AVR(2, 0x04, B); _DEFPIN_AVR(3, 0x08, B);
+_DEFPIN_AVR(4, 0x10, B); _DEFPIN_AVR(5, 0x20, B);
+
+#define HAS_HARDWARE_PIN_SUPPORT 1
+
+#elif defined(ARDUINO_AVR_DIGISPARK) // digispark pin layout
+#define MAX_PIN 5
+#define HAS_HARDWARE_PIN_SUPPORT 1
+_IO(A); _IO(B);
+
+_DEFPIN_AVR(0, 0x01, B); _DEFPIN_AVR(1, 0x02, B); _DEFPIN_AVR(2, 0x04, B);
+_DEFPIN_AVR(3, 0x80, A); _DEFPIN_AVR(4, 0x40, A); _DEFPIN_AVR(5, 0x20, A);
+
+#elif defined(__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__) || defined(__AVR_ATtiny25__)
+_IO(A); _IO(B);
+
+#define MAX_PIN 10
+
+_DEFPIN_AVR(0, 0x01, A); _DEFPIN_AVR(1, 0x02, A); _DEFPIN_AVR(2, 0x04, A); _DEFPIN_AVR(3, 0x08, A);
+_DEFPIN_AVR(4, 0x10, A); _DEFPIN_AVR(5, 0x20, A); _DEFPIN_AVR(6, 0x40, A); _DEFPIN_AVR(7, 0x80, A);
+_DEFPIN_AVR(8, 0x04, B); _DEFPIN_AVR(9, 0x02, B); _DEFPIN_AVR(10, 0x01, B);
+
+#define HAS_HARDWARE_PIN_SUPPORT 1
+
+#elif defined(ARDUINO_AVR_DIGISPARKPRO)
+
+_IO(A); _IO(B);
+#define MAX_PIN 12
+
+_DEFPIN_AVR(0, 0x01, B); _DEFPIN_AVR(1, 0x02, B); _DEFPIN_AVR(2, 0x04, B); _DEFPIN_AVR(3, 0x20, B);
+_DEFPIN_AVR(4, 0x08, B); _DEFPIN_AVR(5, 0x80, A); _DEFPIN_AVR(6, 0x01, A); _DEFPIN_AVR(7, 0x02, A);
+_DEFPIN_AVR(8, 0x04, A); _DEFPIN_AVR(9, 0x08, A); _DEFPIN_AVR(10, 0x10, A); _DEFPIN_AVR(11, 0x20, A);
+_DEFPIN_AVR(12, 0x40, A);
+
+#elif defined(__AVR_ATtiny167__) || defined(__AVR_ATtiny87__)
+_IO(A); _IO(B);
+
+#define MAX_PIN 15
+
+_DEFPIN_AVR(0, 0x01, A); _DEFPIN_AVR(1, 0x02, A); _DEFPIN_AVR(2, 0x04, A); _DEFPIN_AVR(3, 0x08, A);
+_DEFPIN_AVR(4, 0x10, A); _DEFPIN_AVR(5, 0x20, A); _DEFPIN_AVR(6, 0x40, A); _DEFPIN_AVR(7, 0x80, A);
+_DEFPIN_AVR(8, 0x01, B); _DEFPIN_AVR(9, 0x02, B); _DEFPIN_AVR(10, 0x04, B); _DEFPIN_AVR(11, 0x08, B);
+_DEFPIN_AVR(12, 0x10, B); _DEFPIN_AVR(13, 0x20, B); _DEFPIN_AVR(14, 0x40, B); _DEFPIN_AVR(15, 0x80, B);
+
+#define SPI_DATA 4
+#define SPI_CLOCK 5
+#define AVR_HARDWARE_SPI 1
+
+#define HAS_HARDWARE_PIN_SUPPORT 1
+#elif defined(ARDUINO_HOODLOADER2) && (defined(__AVR_ATmega32U2__) || defined(__AVR_ATmega16U2__) || defined(__AVR_ATmega8U2__)) || defined(__AVR_AT90USB82__) || defined(__AVR_AT90USB162__)
+
+_IO(D); _IO(B); _IO(C);
+
+#define MAX_PIN 20
+
+_DEFPIN_AVR( 0, 0x01, B); _DEFPIN_AVR( 1, 0x02, B); _DEFPIN_AVR( 2, 0x04, B); _DEFPIN_AVR( 3, 0x08, B);
+_DEFPIN_AVR( 4, 0x10, B); _DEFPIN_AVR( 5, 0x20, B); _DEFPIN_AVR( 6, 0x40, B); _DEFPIN_AVR( 7, 0x80, B);
+
+_DEFPIN_AVR( 8, 0x80, C); _DEFPIN_AVR( 9, 0x40, C); _DEFPIN_AVR( 10, 0x20,C); _DEFPIN_AVR( 11, 0x10, C);
+_DEFPIN_AVR( 12, 0x04, C); _DEFPIN_AVR( 13, 0x01, D); _DEFPIN_AVR( 14, 0x02, D); _DEFPIN_AVR(15, 0x04, D);
+_DEFPIN_AVR( 16, 0x08, D); _DEFPIN_AVR( 17, 0x10, D); _DEFPIN_AVR( 18, 0x20, D); _DEFPIN_AVR( 19, 0x40, D);
+_DEFPIN_AVR( 20, 0x80, D);
+
+#define HAS_HARDWARE_PIN_SUPPORT 1
+// #define SPI_DATA 2
+// #define SPI_CLOCK 1
+// #define AVR_HARDWARE_SPI 1
+
+#elif defined(IS_BEAN)
+
+// Accelerated port definitions for arduino avrs
+_IO(D); _IO(B); _IO(C);
+
+#define MAX_PIN 19
+_DEFPIN_AVR( 0, 0x40, D); _DEFPIN_AVR( 1, 0x02, B); _DEFPIN_AVR( 2, 0x04, B); _DEFPIN_AVR( 3, 0x08, B);
+_DEFPIN_AVR( 4, 0x10, B); _DEFPIN_AVR( 5, 0x20, B); _DEFPIN_AVR( 6, 0x01, D); _DEFPIN_AVR( 7, 0x80, D);
+_DEFPIN_AVR( 8, 0x01, B); _DEFPIN_AVR( 9, 0x02, D); _DEFPIN_AVR(10, 0x04, D); _DEFPIN_AVR(11, 0x08, D);
+_DEFPIN_AVR(12, 0x10, D); _DEFPIN_AVR(13, 0x20, D); _DEFPIN_AVR(14, 0x01, C); _DEFPIN_AVR(15, 0x02, C);
+_DEFPIN_AVR(16, 0x04, C); _DEFPIN_AVR(17, 0x08, C); _DEFPIN_AVR(18, 0x10, C); _DEFPIN_AVR(19, 0x20, C);
+
+#define SPI_DATA 3
+#define SPI_CLOCK 5
+#define SPI_SELECT 2
+#define AVR_HARDWARE_SPI 1
+#define HAS_HARDWARE_PIN_SUPPORT 1
+
+#ifndef __AVR_ATmega8__
+#define SPI_UART0_DATA 9
+#define SPI_UART0_CLOCK 12
+#endif
+
+#elif defined(__AVR_ATmega328P__) || defined(__AVR_ATmega168__) || defined(__AVR_ATmega168P__) || defined(__AVR_ATmega8__)
+// Accelerated port definitions for arduino avrs
+_IO(D); _IO(B); _IO(C);
+
+#define MAX_PIN 19
+_DEFPIN_AVR( 0, 0x01, D); _DEFPIN_AVR( 1, 0x02, D); _DEFPIN_AVR( 2, 0x04, D); _DEFPIN_AVR( 3, 0x08, D);
+_DEFPIN_AVR( 4, 0x10, D); _DEFPIN_AVR( 5, 0x20, D); _DEFPIN_AVR( 6, 0x40, D); _DEFPIN_AVR( 7, 0x80, D);
+_DEFPIN_AVR( 8, 0x01, B); _DEFPIN_AVR( 9, 0x02, B); _DEFPIN_AVR(10, 0x04, B); _DEFPIN_AVR(11, 0x08, B);
+_DEFPIN_AVR(12, 0x10, B); _DEFPIN_AVR(13, 0x20, B); _DEFPIN_AVR(14, 0x01, C); _DEFPIN_AVR(15, 0x02, C);
+_DEFPIN_AVR(16, 0x04, C); _DEFPIN_AVR(17, 0x08, C); _DEFPIN_AVR(18, 0x10, C); _DEFPIN_AVR(19, 0x20, C);
+
+#define SPI_DATA 11
+#define SPI_CLOCK 13
+#define SPI_SELECT 10
+#define AVR_HARDWARE_SPI 1
+#define HAS_HARDWARE_PIN_SUPPORT 1
+
+#ifndef __AVR_ATmega8__
+#define SPI_UART0_DATA 1
+#define SPI_UART0_CLOCK 4
+#endif
+
+#elif defined(__AVR_ATmega1284P__)
+
+_IO(A); _IO(B); _IO(C); _IO(D);
+
+#define MAX_PIN 31
+_DEFPIN_AVR(0, 1<<0, B); _DEFPIN_AVR(1, 1<<1, B); _DEFPIN_AVR(2, 1<<2, B); _DEFPIN_AVR(3, 1<<3, B);
+_DEFPIN_AVR(4, 1<<4, B); _DEFPIN_AVR(5, 1<<5, B); _DEFPIN_AVR(6, 1<<6, B); _DEFPIN_AVR(7, 1<<7, B);
+_DEFPIN_AVR(8, 1<<0, D); _DEFPIN_AVR(9, 1<<1, D); _DEFPIN_AVR(10, 1<<2, D); _DEFPIN_AVR(11, 1<<3, D);
+_DEFPIN_AVR(12, 1<<4, D); _DEFPIN_AVR(13, 1<<5, D); _DEFPIN_AVR(14, 1<<6, D); _DEFPIN_AVR(15, 1<<7, D);
+_DEFPIN_AVR(16, 1<<0, C); _DEFPIN_AVR(17, 1<<1, C); _DEFPIN_AVR(18, 1<<2, C); _DEFPIN_AVR(19, 1<<3, C);
+_DEFPIN_AVR(20, 1<<4, C); _DEFPIN_AVR(21, 1<<5, C); _DEFPIN_AVR(22, 1<<6, C); _DEFPIN_AVR(23, 1<<7, C);
+_DEFPIN_AVR(24, 1<<0, A); _DEFPIN_AVR(25, 1<<1, A); _DEFPIN_AVR(26, 1<<2, A); _DEFPIN_AVR(27, 1<<3, A);
+_DEFPIN_AVR(28, 1<<4, A); _DEFPIN_AVR(29, 1<<5, A); _DEFPIN_AVR(30, 1<<6, A); _DEFPIN_AVR(31, 1<<7, A);
+
+#define SPI_DATA 5
+#define SPI_CLOCK 7
+#define SPI_SELECT 4
+#define AVR_HARDWARE_SPI 1
+#define HAS_HARDWARE_PIN_SUPPORT 1
+
+#elif defined(__AVR_ATmega128RFA1__) || defined(__AVR_ATmega256RFR2__)
+
+// AKA the Pinoccio
+
+_IO(A); _IO(B); _IO(C); _IO(D); _IO(E); _IO(F);
+
+_DEFPIN_AVR( 0, 1<<0, E); _DEFPIN_AVR( 1, 1<<1, E); _DEFPIN_AVR( 2, 1<<7, B); _DEFPIN_AVR( 3, 1<<3, E);
+_DEFPIN_AVR( 4, 1<<4, E); _DEFPIN_AVR( 5, 1<<5, E); _DEFPIN_AVR( 6, 1<<2, E); _DEFPIN_AVR( 7, 1<<6, E);
+_DEFPIN_AVR( 8, 1<<5, D); _DEFPIN_AVR( 9, 1<<0, B); _DEFPIN_AVR(10, 1<<2, B); _DEFPIN_AVR(11, 1<<3, B);
+_DEFPIN_AVR(12, 1<<1, B); _DEFPIN_AVR(13, 1<<2, D); _DEFPIN_AVR(14, 1<<3, D); _DEFPIN_AVR(15, 1<<0, D);
+_DEFPIN_AVR(16, 1<<1, D); _DEFPIN_AVR(17, 1<<4, D); _DEFPIN_AVR(18, 1<<7, E); _DEFPIN_AVR(19, 1<<6, D);
+_DEFPIN_AVR(20, 1<<7, D); _DEFPIN_AVR(21, 1<<4, B); _DEFPIN_AVR(22, 1<<5, B); _DEFPIN_AVR(23, 1<<6, B);
+_DEFPIN_AVR(24, 1<<0, F); _DEFPIN_AVR(25, 1<<1, F); _DEFPIN_AVR(26, 1<<2, F); _DEFPIN_AVR(27, 1<<3, F);
+_DEFPIN_AVR(28, 1<<4, F); _DEFPIN_AVR(29, 1<<5, F); _DEFPIN_AVR(30, 1<<6, F); _DEFPIN_AVR(31, 1<<7, F);
+
+#define SPI_DATA 10
+#define SPI_CLOCK 12
+#define SPI_SELECT 9
+
+#define AVR_HARDWARE_SPI 1
+#define HAS_HARDWARE_PIN_SUPPORT 1
+
+#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
+// megas
+
+_IO(A); _IO(B); _IO(C); _IO(D); _IO(E); _IO(F); _IO(G); _IO(H); _IO(J); _IO(K); _IO(L);
+
+#define MAX_PIN 69
+_DEFPIN_AVR(0, 1, E); _DEFPIN_AVR(1, 2, E); _DEFPIN_AVR(2, 16, E); _DEFPIN_AVR(3, 32, E);
+_DEFPIN_AVR(4, 32, G); _DEFPIN_AVR(5, 8, E); _DEFPIN_AVR(6, 8, H); _DEFPIN_AVR(7, 16, H);
+_DEFPIN_AVR(8, 32, H); _DEFPIN_AVR(9, 64, H); _DEFPIN_AVR(10, 16, B); _DEFPIN_AVR(11, 32, B);
+_DEFPIN_AVR(12, 64, B); _DEFPIN_AVR(13, 128, B); _DEFPIN_AVR(14, 2, J); _DEFPIN_AVR(15, 1, J);
+_DEFPIN_AVR(16, 2, H); _DEFPIN_AVR(17, 1, H); _DEFPIN_AVR(18, 8, D); _DEFPIN_AVR(19, 4, D);
+_DEFPIN_AVR(20, 2, D); _DEFPIN_AVR(21, 1, D); _DEFPIN_AVR(22, 1, A); _DEFPIN_AVR(23, 2, A);
+_DEFPIN_AVR(24, 4, A); _DEFPIN_AVR(25, 8, A); _DEFPIN_AVR(26, 16, A); _DEFPIN_AVR(27, 32, A);
+_DEFPIN_AVR(28, 64, A); _DEFPIN_AVR(29, 128, A); _DEFPIN_AVR(30, 128, C); _DEFPIN_AVR(31, 64, C);
+_DEFPIN_AVR(32, 32, C); _DEFPIN_AVR(33, 16, C); _DEFPIN_AVR(34, 8, C); _DEFPIN_AVR(35, 4, C);
+_DEFPIN_AVR(36, 2, C); _DEFPIN_AVR(37, 1, C); _DEFPIN_AVR(38, 128, D); _DEFPIN_AVR(39, 4, G);
+_DEFPIN_AVR(40, 2, G); _DEFPIN_AVR(41, 1, G); _DEFPIN_AVR(42, 128, L); _DEFPIN_AVR(43, 64, L);
+_DEFPIN_AVR(44, 32, L); _DEFPIN_AVR(45, 16, L); _DEFPIN_AVR(46, 8, L); _DEFPIN_AVR(47, 4, L);
+_DEFPIN_AVR(48, 2, L); _DEFPIN_AVR(49, 1, L); _DEFPIN_AVR(50, 8, B); _DEFPIN_AVR(51, 4, B);
+_DEFPIN_AVR(52, 2, B); _DEFPIN_AVR(53, 1, B); _DEFPIN_AVR(54, 1, F); _DEFPIN_AVR(55, 2, F);
+_DEFPIN_AVR(56, 4, F); _DEFPIN_AVR(57, 8, F); _DEFPIN_AVR(58, 16, F); _DEFPIN_AVR(59, 32, F);
+_DEFPIN_AVR(60, 64, F); _DEFPIN_AVR(61, 128, F); _DEFPIN_AVR(62, 1, K); _DEFPIN_AVR(63, 2, K);
+_DEFPIN_AVR(64, 4, K); _DEFPIN_AVR(65, 8, K); _DEFPIN_AVR(66, 16, K); _DEFPIN_AVR(67, 32, K);
+_DEFPIN_AVR(68, 64, K); _DEFPIN_AVR(69, 128, K);
+
+#define SPI_DATA 51
+#define SPI_CLOCK 52
+#define SPI_SELECT 53
+#define AVR_HARDWARE_SPI 1
+#define HAS_HARDWARE_PIN_SUPPORT 1
+
+// Leonardo, teensy, blinkm
+#elif defined(__AVR_ATmega32U4__) && defined(CORE_TEENSY)
+
+// teensy defs
+_IO(B); _IO(C); _IO(D); _IO(E); _IO(F);
+
+#define MAX_PIN 23
+_DEFPIN_AVR(0, 1, B); _DEFPIN_AVR(1, 2, B); _DEFPIN_AVR(2, 4, B); _DEFPIN_AVR(3, 8, B);
+_DEFPIN_AVR(4, 128, B); _DEFPIN_AVR(5, 1, D); _DEFPIN_AVR(6, 2, D); _DEFPIN_AVR(7, 4, D);
+_DEFPIN_AVR(8, 8, D); _DEFPIN_AVR(9, 64, C); _DEFPIN_AVR(10, 128, C); _DEFPIN_AVR(11, 64, D);
+_DEFPIN_AVR(12, 128, D); _DEFPIN_AVR(13, 16, B); _DEFPIN_AVR(14, 32, B); _DEFPIN_AVR(15, 64, B);
+_DEFPIN_AVR(16, 128, F); _DEFPIN_AVR(17, 64, F); _DEFPIN_AVR(18, 32, F); _DEFPIN_AVR(19, 16, F);
+_DEFPIN_AVR(20, 2, F); _DEFPIN_AVR(21, 1, F); _DEFPIN_AVR(22, 16, D); _DEFPIN_AVR(23, 32, D);
+
+#define SPI_DATA 2
+#define SPI_CLOCK 1
+#define SPI_SELECT 0
+#define AVR_HARDWARE_SPI 1
+#define HAS_HARDWARE_PIN_SUPPORT 1
+
+// PD3/PD5
+#define SPI_UART1_DATA 8
+#define SPI_UART1_CLOCK 23
+
+#elif defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__)
+// teensy++ 2 defs
+
+_IO(A); _IO(B); _IO(C); _IO(D); _IO(E); _IO(F);
+
+#define MAX_PIN 45
+_DEFPIN_AVR(0, 1, D); _DEFPIN_AVR(1, 2, D); _DEFPIN_AVR(2, 4, D); _DEFPIN_AVR(3, 8, D);
+_DEFPIN_AVR(4, 16, D); _DEFPIN_AVR(5, 32, D); _DEFPIN_AVR(6, 64, D); _DEFPIN_AVR(7, 128, D);
+_DEFPIN_AVR(8, 1, E); _DEFPIN_AVR(9, 2, E); _DEFPIN_AVR(10, 1, C); _DEFPIN_AVR(11, 2, C);
+_DEFPIN_AVR(12, 4, C); _DEFPIN_AVR(13, 8, C); _DEFPIN_AVR(14, 16, C); _DEFPIN_AVR(15, 32, C);
+_DEFPIN_AVR(16, 64, C); _DEFPIN_AVR(17, 128, C); _DEFPIN_AVR(18, 64, E); _DEFPIN_AVR(19, 128, E);
+_DEFPIN_AVR(20, 1, B); _DEFPIN_AVR(21, 2, B); _DEFPIN_AVR(22, 4, B); _DEFPIN_AVR(23, 8, B);
+_DEFPIN_AVR(24, 16, B); _DEFPIN_AVR(25, 32, B); _DEFPIN_AVR(26, 64, B); _DEFPIN_AVR(27, 128, B);
+_DEFPIN_AVR(28, 1, A); _DEFPIN_AVR(29, 2, A); _DEFPIN_AVR(30, 4, A); _DEFPIN_AVR(31, 8, A);
+_DEFPIN_AVR(32, 16, A); _DEFPIN_AVR(33, 32, A); _DEFPIN_AVR(34, 64, A); _DEFPIN_AVR(35, 128, A);
+_DEFPIN_AVR(36, 16, E); _DEFPIN_AVR(37, 32, E); _DEFPIN_AVR(38, 1, F); _DEFPIN_AVR(39, 2, F);
+_DEFPIN_AVR(40, 4, F); _DEFPIN_AVR(41, 8, F); _DEFPIN_AVR(42, 16, F); _DEFPIN_AVR(43, 32, F);
+_DEFPIN_AVR(44, 64, F); _DEFPIN_AVR(45, 128, F);
+
+#define SPI_DATA 22
+#define SPI_CLOCK 21
+#define SPI_SELECT 20
+#define AVR_HARDWARE_SPI 1
+#define HAS_HARDWARE_PIN_SUPPORT 1
+
+// PD3/PD5
+#define SPI_UART1_DATA 3
+#define SPI_UART1_CLOCK 5
+
+
+#elif defined(__AVR_ATmega32U4__)
+
+// leonard defs
+_IO(B); _IO(C); _IO(D); _IO(E); _IO(F);
+
+#define MAX_PIN 30
+_DEFPIN_AVR(0, 4, D); _DEFPIN_AVR(1, 8, D); _DEFPIN_AVR(2, 2, D); _DEFPIN_AVR(3, 1, D);
+_DEFPIN_AVR(4, 16, D); _DEFPIN_AVR(5, 64, C); _DEFPIN_AVR(6, 128, D); _DEFPIN_AVR(7, 64, E);
+_DEFPIN_AVR(8, 16, B); _DEFPIN_AVR(9, 32, B); _DEFPIN_AVR(10, 64, B); _DEFPIN_AVR(11, 128, B);
+_DEFPIN_AVR(12, 64, D); _DEFPIN_AVR(13, 128, C); _DEFPIN_AVR(14, 8, B); _DEFPIN_AVR(15, 2, B);
+_DEFPIN_AVR(16, 4, B); _DEFPIN_AVR(17, 1, B); _DEFPIN_AVR(18, 128, F); _DEFPIN_AVR(19, 64, F);
+_DEFPIN_AVR(20, 32, F); _DEFPIN_AVR(21, 16, F); _DEFPIN_AVR(22, 2, F); _DEFPIN_AVR(23, 1, F);
+_DEFPIN_AVR(24, 16, D); _DEFPIN_AVR(25, 128, D); _DEFPIN_AVR(26, 16, B); _DEFPIN_AVR(27, 32, B);
+_DEFPIN_AVR(28, 64, B); _DEFPIN_AVR(29, 64, D); _DEFPIN_AVR(30, 32, D);
+
+#define SPI_DATA 16
+#define SPI_CLOCK 15
+#define AVR_HARDWARE_SPI 1
+#define HAS_HARDWARE_PIN_SUPPORT 1
+
+// PD3/PD5
+#define SPI_UART1_DATA 1
+#define SPI_UART1_CLOCK 30
+
+
+#endif
+
+#endif // FASTLED_FORCE_SOFTWARE_PINS
+
+FASTLED_NAMESPACE_END
+
+#endif // __INC_FASTPIN_AVR_H
diff --git a/Библиотеки/FastLED-master/platforms/avr/fastspi_avr.h b/Библиотеки/FastLED-master/platforms/avr/fastspi_avr.h
new file mode 100644
index 0000000..2ed5bb1
--- /dev/null
+++ b/Библиотеки/FastLED-master/platforms/avr/fastspi_avr.h
@@ -0,0 +1,505 @@
+#ifndef __INC_FASTSPI_AVR_H
+#define __INC_FASTSPI_AVR_H
+
+FASTLED_NAMESPACE_BEGIN
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// Hardware SPI support using USART registers and friends
+//
+// TODO: Complete/test implementation - right now this doesn't work
+//
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+// uno/mini/duemilanove
+#if defined(AVR_HARDWARE_SPI)
+
+#if defined(UBRR1)
+
+#ifndef UCPHA1
+#define UCPHA1 1
+#endif
+
+template <uint8_t _DATA_PIN, uint8_t _CLOCK_PIN, uint8_t _SPI_CLOCK_DIVIDER>
+class AVRUSART1SPIOutput {
+ Selectable *m_pSelect;
+
+public:
+ AVRUSART1SPIOutput() { m_pSelect = NULL; }
+ AVRUSART1SPIOutput(Selectable *pSelect) { m_pSelect = pSelect; }
+ void setSelect(Selectable *pSelect) { m_pSelect = pSelect; }
+
+ void init() {
+ UBRR1 = 0;
+
+ /* Set MSPI mode of operation and SPI data mode 0. */
+ UCSR1C = (1<<UMSEL11)|(1<<UMSEL10)|(0<<UCPHA1)|(0<<UCPOL1);
+ /* Enable receiver and transmitter. */
+ UCSR1B = (1<<RXEN1)|(1<<TXEN1);
+
+ FastPin<_CLOCK_PIN>::setOutput();
+ FastPin<_DATA_PIN>::setOutput();
+
+ // must be done last, see page 206
+ setSPIRate();
+ }
+
+ void setSPIRate() {
+ if(_SPI_CLOCK_DIVIDER > 2) {
+ UBRR1 = (_SPI_CLOCK_DIVIDER/2)-1;
+ } else {
+ UBRR1 = 0;
+ }
+ }
+
+
+ static void stop() {
+ // TODO: stop the uart spi output
+ }
+
+ static bool shouldWait(bool wait = false) __attribute__((always_inline)) {
+ static bool sWait=false;
+ if(sWait) {
+ sWait = wait; return true;
+ } else {
+ sWait = wait; return false;
+ }
+ // return true;
+ }
+ static void wait() __attribute__((always_inline)) {
+ if(shouldWait()) {
+ while(!(UCSR1A & (1<<UDRE1)));
+ }
+ }
+ static void waitFully() __attribute__((always_inline)) { wait(); }
+
+ static void writeWord(uint16_t w) __attribute__((always_inline)) { writeByte(w>>8); writeByte(w&0xFF); }
+
+ static void writeByte(uint8_t b) __attribute__((always_inline)) { wait(); UDR1=b; shouldWait(true); }
+ static void writeBytePostWait(uint8_t b) __attribute__((always_inline)) { UDR1=b; shouldWait(true); wait(); }
+ static void writeByteNoWait(uint8_t b) __attribute__((always_inline)) { UDR1=b; shouldWait(true); }
+
+
+ template <uint8_t BIT> inline static void writeBit(uint8_t b) {
+ if(b && (1 << BIT)) {
+ FastPin<_DATA_PIN>::hi();
+ } else {
+ FastPin<_DATA_PIN>::lo();
+ }
+
+ FastPin<_CLOCK_PIN>::hi();
+ FastPin<_CLOCK_PIN>::lo();
+ }
+
+ void enable_pins() { }
+ void disable_pins() { }
+
+ void select() {
+ if(m_pSelect != NULL) {
+ m_pSelect->select();
+ }
+ enable_pins();
+ setSPIRate();
+ }
+
+ void release() {
+ if(m_pSelect != NULL) {
+ m_pSelect->release();
+ }
+ disable_pins();
+ }
+
+ static void writeBytesValueRaw(uint8_t value, int len) {
+ while(len--) {
+ writeByte(value);
+ }
+ }
+
+ void writeBytesValue(uint8_t value, int len) {
+ //setSPIRate();
+ select();
+ while(len--) {
+ writeByte(value);
+ }
+ release();
+ }
+
+ // Write a block of n uint8_ts out
+ template <class D> void writeBytes(register uint8_t *data, int len) {
+ //setSPIRate();
+ uint8_t *end = data + len;
+ select();
+ while(data != end) {
+ // a slight touch of delay here helps optimize the timing of the status register check loop (not used on ARM)
+ writeByte(D::adjust(*data++)); delaycycles<3>();
+ }
+ release();
+ }
+
+ void writeBytes(register uint8_t *data, int len) { writeBytes<DATA_NOP>(data, len); }
+
+ // write a block of uint8_ts out in groups of three. len is the total number of uint8_ts to write out. The template
+ // parameters indicate how many uint8_ts to skip at the beginning and/or end of each grouping
+ template <uint8_t FLAGS, class D, EOrder RGB_ORDER> void writePixels(PixelController<RGB_ORDER> pixels) {
+ //setSPIRate();
+ int len = pixels.mLen;
+
+ select();
+ while(pixels.has(1)) {
+ if(FLAGS & FLAG_START_BIT) {
+ writeBit<0>(1);
+ writeBytePostWait(D::adjust(pixels.loadAndScale0()));
+ writeBytePostWait(D::adjust(pixels.loadAndScale1()));
+ writeBytePostWait(D::adjust(pixels.loadAndScale2()));
+ } else {
+ writeByte(D::adjust(pixels.loadAndScale0()));
+ writeByte(D::adjust(pixels.loadAndScale1()));
+ writeByte(D::adjust(pixels.loadAndScale2()));
+ }
+
+ pixels.advanceData();
+ pixels.stepDithering();
+ }
+ D::postBlock(len);
+ release();
+ }
+};
+#endif
+
+#if defined(UBRR0)
+template <uint8_t _DATA_PIN, uint8_t _CLOCK_PIN, uint8_t _SPI_CLOCK_DIVIDER>
+class AVRUSART0SPIOutput {
+ Selectable *m_pSelect;
+
+public:
+ AVRUSART0SPIOutput() { m_pSelect = NULL; }
+ AVRUSART0SPIOutput(Selectable *pSelect) { m_pSelect = pSelect; }
+ void setSelect(Selectable *pSelect) { m_pSelect = pSelect; }
+
+ void init() {
+ UBRR0 = 0;
+
+ /* Set MSPI mode of operation and SPI data mode 0. */
+ UCSR0C = (1<<UMSEL01)|(1<<UMSEL00)/*|(0<<UCPHA0)*/|(0<<UCPOL0);
+ /* Enable receiver and transmitter. */
+ UCSR0B = (1<<RXEN0)|(1<<TXEN0);
+
+ FastPin<_CLOCK_PIN>::setOutput();
+ FastPin<_DATA_PIN>::setOutput();
+
+
+ // must be done last, see page 206
+ setSPIRate();
+ }
+
+ void setSPIRate() {
+ if(_SPI_CLOCK_DIVIDER > 2) {
+ UBRR0 = (_SPI_CLOCK_DIVIDER/2)-1;
+ } else {
+ UBRR0 = 0;
+ }
+ }
+
+ static void stop() {
+ // TODO: stop the uart spi output
+ }
+
+ static bool shouldWait(bool wait = false) __attribute__((always_inline)) {
+ static bool sWait=false;
+ if(sWait) {
+ sWait = wait; return true;
+ } else {
+ sWait = wait; return false;
+ }
+ // return true;
+ }
+ static void wait() __attribute__((always_inline)) {
+ if(shouldWait()) {
+ while(!(UCSR0A & (1<<UDRE0)));
+ }
+ }
+ static void waitFully() __attribute__((always_inline)) { wait(); }
+
+ static void writeWord(uint16_t w) __attribute__((always_inline)) { writeByte(w>>8); writeByte(w&0xFF); }
+
+ static void writeByte(uint8_t b) __attribute__((always_inline)) { wait(); UDR0=b; shouldWait(true); }
+ static void writeBytePostWait(uint8_t b) __attribute__((always_inline)) { UDR0=b; shouldWait(true); wait(); }
+ static void writeByteNoWait(uint8_t b) __attribute__((always_inline)) { UDR0=b; shouldWait(true); }
+
+
+ template <uint8_t BIT> inline static void writeBit(uint8_t b) {
+ if(b && (1 << BIT)) {
+ FastPin<_DATA_PIN>::hi();
+ } else {
+ FastPin<_DATA_PIN>::lo();
+ }
+
+ FastPin<_CLOCK_PIN>::hi();
+ FastPin<_CLOCK_PIN>::lo();
+ }
+
+ void enable_pins() { }
+ void disable_pins() { }
+
+ void select() {
+ if(m_pSelect != NULL) {
+ m_pSelect->select();
+ }
+ enable_pins();
+ setSPIRate();
+ }
+
+ void release() {
+ if(m_pSelect != NULL) {
+ m_pSelect->release();
+ }
+ disable_pins();
+ }
+
+ static void writeBytesValueRaw(uint8_t value, int len) {
+ while(len--) {
+ writeByte(value);
+ }
+ }
+
+ void writeBytesValue(uint8_t value, int len) {
+ //setSPIRate();
+ select();
+ while(len--) {
+ writeByte(value);
+ }
+ release();
+ }
+
+ // Write a block of n uint8_ts out
+ template <class D> void writeBytes(register uint8_t *data, int len) {
+ //setSPIRate();
+ uint8_t *end = data + len;
+ select();
+ while(data != end) {
+ // a slight touch of delay here helps optimize the timing of the status register check loop (not used on ARM)
+ writeByte(D::adjust(*data++)); delaycycles<3>();
+ }
+ release();
+ }
+
+ void writeBytes(register uint8_t *data, int len) { writeBytes<DATA_NOP>(data, len); }
+
+ // write a block of uint8_ts out in groups of three. len is the total number of uint8_ts to write out. The template
+ // parameters indicate how many uint8_ts to skip at the beginning and/or end of each grouping
+ template <uint8_t FLAGS, class D, EOrder RGB_ORDER> void writePixels(PixelController<RGB_ORDER> pixels) {
+ //setSPIRate();
+ int len = pixels.mLen;
+
+ select();
+ while(pixels.has(1)) {
+ if(FLAGS & FLAG_START_BIT) {
+ writeBit<0>(1);
+ writeBytePostWait(D::adjust(pixels.loadAndScale0()));
+ writeBytePostWait(D::adjust(pixels.loadAndScale1()));
+ writeBytePostWait(D::adjust(pixels.loadAndScale2()));
+ } else {
+ writeByte(D::adjust(pixels.loadAndScale0()));
+ writeByte(D::adjust(pixels.loadAndScale1()));
+ writeByte(D::adjust(pixels.loadAndScale2()));
+ }
+
+ pixels.advanceData();
+ pixels.stepDithering();
+ }
+ D::postBlock(len);
+ waitFully();
+ release();
+ }
+};
+
+#endif
+
+
+#if defined(SPSR)
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// Hardware SPI support using SPDR registers and friends
+//
+// Technically speaking, this uses the AVR SPI registers. This will work on the Teensy 3.0 because Paul made a set of compatability
+// classes that map the AVR SPI registers to ARM's, however this caps the performance of output.
+//
+// TODO: implement ARMHardwareSPIOutput
+//
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+template <uint8_t _DATA_PIN, uint8_t _CLOCK_PIN, uint8_t _SPI_CLOCK_DIVIDER>
+class AVRHardwareSPIOutput {
+ Selectable *m_pSelect;
+ bool mWait;
+public:
+ AVRHardwareSPIOutput() { m_pSelect = NULL; mWait = false;}
+ AVRHardwareSPIOutput(Selectable *pSelect) { m_pSelect = pSelect; }
+ void setSelect(Selectable *pSelect) { m_pSelect = pSelect; }
+
+ void setSPIRate() {
+ SPCR &= ~ ( (1<<SPR1) | (1<<SPR0) ); // clear out the prescalar bits
+
+ bool b2x = false;
+
+ if(_SPI_CLOCK_DIVIDER >= 128) { SPCR |= (1<<SPR1); SPCR |= (1<<SPR0); }
+ else if(_SPI_CLOCK_DIVIDER >= 64) { SPCR |= (1<<SPR1);}
+ else if(_SPI_CLOCK_DIVIDER >= 32) { SPCR |= (1<<SPR1); b2x = true; }
+ else if(_SPI_CLOCK_DIVIDER >= 16) { SPCR |= (1<<SPR0); }
+ else if(_SPI_CLOCK_DIVIDER >= 8) { SPCR |= (1<<SPR0); b2x = true; }
+ else if(_SPI_CLOCK_DIVIDER >= 4) { /* do nothing - default rate */ }
+ else { b2x = true; }
+
+ if(b2x) { SPSR |= (1<<SPI2X); }
+ else { SPSR &= ~ (1<<SPI2X); }
+ }
+
+ void init() {
+ volatile uint8_t clr;
+
+ // set the pins to output
+ FastPin<_DATA_PIN>::setOutput();
+ FastPin<_CLOCK_PIN>::setOutput();
+#ifdef SPI_SELECT
+ // Make sure the slave select line is set to output, or arduino will block us
+ FastPin<SPI_SELECT>::setOutput();
+ FastPin<SPI_SELECT>::lo();
+#endif
+
+ SPCR |= ((1<<SPE) | (1<<MSTR) ); // enable SPI as master
+ SPCR &= ~ ( (1<<SPR1) | (1<<SPR0) ); // clear out the prescalar bits
+
+ clr = SPSR; // clear SPI status register
+ clr = SPDR; // clear SPI data register
+ clr;
+
+ bool b2x = false;
+
+ if(_SPI_CLOCK_DIVIDER >= 128) { SPCR |= (1<<SPR1); SPCR |= (1<<SPR0); }
+ else if(_SPI_CLOCK_DIVIDER >= 64) { SPCR |= (1<<SPR1);}
+ else if(_SPI_CLOCK_DIVIDER >= 32) { SPCR |= (1<<SPR1); b2x = true; }
+ else if(_SPI_CLOCK_DIVIDER >= 16) { SPCR |= (1<<SPR0); }
+ else if(_SPI_CLOCK_DIVIDER >= 8) { SPCR |= (1<<SPR0); b2x = true; }
+ else if(_SPI_CLOCK_DIVIDER >= 4) { /* do nothing - default rate */ }
+ else { b2x = true; }
+
+ if(b2x) { SPSR |= (1<<SPI2X); }
+ else { SPSR &= ~ (1<<SPI2X); }
+
+ SPDR=0;
+ shouldWait(false);
+ release();
+ }
+
+ static bool shouldWait(bool wait = false) __attribute__((always_inline)) {
+ static bool sWait=false;
+ if(sWait) { sWait = wait; return true; } else { sWait = wait; return false; }
+ // return true;
+ }
+ static void wait() __attribute__((always_inline)) { if(shouldWait()) { while(!(SPSR & (1<<SPIF))); } }
+ static void waitFully() __attribute__((always_inline)) { wait(); }
+
+ static void writeWord(uint16_t w) __attribute__((always_inline)) { writeByte(w>>8); writeByte(w&0xFF); }
+
+ static void writeByte(uint8_t b) __attribute__((always_inline)) { wait(); SPDR=b; shouldWait(true); }
+ static void writeBytePostWait(uint8_t b) __attribute__((always_inline)) { SPDR=b; shouldWait(true); wait(); }
+ static void writeByteNoWait(uint8_t b) __attribute__((always_inline)) { SPDR=b; shouldWait(true); }
+
+ template <uint8_t BIT> inline static void writeBit(uint8_t b) {
+ SPCR &= ~(1 << SPE);
+ if(b & (1 << BIT)) {
+ FastPin<_DATA_PIN>::hi();
+ } else {
+ FastPin<_DATA_PIN>::lo();
+ }
+
+ FastPin<_CLOCK_PIN>::hi();
+ FastPin<_CLOCK_PIN>::lo();
+ SPCR |= 1 << SPE;
+ shouldWait(false);
+ }
+
+ void enable_pins() {
+ SPCR |= ((1<<SPE) | (1<<MSTR) ); // enable SPI as master
+ }
+
+ void disable_pins() {
+ SPCR &= ~(((1<<SPE) | (1<<MSTR) )); // disable SPI
+ }
+
+ void select() {
+ if(m_pSelect != NULL) { m_pSelect->select(); }
+ enable_pins();
+ setSPIRate();
+ }
+
+ void release() {
+ if(m_pSelect != NULL) { m_pSelect->release(); }
+ disable_pins();
+ }
+
+ static void writeBytesValueRaw(uint8_t value, int len) {
+ while(len--) { writeByte(value); }
+ }
+
+ void writeBytesValue(uint8_t value, int len) {
+ //setSPIRate();
+ select();
+ while(len--) {
+ writeByte(value);
+ }
+ release();
+ }
+
+ // Write a block of n uint8_ts out
+ template <class D> void writeBytes(register uint8_t *data, int len) {
+ //setSPIRate();
+ uint8_t *end = data + len;
+ select();
+ while(data != end) {
+ // a slight touch of delay here helps optimize the timing of the status register check loop (not used on ARM)
+ writeByte(D::adjust(*data++)); delaycycles<3>();
+ }
+ release();
+ }
+
+ void writeBytes(register uint8_t *data, int len) { writeBytes<DATA_NOP>(data, len); }
+
+ // write a block of uint8_ts out in groups of three. len is the total number of uint8_ts to write out. The template
+ // parameters indicate how many uint8_ts to skip at the beginning and/or end of each grouping
+ template <uint8_t FLAGS, class D, EOrder RGB_ORDER> void writePixels(PixelController<RGB_ORDER> pixels) {
+ //setSPIRate();
+ int len = pixels.mLen;
+
+ select();
+ while(pixels.has(1)) {
+ if(FLAGS & FLAG_START_BIT) {
+ writeBit<0>(1);
+ writeBytePostWait(D::adjust(pixels.loadAndScale0()));
+ writeBytePostWait(D::adjust(pixels.loadAndScale1()));
+ writeBytePostWait(D::adjust(pixels.loadAndScale2()));
+ } else {
+ writeByte(D::adjust(pixels.loadAndScale0()));
+ writeByte(D::adjust(pixels.loadAndScale1()));
+ writeByte(D::adjust(pixels.loadAndScale2()));
+ }
+
+ pixels.advanceData();
+ pixels.stepDithering();
+ }
+ D::postBlock(len);
+ waitFully();
+ release();
+ }
+};
+#endif
+
+#else
+// #define FASTLED_FORCE_SOFTWARE_SPI
+#endif
+
+FASTLED_NAMESPACE_END;
+
+
+#endif
diff --git a/Библиотеки/FastLED-master/platforms/avr/led_sysdefs_avr.h b/Библиотеки/FastLED-master/platforms/avr/led_sysdefs_avr.h
new file mode 100644
index 0000000..37f8cff
--- /dev/null
+++ b/Библиотеки/FastLED-master/platforms/avr/led_sysdefs_avr.h
@@ -0,0 +1,54 @@
+#ifndef __INC_LED_SYSDEFS_AVR_H
+#define __INC_LED_SYSDEFS_AVR_H
+
+#define FASTLED_AVR
+
+#ifndef INTERRUPT_THRESHOLD
+#define INTERRUPT_THRESHOLD 2
+#endif
+
+#define FASTLED_SPI_BYTE_ONLY
+
+#include <avr/io.h>
+#include <avr/interrupt.h> // for cli/se definitions
+
+// Define the register types
+#if defined(ARDUINO) // && ARDUINO < 150
+typedef volatile uint8_t RoReg; /**< Read only 8-bit register (volatile const unsigned int) */
+typedef volatile uint8_t RwReg; /**< Read-Write 8-bit register (volatile unsigned int) */
+#endif
+
+
+// Default to disallowing interrupts (may want to gate this on teensy2 vs. other arm platforms, since the
+// teensy2 has a good, fast millis interrupt implementation)
+#ifndef FASTLED_ALLOW_INTERRUPTS
+#define FASTLED_ALLOW_INTERRUPTS 0
+#endif
+
+#if FASTLED_ALLOW_INTERRUPTS == 1
+#define FASTLED_ACCURATE_CLOCK
+#endif
+
+
+// Default to using PROGMEM here
+#ifndef FASTLED_USE_PROGMEM
+#define FASTLED_USE_PROGMEM 1
+#endif
+
+#if defined(ARDUINO_AVR_DIGISPARK) || defined(ARDUINO_AVR_DIGISPARKPRO)
+#ifndef NO_CORRECTION
+#define NO_CORRECTION 1
+#endif
+#endif
+
+extern "C" {
+# if defined(CORE_TEENSY) || defined(TEENSYDUINO)
+extern volatile unsigned long timer0_millis_count;
+# define MS_COUNTER timer0_millis_count
+# else
+extern volatile unsigned long timer0_millis;
+# define MS_COUNTER timer0_millis
+# endif
+};
+
+#endif
diff --git a/Библиотеки/FastLED-master/platforms/esp/8266/clockless_block_esp8266.h b/Библиотеки/FastLED-master/platforms/esp/8266/clockless_block_esp8266.h
new file mode 100644
index 0000000..e3341d1
--- /dev/null
+++ b/Библиотеки/FastLED-master/platforms/esp/8266/clockless_block_esp8266.h
@@ -0,0 +1,159 @@
+#ifndef __INC_CLOCKLESS_BLOCK_ESP8266_H
+#define __INC_CLOCKLESS_BLOCK_ESP8266_H
+
+#define FASTLED_HAS_BLOCKLESS 1
+
+#define FIX_BITS(bits) (((bits & 0x0fL) << 12) | (bits & 0x30))
+
+#define MIN(X,Y) (((X)<(Y)) ? (X):(Y))
+#define USED_LANES (MIN(LANES, 6))
+#define PORT_MASK (((1 << USED_LANES)-1) & 0x0000FFFFL)
+#define PIN_MASK FIX_BITS(PORT_MASK)
+
+FASTLED_NAMESPACE_BEGIN
+
+#ifdef FASTLED_DEBUG_COUNT_FRAME_RETRIES
+extern uint32_t _frame_cnt;
+extern uint32_t _retry_cnt;
+#endif
+
+template <uint8_t LANES, int FIRST_PIN, int T1, int T2, int T3, EOrder RGB_ORDER = GRB, int XTRA0 = 0, bool FLIP = false, int WAIT_TIME = 5>
+class InlineBlockClocklessController : public CPixelLEDController<RGB_ORDER, LANES, PORT_MASK> {
+ typedef typename FastPin<FIRST_PIN>::port_ptr_t data_ptr_t;
+ typedef typename FastPin<FIRST_PIN>::port_t data_t;
+
+ CMinWait<WAIT_TIME> mWait;
+public:
+ virtual int size() { return CLEDController::size() * LANES; }
+
+ virtual void showPixels(PixelController<RGB_ORDER, LANES, PORT_MASK> & pixels) {
+ // mWait.wait();
+ /*uint32_t clocks = */
+ int cnt=FASTLED_INTERRUPT_RETRY_COUNT;
+ while(!showRGBInternal(pixels) && cnt--) {
+ os_intr_unlock();
+ #ifdef FASTLED_DEBUG_COUNT_FRAME_RETRIES
+ _retry_cnt++;
+ #endif
+ delayMicroseconds(WAIT_TIME * 10);
+ os_intr_lock();
+ }
+ // #if FASTLED_ALLOW_INTTERUPTS == 0
+ // Adjust the timer
+ // long microsTaken = CLKS_TO_MICROS(clocks);
+ // MS_COUNTER += (1 + (microsTaken / 1000));
+ // #endif
+
+ // mWait.mark();
+ }
+
+ template<int PIN> static void initPin() {
+ _ESPPIN<PIN, 1<<(PIN & 0xFF)>::setOutput();
+ }
+
+ virtual void init() {
+ void (* funcs[])() ={initPin<12>, initPin<13>, initPin<14>, initPin<15>, initPin<4>, initPin<5>};
+
+ for (uint8_t i = 0; i < USED_LANES; ++i) {
+ funcs[i]();
+ }
+ }
+
+ virtual uint16_t getMaxRefreshRate() const { return 400; }
+
+ typedef union {
+ uint8_t bytes[8];
+ uint16_t shorts[4];
+ uint32_t raw[2];
+ } Lines;
+
+#define ESP_ADJUST 0 // (2*(F_CPU/24000000))
+#define ESP_ADJUST2 0
+ template<int BITS,int PX> __attribute__ ((always_inline)) inline static void writeBits(register uint32_t & last_mark, register Lines & b, PixelController<RGB_ORDER, LANES, PORT_MASK> &pixels) { // , register uint32_t & b2) {
+ Lines b2 = b;
+ transpose8x1_noinline(b.bytes,b2.bytes);
+
+ register uint8_t d = pixels.template getd<PX>(pixels);
+ register uint8_t scale = pixels.template getscale<PX>(pixels);
+
+ for(register uint32_t i = 0; i < USED_LANES; i++) {
+ while((__clock_cycles() - last_mark) < (T1+T2+T3));
+ last_mark = __clock_cycles();
+ *FastPin<FIRST_PIN>::sport() = PIN_MASK;
+
+ uint32_t nword = (uint32_t)(~b2.bytes[7-i]);
+ while((__clock_cycles() - last_mark) < (T1-6));
+ *FastPin<FIRST_PIN>::cport() = FIX_BITS(nword);
+
+ while((__clock_cycles() - last_mark) < (T1+T2));
+ *FastPin<FIRST_PIN>::cport() = PIN_MASK;
+
+ b.bytes[i] = pixels.template loadAndScale<PX>(pixels,i,d,scale);
+ }
+
+ for(register uint32_t i = USED_LANES; i < 8; i++) {
+ while((__clock_cycles() - last_mark) < (T1+T2+T3));
+ last_mark = __clock_cycles();
+ *FastPin<FIRST_PIN>::sport() = PIN_MASK;
+
+ uint32_t nword = (uint32_t)(~b2.bytes[7-i]);
+ while((__clock_cycles() - last_mark) < (T1-6));
+ *FastPin<FIRST_PIN>::cport() = FIX_BITS(nword);
+
+ while((__clock_cycles() - last_mark) < (T1+T2));
+ *FastPin<FIRST_PIN>::cport() = PIN_MASK;
+ }
+ }
+
+ // This method is made static to force making register Y available to use for data on AVR - if the method is non-static, then
+ // gcc will use register Y for the this pointer.
+ static uint32_t ICACHE_RAM_ATTR showRGBInternal(PixelController<RGB_ORDER, LANES, PORT_MASK> &allpixels) {
+
+ // Setup the pixel controller and load/scale the first byte
+ Lines b0;
+
+ for(int i = 0; i < USED_LANES; i++) {
+ b0.bytes[i] = allpixels.loadAndScale0(i);
+ }
+ allpixels.preStepFirstByteDithering();
+
+ os_intr_lock();
+ uint32_t _start = __clock_cycles();
+ uint32_t last_mark = _start;
+
+ while(allpixels.has(1)) {
+ // Write first byte, read next byte
+ writeBits<8+XTRA0,1>(last_mark, b0, allpixels);
+
+ // Write second byte, read 3rd byte
+ writeBits<8+XTRA0,2>(last_mark, b0, allpixels);
+ allpixels.advanceData();
+
+ // Write third byte
+ writeBits<8+XTRA0,0>(last_mark, b0, allpixels);
+
+ #if (FASTLED_ALLOW_INTERRUPTS == 1)
+ os_intr_unlock();
+ #endif
+
+ allpixels.stepDithering();
+
+ #if (FASTLED_ALLOW_INTERRUPTS == 1)
+ os_intr_lock();
+ // if interrupts took longer than 45µs, punt on the current frame
+ if((int32_t)(__clock_cycles()-last_mark) > 0) {
+ if((int32_t)(__clock_cycles()-last_mark) > (T1+T2+T3+((WAIT_TIME-INTERRUPT_THRESHOLD)*CLKS_PER_US))) { os_intr_unlock(); return 0; }
+ }
+ #endif
+ };
+
+ os_intr_unlock();
+ #ifdef FASTLED_DEBUG_COUNT_FRAME_RETRIES
+ _frame_cnt++;
+ #endif
+ return __clock_cycles() - _start;
+ }
+};
+
+FASTLED_NAMESPACE_END
+#endif
diff --git a/Библиотеки/FastLED-master/platforms/esp/8266/clockless_esp8266.h b/Библиотеки/FastLED-master/platforms/esp/8266/clockless_esp8266.h
new file mode 100644
index 0000000..20ae641
--- /dev/null
+++ b/Библиотеки/FastLED-master/platforms/esp/8266/clockless_esp8266.h
@@ -0,0 +1,117 @@
+#pragma once
+
+FASTLED_NAMESPACE_BEGIN
+
+#ifdef FASTLED_DEBUG_COUNT_FRAME_RETRIES
+extern uint32_t _frame_cnt;
+extern uint32_t _retry_cnt;
+#endif
+
+// Info on reading cycle counter from https://github.com/kbeckmann/nodemcu-firmware/blob/ws2812-dual/app/modules/ws2812.c
+__attribute__ ((always_inline)) inline static uint32_t __clock_cycles() {
+ uint32_t cyc;
+ __asm__ __volatile__ ("rsr %0,ccount":"=a" (cyc));
+ return cyc;
+}
+
+#define FASTLED_HAS_CLOCKLESS 1
+
+template <int DATA_PIN, int T1, int T2, int T3, EOrder RGB_ORDER = RGB, int XTRA0 = 0, bool FLIP = false, int WAIT_TIME = 5>
+class ClocklessController : public CPixelLEDController<RGB_ORDER> {
+ typedef typename FastPin<DATA_PIN>::port_ptr_t data_ptr_t;
+ typedef typename FastPin<DATA_PIN>::port_t data_t;
+
+ data_t mPinMask;
+ data_ptr_t mPort;
+ CMinWait<WAIT_TIME> mWait;
+public:
+ virtual void init() {
+ FastPin<DATA_PIN>::setOutput();
+ mPinMask = FastPin<DATA_PIN>::mask();
+ mPort = FastPin<DATA_PIN>::port();
+ }
+
+ virtual uint16_t getMaxRefreshRate() const { return 400; }
+
+protected:
+
+ virtual void showPixels(PixelController<RGB_ORDER> & pixels) {
+ // mWait.wait();
+ int cnt = FASTLED_INTERRUPT_RETRY_COUNT;
+ while((showRGBInternal(pixels)==0) && cnt--) {
+ #ifdef FASTLED_DEBUG_COUNT_FRAME_RETRIES
+ _retry_cnt++;
+ #endif
+ os_intr_unlock();
+ delayMicroseconds(WAIT_TIME);
+ os_intr_lock();
+ }
+ // mWait.mark();
+ }
+
+#define _ESP_ADJ (0)
+#define _ESP_ADJ2 (0)
+
+ template<int BITS> __attribute__ ((always_inline)) inline static void writeBits(register uint32_t & last_mark, register uint32_t b) {
+ b = ~b; b <<= 24;
+ for(register uint32_t i = BITS; i > 0; i--) {
+ while((__clock_cycles() - last_mark) < (T1+T2+T3));
+ last_mark = __clock_cycles();
+ FastPin<DATA_PIN>::hi();
+
+ while((__clock_cycles() - last_mark) < T1);
+ if(b & 0x80000000L) { FastPin<DATA_PIN>::lo(); }
+ b <<= 1;
+
+ while((__clock_cycles() - last_mark) < (T1+T2));
+ FastPin<DATA_PIN>::lo();
+ }
+ }
+
+ // This method is made static to force making register Y available to use for data on AVR - if the method is non-static, then
+ // gcc will use register Y for the this pointer.
+ static uint32_t ICACHE_RAM_ATTR showRGBInternal(PixelController<RGB_ORDER> pixels) {
+ // Setup the pixel controller and load/scale the first byte
+ pixels.preStepFirstByteDithering();
+ register uint32_t b = pixels.loadAndScale0();
+ pixels.preStepFirstByteDithering();
+ os_intr_lock();
+ uint32_t start = __clock_cycles();
+ uint32_t last_mark = start;
+ while(pixels.has(1)) {
+ // Write first byte, read next byte
+ writeBits<8+XTRA0>(last_mark, b);
+ b = pixels.loadAndScale1();
+
+ // Write second byte, read 3rd byte
+ writeBits<8+XTRA0>(last_mark, b);
+ b = pixels.loadAndScale2();
+
+ // Write third byte, read 1st byte of next pixel
+ writeBits<8+XTRA0>(last_mark, b);
+ b = pixels.advanceAndLoadAndScale0();
+
+ #if (FASTLED_ALLOW_INTERRUPTS == 1)
+ os_intr_unlock();
+ #endif
+
+ pixels.stepDithering();
+
+ #if (FASTLED_ALLOW_INTERRUPTS == 1)
+ os_intr_lock();
+ // if interrupts took longer than 45µs, punt on the current frame
+ if((int32_t)(__clock_cycles()-last_mark) > 0) {
+ if((int32_t)(__clock_cycles()-last_mark) > (T1+T2+T3+((WAIT_TIME-INTERRUPT_THRESHOLD)*CLKS_PER_US))) { sei(); return 0; }
+ }
+ #endif
+ };
+
+ os_intr_unlock();
+ #ifdef FASTLED_DEBUG_COUNT_FRAME_RETRIES
+ _frame_cnt++;
+ #endif
+ return __clock_cycles() - start;
+ }
+};
+
+FASTLED_NAMESPACE_END
diff --git a/Библиотеки/FastLED-master/platforms/esp/8266/fastled_esp8266.h b/Библиотеки/FastLED-master/platforms/esp/8266/fastled_esp8266.h
new file mode 100644
index 0000000..d209de9
--- /dev/null
+++ b/Библиотеки/FastLED-master/platforms/esp/8266/fastled_esp8266.h
@@ -0,0 +1,7 @@
+#pragma once
+
+#include "bitswap.h"
+#include "fastled_delay.h"
+#include "fastpin_esp8266.h"
+#include "clockless_esp8266.h"
+#include "clockless_block_esp8266.h"
diff --git a/Библиотеки/FastLED-master/platforms/esp/8266/fastpin_esp8266.h b/Библиотеки/FastLED-master/platforms/esp/8266/fastpin_esp8266.h
new file mode 100644
index 0000000..b8095b8
--- /dev/null
+++ b/Библиотеки/FastLED-master/platforms/esp/8266/fastpin_esp8266.h
@@ -0,0 +1,101 @@
+#pragma once
+
+FASTLED_NAMESPACE_BEGIN
+
+struct FASTLED_ESP_IO {
+ volatile uint32_t _GPO;
+ volatile uint32_t _GPOS;
+ volatile uint32_t _GPOC;
+};
+
+#define _GPB (*(FASTLED_ESP_IO*)(0x60000000+(0x300)))
+
+
+template<uint8_t PIN, uint32_t MASK> class _ESPPIN {
+
+public:
+ typedef volatile uint32_t * port_ptr_t;
+ typedef uint32_t port_t;
+
+ inline static void setOutput() { pinMode(PIN, OUTPUT); }
+ inline static void setInput() { pinMode(PIN, INPUT); }
+
+ inline static void hi() __attribute__ ((always_inline)) { if(PIN < 16) { _GPB._GPOS = MASK; } else { GP16O |= MASK; } }
+ inline static void lo() __attribute__ ((always_inline)) { if(PIN < 16) { _GPB._GPOC = MASK; } else { GP16O &= ~MASK; } }
+ inline static void set(register port_t val) __attribute__ ((always_inline)) { if(PIN < 16) { _GPB._GPO = val; } else { GP16O = val; }}
+
+ inline static void strobe() __attribute__ ((always_inline)) { toggle(); toggle(); }
+
+ inline static void toggle() __attribute__ ((always_inline)) { if(PIN < 16) { _GPB._GPO ^= MASK; } else { GP16O ^= MASK; } }
+
+ inline static void hi(register port_ptr_t port) __attribute__ ((always_inline)) { hi(); }
+ inline static void lo(register port_ptr_t port) __attribute__ ((always_inline)) { lo(); }
+ inline static void fastset(register port_ptr_t port, register port_t val) __attribute__ ((always_inline)) { *port = val; }
+
+ inline static port_t hival() __attribute__ ((always_inline)) { if (PIN<16) { return GPO | MASK; } else { return GP16O | MASK; } }
+ inline static port_t loval() __attribute__ ((always_inline)) { if (PIN<16) { return GPO & ~MASK; } else { return GP16O & ~MASK; } }
+ inline static port_ptr_t port() __attribute__ ((always_inline)) { if(PIN<16) { return &_GPB._GPO; } else { return &GP16O; } }
+ inline static port_ptr_t sport() __attribute__ ((always_inline)) { return &_GPB._GPOS; } // there is no GP160 support for this
+ inline static port_ptr_t cport() __attribute__ ((always_inline)) { return &_GPB._GPOC; }
+ inline static port_t mask() __attribute__ ((always_inline)) { return MASK; }
+
+ inline static bool isset() __attribute__ ((always_inline)) { return (PIN < 16) ? (GPO & MASK) : (GP16O & MASK); }
+};
+
+#define _DEFPIN_ESP8266(PIN, REAL_PIN) template<> class FastPin<PIN> : public _ESPPIN<REAL_PIN, (1<<(REAL_PIN & 0xFF))> {};
+
+
+#ifdef FASTLED_ESP8266_RAW_PIN_ORDER
+#define MAX_PIN 16
+_DEFPIN_ESP8266(0,0); _DEFPIN_ESP8266(1,1); _DEFPIN_ESP8266(2,2); _DEFPIN_ESP8266(3,3);
+_DEFPIN_ESP8266(4,4); _DEFPIN_ESP8266(5,5);
+
+// These pins should be disabled, as they always cause WDT resets
+// _DEFPIN_ESP8266(6,6); _DEFPIN_ESP8266(7,7);
+// _DEFPIN_ESP8266(8,8); _DEFPIN_ESP8266(9,9); _DEFPIN_ESP8266(10,10); _DEFPIN_ESP8266(11,11);
+
+_DEFPIN_ESP8266(12,12); _DEFPIN_ESP8266(13,13); _DEFPIN_ESP8266(14,14); _DEFPIN_ESP8266(15,15);
+_DEFPIN_ESP8266(16,16);
+
+#define PORTA_FIRST_PIN 12
+#elif defined(FASTLED_ESP8266_D1_PIN_ORDER)
+#define MAX_PIN 15
+_DEFPIN_ESP8266(0,3);
+_DEFPIN_ESP8266(1,1);
+_DEFPIN_ESP8266(2,16);
+_DEFPIN_ESP8266(3,5);
+_DEFPIN_ESP8266(4,4);
+_DEFPIN_ESP8266(5,14);
+_DEFPIN_ESP8266(6,12);
+_DEFPIN_ESP8266(7,13);
+_DEFPIN_ESP8266(8,0);
+_DEFPIN_ESP8266(9,2);
+_DEFPIN_ESP8266(10,15);
+_DEFPIN_ESP8266(11,13);
+_DEFPIN_ESP8266(12,12);
+_DEFPIN_ESP8266(13,14);
+_DEFPIN_ESP8266(14,4);
+_DEFPIN_ESP8266(15,5);
+
+#define PORTA_FIRST_PIN 12
+
+#else // if defined(FASTLED_ESP8266_NODEMCU_PIN_ORDER)
+#define MAX_PIN 10
+
+// This seems to be the standard Dxx pin mapping on most of the esp boards that i've found
+_DEFPIN_ESP8266(0,16); _DEFPIN_ESP8266(1,5); _DEFPIN_ESP8266(2,4); _DEFPIN_ESP8266(3,0);
+_DEFPIN_ESP8266(4,2); _DEFPIN_ESP8266(5,14); _DEFPIN_ESP8266(6,12); _DEFPIN_ESP8266(7,13);
+_DEFPIN_ESP8266(8,15); _DEFPIN_ESP8266(9,3); _DEFPIN_ESP8266(10,1);
+
+#define PORTA_FIRST_PIN 6
+
+// The rest of the pins - these are generally not available
+// _DEFPIN_ESP8266(11,6);
+// _DEFPIN_ESP8266(12,7); _DEFPIN_ESP8266(13,8); _DEFPIN_ESP8266(14,9); _DEFPIN_ESP8266(15,10);
+// _DEFPIN_ESP8266(16,11);
+
+#endif
+
+#define HAS_HARDWARE_PIN_SUPPORT
+
+#define FASTLED_NAMESPACE_END
diff --git a/Библиотеки/FastLED-master/platforms/esp/8266/led_sysdefs_esp8266.h b/Библиотеки/FastLED-master/platforms/esp/8266/led_sysdefs_esp8266.h
new file mode 100644
index 0000000..a3f6ac3
--- /dev/null
+++ b/Библиотеки/FastLED-master/platforms/esp/8266/led_sysdefs_esp8266.h
@@ -0,0 +1,39 @@
+#pragma once
+
+#ifndef ESP8266
+#define ESP8266
+#endif
+
+#define FASTLED_ESP8266
+
+// Use system millis timer
+#define FASTLED_HAS_MILLIS
+
+typedef volatile uint32_t RoReg;
+typedef volatile uint32_t RwReg;
+typedef uint32_t prog_uint32_t;
+typedef uint8_t boolean;
+
+// Default to NOT using PROGMEM here
+#ifndef FASTLED_USE_PROGMEM
+# define FASTLED_USE_PROGMEM 0
+#endif
+
+#ifndef FASTLED_ALLOW_INTERRUPTS
+# define FASTLED_ALLOW_INTERRUPTS 1
+# define INTERRUPT_THRESHOLD 0
+#endif
+
+#define NEED_CXX_BITS
+
+// These can be overridden
+#if !defined(FASTLED_ESP8266_RAW_PIN_ORDER) && !defined(FASTLED_ESP8266_NODEMCU_PIN_ORDER) && !defined(FASTLED_ESP8266_D1_PIN_ORDER)
+# ifdef ARDUINO_ESP8266_NODEMCU
+# define FASTLED_ESP8266_NODEMCU_PIN_ORDER
+# else
+# define FASTLED_ESP8266_RAW_PIN_ORDER
+# endif
+#endif
+
+// #define cli() os_intr_lock();
+// #define sei() os_intr_lock();