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:
Diffstat (limited to 'Библиотеки/FastLED-master/platforms/avr')
-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
5 files changed, 1367 insertions, 0 deletions
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