-- cgit v1.2.3 From f3ef3ff5235f1bb580ddce7a192fbd0888983b1b Mon Sep 17 00:00:00 2001 From: "danielgarcia@gmail.com" Date: Sun, 2 Jun 2013 17:07:46 +0000 Subject: checkpointing tm1829 code --- FastSPI_LED2.h | 5 +++- chipsets.h | 35 +++++++++++++++++++++++---- clockless.h | 54 +++++++++++++++++++++++------------------- examples/Fast2Dev/Fast2Dev.ino | 10 +++++--- 4 files changed, 71 insertions(+), 33 deletions(-) diff --git a/FastSPI_LED2.h b/FastSPI_LED2.h index c601be3b..86bc5a3b 100644 --- a/FastSPI_LED2.h +++ b/FastSPI_LED2.h @@ -21,7 +21,8 @@ enum EClocklessChipsets { TM1809, TM1803, WS2811, - UCS1903 + UCS1903, + TM1829 }; #define NUM_CONTROLLERS 8 @@ -80,6 +81,7 @@ public: #ifdef FASTSPI_USE_DMX_SIMPLE case DMX: return addLeds(new DMXController(), data, nLedsOrOffset, nLedsIfOffset); #endif + case TM1829: return addLeds(new TM1829Controller800Khz(), data, nLedsOrOffset, nLedsIfOffset); case TM1809: return addLeds(new TM1809Controller800Khz(), data, nLedsOrOffset, nLedsIfOffset); case TM1803: return addLeds(new TM1803Controller400Khz(), data, nLedsOrOffset, nLedsIfOffset); case UCS1903: return addLeds(new UCS1903Controller400Khz(), data, nLedsOrOffset, nLedsIfOffset); @@ -93,6 +95,7 @@ public: #ifdef FASTSPI_USE_DMX_SIMPLE case DMX: return addLeds(new DMXController(), data, nLedsOrOffset, nLedsIfOffset); #endif + case TM1829: return addLeds(new TM1829Controller800Khz(), data, nLedsOrOffset, nLedsIfOffset); case TM1809: return addLeds(new TM1809Controller800Khz(), data, nLedsOrOffset, nLedsIfOffset); case TM1803: return addLeds(new TM1803Controller400Khz(), data, nLedsOrOffset, nLedsIfOffset); case UCS1903: return addLeds(new UCS1903Controller400Khz(), data, nLedsOrOffset, nLedsIfOffset); diff --git a/chipsets.h b/chipsets.h index 999fda1f..fe24560e 100644 --- a/chipsets.h +++ b/chipsets.h @@ -231,7 +231,7 @@ class UCS1903Controller400Mhz : public ClocklessController class UCS1903Controller400Khz : public ClocklessController {}; #if NO_TIME(500, 1500, 500) -#warning "No enough clock cycles available for the UCS103" +#warning "Not enough clock cycles available for the UCS103" #endif // TM1809 - 312.5ns, 312.5ns, 325ns @@ -240,7 +240,7 @@ class TM1809Controller800Mhz : public ClocklessController class TM1809Controller800Khz : public ClocklessController {}; #if NO_TIME(350, 350, 550) -#warning "No enough clock cycles available for the UCS103" +#warning "Not enough clock cycles available for the UCS103" #endif // WS2811 - 350n, 350ns, 550ns @@ -249,7 +249,7 @@ class WS2811Controller800Mhz : public ClocklessController class WS2811Controller800Khz : public ClocklessController {}; #if NO_TIME(320, 320, 550) -#warning "No enough clock cycles available for the UCS103" +#warning "Not enough clock cycles available for the UCS103" #endif // 750NS, 750NS, 750NS @@ -258,7 +258,34 @@ class TM1803Controller400Mhz : public ClocklessController class TM1803Controller400Khz : public ClocklessController {}; #if NO_TIME(750, 750, 750) -#warning "No enough clock cycles available for the UCS103" +#warning "Not enough clock cycles available for the UCS103" +#endif + +template +class TM1829Controller800Khz : public ClocklessController { +public: + // virtual void show(const struct CRGB *data, int nLeds, uint8_t scale = 255) { + // ClocklessController::show(data, nLeds, scale8(scale, 254)); + // } + + // virtual void showColor(const struct CRGB &data, int nLeds, uint8_t scale = 255) { + // ClocklessController::showColor(data, nLeds, scale8(scale, 254)); + // } +}; + +template +class TM1829Controller1600Khz : public ClocklessController { +public: + virtual void show(const struct CRGB *data, int nLeds, uint8_t scale = 255) { + ClocklessController::show(data, nLeds, scale8(scale, 254)); + } + + virtual void showColor(const struct CRGB &data, int nLeds, uint8_t scale = 255) { + ClocklessController::showColor(data, nLeds, scale8(scale, 254)); + } +}; +#if NO_TIME(100, 300, 200) +#warning "Not enough clock cycles available for TM1829@12v" #endif #endif diff --git a/clockless.h b/clockless.h index 81f0811f..b4e33462 100644 --- a/clockless.h +++ b/clockless.h @@ -32,7 +32,11 @@ extern volatile unsigned long timer0_millis; // ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -template +// Convinience macros to wrap around the toggling of hi vs. lo +#define SET_LO FLIP ? FastPin::fastset(port, hi) : FastPin::fastset(port, lo) +#define SET_HI FLIP ? FastPin::fastset(port, lo) : FastPin::fastset(port, hi) + +template class ClocklessController : public CLEDController { typedef typename FastPin::port_ptr_t data_ptr_t; typedef typename FastPin::port_t data_t; @@ -52,16 +56,16 @@ public: #else template inline static void bitSetFast(register data_ptr_t port, register data_t hi, register data_t lo, register uint8_t b) { // First cycle - FastPin::fastset(port, hi); // 1/2 clock cycle if using out + SET_HI; // 1/2 clock cycle if using out delaycycles(); // 1st cycle length minus 1/2 clock for out, 1 clock for sbrs __asm__ __volatile__ ("sbrs %0, %1" :: "r" (b), "M" (N) :); // 1 clock for check (+1 if skipping, next op is also 1 clock) // Second cycle - FastPin::fastset(port, lo); // 1/2 clock cycle if using out + SET_LO; // 1/2 clock cycle if using out delaycycles(); // 2nd cycle length minus 1/2 clock for out // Third cycle - FastPin::fastset(port, lo); // 1 clock cycle if using out + SET_LO; // 1 clock cycle if using out delaycycles(); // 3rd cycle length minus 1 clock for out } @@ -69,16 +73,16 @@ public: #define END_OF_LOOP 6 // loop compare, jump, next uint8_t load template inline static void bitSetLast(register data_ptr_t port, register data_t hi, register data_t lo, register uint8_t b) { // First cycle - FastPin::fastset(port, hi); // 1 clock cycle if using out, 2 otherwise + SET_HI; // 1 clock cycle if using out, 2 otherwise delaycycles(); // 1st cycle length minus 1 clock for out, 1 clock for sbrs __asm__ __volatile__ ("sbrs %0, %1" :: "r" (b), "M" (N) :); // 1 clock for check (+1 if skipping, next op is also 1 clock) // Second cycle - FastPin::fastset(port, lo); // 1/2 clock cycle if using out + SET_LO; // 1/2 clock cycle if using out delaycycles(); // 2nd cycle length minus 1/2 clock for out // Third cycle - FastPin::fastset(port, lo); // 1/2 clock cycle if using out + SET_LO; // 1/2 clock cycle if using out delaycycles(); // 3rd cycle length minus 7 clocks for out, loop compare, jump, next uint8_t load } #endif @@ -165,23 +169,23 @@ public: // TODO: hand rig asm version of this method. The timings are based on adjusting/studying GCC compiler ouptut. This // will bite me in the ass at some point, I know it. for(register uint32_t i = 7; i > 0; i--) { - FastPin::fastset(port, hi); + SET_HI; delaycycles(); // 3 cycles - 1 store, 1 test, 1 if - if(b & 0x80) { FastPin::fastset(port, hi); } else { FastPin::fastset(port, lo); } + if(b & 0x80) { SET_HI; } else { SET_LO; } b <<= 1; delaycycles(); // 3 cycles, 1 store, 1 store/skip, 1 shift - FastPin::fastset(port, lo); + SET_LO; delaycycles(); // 3 cycles, 1 store, 1 sub, 1 branch backwards } // extra delay because branch is faster falling through delaycycles<1>(); // 8th bit, interleave loading rest of data - FastPin::fastset(port, hi); + SET_HI; delaycycles(); - if(b & 0x80) { FastPin::fastset(port, hi); } else { FastPin::fastset(port, lo); } + if(b & 0x80) { SET_HI; } else { SET_LO; } delaycycles(); // 4 cycles, 2 store, store/skip - FastPin::fastset(port, lo); + SET_LO; if(ADVANCE) { b = data[SKIP + RGB_BYTE1(RGB_ORDER)]; @@ -193,23 +197,23 @@ public: delaycycles(); // 1 store, 2 load, 1 mul, 1 shift, for(register uint32_t i = 7; i > 0; i--) { - FastPin::fastset(port, hi); + SET_HI; delaycycles(); // 3 cycles - 1 store, 1 test, 1 if - if(b & 0x80) { FastPin::fastset(port, hi); } else { FastPin::fastset(port, lo); } + if(b & 0x80) { SET_HI; } else { SET_LO; } b <<= 1; delaycycles(); // 3 cycles, 1 store, 1 store/skip, 1 shift - FastPin::fastset(port, lo); + SET_LO; delaycycles(); // 3 cycles, 1 store, 1 sub, 1 branch backwards } // extra delay because branch is faster falling through delaycycles<1>(); // 8th bit, interleave loading rest of data - FastPin::fastset(port, hi); + SET_HI; delaycycles(); - if(b & 0x80) { FastPin::fastset(port, hi); } else { FastPin::fastset(port, lo); } + if(b & 0x80) { SET_HI; } else { SET_LO; } delaycycles(); // 4 cycles, 2 store, store/skip - FastPin::fastset(port, lo); + SET_LO; if(ADVANCE) { b = data[SKIP + RGB_BYTE2(RGB_ORDER)]; @@ -226,23 +230,23 @@ public: } for(register uint32_t i = 7; i > 0; i--) { - FastPin::fastset(port, hi); + SET_HI; delaycycles(); // 3 cycles - 1 store, 1 test, 1 if - if(b & 0x80) { FastPin::fastset(port, hi); } else { FastPin::fastset(port, lo); } + if(b & 0x80) { SET_HI; } else { SET_LO; } b <<= 1; delaycycles(); // 3 cycles, 1 store, 1 store/skip, 1 shift - FastPin::fastset(port, lo); + SET_LO; delaycycles(); // 3 cycles, 1 store, 1 sub, 1 branch backwards } // extra delay because branch is faster falling through delaycycles<1>(); // 8th bit, interleave loading rest of data - FastPin::fastset(port, hi); + SET_HI; delaycycles(); - if(b & 0x80) { FastPin::fastset(port, hi); } else { FastPin::fastset(port, lo); } + if(b & 0x80) { SET_HI; } else { SET_LO; } delaycycles(); // 4 cycles, 2 store, store/skip - FastPin::fastset(port, lo); + SET_LO; if(ADVANCE) { b = data[SKIP + RGB_BYTE0(RGB_ORDER)]; diff --git a/examples/Fast2Dev/Fast2Dev.ino b/examples/Fast2Dev/Fast2Dev.ino index a64b7890..df7916bf 100644 --- a/examples/Fast2Dev/Fast2Dev.ino +++ b/examples/Fast2Dev/Fast2Dev.ino @@ -16,7 +16,7 @@ // ////////////////////////////////////////////////// -#define NUM_LEDS 150 +#define NUM_LEDS 15 struct CRGB leds[NUM_LEDS]; @@ -29,11 +29,13 @@ void setup() { LEDS.setBrightness(64); // LEDS.addLeds(leds, NUM_LEDS); - // LEDS.addLeds(leds, NUM_LEDS); + LEDS.addLeds(leds, NUM_LEDS); // LEDS.addLeds(leds, NUM_LEDS); // LEDS.addLeds(leds, NUM_LEDS); + // LEDS.addLeds(leds, NUM_LEDS); - LEDS.addLeds(leds, NUM_LEDS)->clearLeds(300); + // LEDS.addLeds(leds, NUM_LEDS); + // LEDS.addLeds(leds, NUM_LEDS); // LEDS.addLeds(leds, NUM_LEDS); // LEDS.addLeds(leds, NUM_LEDS); @@ -48,6 +50,8 @@ void setup() { } void loop() { + // LEDS.clear(); for(;;); + for(int i = 0; i < 3; i++) { for(int iLed = 0; iLed < NUM_LEDS; iLed++) { memset(leds, 0, NUM_LEDS * sizeof(struct CRGB)); -- cgit v1.2.3 From 99acbfb606381394581227d28a9ff72bcb48b0ce Mon Sep 17 00:00:00 2001 From: "danielgarcia@gmail.com" Date: Thu, 6 Jun 2013 18:13:40 +0000 Subject: Add the toggle method to AVR pin --- fastpin.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fastpin.h b/fastpin.h index 6a94df28..b88f1522 100644 --- a/fastpin.h +++ b/fastpin.h @@ -153,6 +153,8 @@ public: inline static void strobe() __attribute__ ((always_inline)) { hi(); lo(); } + 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); } -- cgit v1.2.3 From 607af7895ab01b0041744a5e6e6d9b891b7af4d8 Mon Sep 17 00:00:00 2001 From: "danielgarcia@gmail.com" Date: Thu, 6 Jun 2013 18:18:39 +0000 Subject: make sure everything has toggle, actually --- fastpin.h | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/fastpin.h b/fastpin.h index b88f1522..d11e6d2d 100644 --- a/fastpin.h +++ b/fastpin.h @@ -44,10 +44,12 @@ class Pin : public Selectable { uint8_t mPinMask; uint8_t mPin; volatile uint8_t *mPort; + volatile uint8_t *mInPort; void _init() { mPinMask = digitalPinToBitMask(mPin); mPort = portOutputRegister(digitalPinToPort(mPin)); + mInPort = portInputRegister(digitalPinToPort(mPin)); } public: Pin(int pin) : mPin(pin) { _init(); } @@ -61,7 +63,8 @@ public: inline void hi() __attribute__ ((always_inline)) { *mPort |= mPinMask; } inline void lo() __attribute__ ((always_inline)) { *mPort &= ~mPinMask; } - inline void strobe() __attribute__ ((always_inline)) { hi(); lo(); } + inline void strobe() __attribute__ ((always_inline)) { toggle(); toggle(); } + inline void toggle() __attribute__ ((always_inline)) { *mInPort = mPinMask; } inline void hi(register port_ptr_t port) __attribute__ ((always_inline)) { *port |= mPinMask; } inline void lo(register port_ptr_t port) __attribute__ ((always_inline)) { *port &= ~mPinMask; } @@ -106,9 +109,11 @@ public: template class FastPin { static uint8_t sPinMask; static volatile uint8_t *sPort; + static volatile uint8_t *sInPort; static void _init() { sPinMask = digitalPinToBitMask(PIN); sPort = portOutputRegister(digitalPinToPort(PIN)); + sInPort = portInputRegister(digitalPinToPort(PIN)); } public: typedef volatile uint8_t * port_ptr_t; @@ -120,7 +125,9 @@ public: inline static void hi() __attribute__ ((always_inline)) { *sPort |= sPinMask; } inline static void lo() __attribute__ ((always_inline)) { *sPort &= ~sPinMask; } - inline static void strobe() __attribute__ ((always_inline)) { hi(); lo(); } + inline static void strobe() __attribute__ ((always_inline)) { toggle(); toggle(); } + + inline static void toggle() __attribute__ ((always_inline)) { *sInPort = sPinMask; } inline static void hi(register port_ptr_t port) __attribute__ ((always_inline)) { *port |= sPinMask; } inline static void lo(register port_ptr_t port) __attribute__ ((always_inline)) { *port &= ~sPinMask; } @@ -151,10 +158,10 @@ public: 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)) { hi(); lo(); } + 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); } -- cgit v1.2.3 From 1bd88e84936470887f60c1927a2bbc32e6c76eed Mon Sep 17 00:00:00 2001 From: "danielgarcia@gmail.com" Date: Wed, 12 Jun 2013 05:20:36 +0000 Subject: Checkpointing the multi-lane clockless work, also playing with using bitbanded pin access on arm --- FastSPI_LED2.h | 1 + chipsets.h | 12 ++++++++---- fastpin.h | 13 +++++++------ 3 files changed, 16 insertions(+), 10 deletions(-) diff --git a/FastSPI_LED2.h b/FastSPI_LED2.h index 9eb9ba6a..a2e8ab46 100644 --- a/FastSPI_LED2.h +++ b/FastSPI_LED2.h @@ -5,6 +5,7 @@ #include "fastpin.h" #include "fastspi.h" #include "clockless.h" +#include "clockless2.h" #include "lib8tion.h" #include "hsv2rgb.h" #include "chipsets.h" diff --git a/chipsets.h b/chipsets.h index b0c123d7..325e8b5b 100644 --- a/chipsets.h +++ b/chipsets.h @@ -309,7 +309,7 @@ class TM1809Controller800Mhz : public ClocklessController class TM1809Controller800Khz : public ClocklessController {}; #if NO_TIME(350, 350, 550) -#warning "Not enough clock cycles available for the UCS103" +#warning "Not enough clock cycles available for the TM1809" #endif // WS2811 - 350n, 350ns, 550ns @@ -317,8 +317,12 @@ template class WS2811Controller800Mhz : public ClocklessController {}; template class WS2811Controller800Khz : public ClocklessController {}; + +template +class WS2811Controller2800Khz : public ClocklessController2 {}; + #if NO_TIME(320, 320, 550) -#warning "Not enough clock cycles available for the UCS103" +#warning "Not enough clock cycles available for the WS2811" #endif // 750NS, 750NS, 750NS @@ -327,7 +331,7 @@ class TM1803Controller400Mhz : public ClocklessController class TM1803Controller400Khz : public ClocklessController {}; #if NO_TIME(750, 750, 750) -#warning "Not enough clock cycles available for the UCS103" +#warning "Not enough clock cycles available for the TM1803" #endif template @@ -354,7 +358,7 @@ public: } }; #if NO_TIME(100, 300, 200) -#warning "Not enough clock cycles available for TM1829@12v" +#warning "Not enough clock cycles available for TM1829@1.6Mhz" #endif #endif diff --git a/fastpin.h b/fastpin.h index d11e6d2d..e91a272d 100644 --- a/fastpin.h +++ b/fastpin.h @@ -249,13 +249,14 @@ typedef volatile uint32_t * ptr_reg32_t; template 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 : public _ARMPIN class FastPin : public _ARMPIN {}; - -// Don't use bit band'd pins for now, the compiler generates far less efficient code around them -// #define _DEFPIN_ARM(PIN, BIT, L) template<> class Pin : public _ARMPIN_BITBAND {}; - +#else + #define _DEFPIN_ARM(PIN, BIT, L) template<> class FastPin : public _ARMPIN_BITBAND {}; +#endif /////////////////////////////////////////////////////////////////////////////////////////////////////////// // -- cgit v1.2.3 From ae8c92019f7fda09df0522ee35dad8be7e58d181 Mon Sep 17 00:00:00 2001 From: "danielgarcia@gmail.com" Date: Wed, 19 Jun 2013 06:35:20 +0000 Subject: Preliminary support for due - only tested with clockless chips at the moment. If the SPI chipsets work, they will be using bit bang'd output. --- FastSPI_LED2.cpp | 3 + clockless.h | 11 +- clockless2.h | 265 +++++++++++++++++++++++++++++++++++++++++ controller.h | 2 +- delay.h | 5 +- examples/Fast2Dev/Fast2Dev.ino | 9 +- fastpin.h | 96 ++++++++++++--- led_sysdefs.h | 30 +++++ 8 files changed, 393 insertions(+), 28 deletions(-) create mode 100644 clockless2.h create mode 100644 led_sysdefs.h diff --git a/FastSPI_LED2.cpp b/FastSPI_LED2.cpp index b8e46e4d..34849fa1 100644 --- a/FastSPI_LED2.cpp +++ b/FastSPI_LED2.cpp @@ -1,5 +1,8 @@ #include "FastSPI_LED2.h" +#if defined(__SAM3X8E__) +volatile uint32_t fuckit; +#endif CFastSPI_LED2 LEDS; CFastSPI_LED2 & FastSPI_LED = LEDS; diff --git a/clockless.h b/clockless.h index b7f8a0fe..2bd449bc 100644 --- a/clockless.h +++ b/clockless.h @@ -3,7 +3,7 @@ #include "controller.h" #include "lib8tion.h" -#include // for cli/se definitions +#include "led_sysdefs.h" // Macro to convert from nano-seconds to clocks and clocks to nano-seconds // #define NS(_NS) (_NS / (1000 / (F_CPU / 1000000L))) @@ -21,6 +21,9 @@ #if defined(__MK20DX128__) extern volatile uint32_t systick_millis_count; # define MS_COUNTER systick_millis_count +#elif defined(__SAM3X8E__) + extern volatile uint32_t fuckit; +# define MS_COUNTER fuckit #else # if defined(CORE_TEENSY) extern volatile unsigned long timer0_millis_count; @@ -58,9 +61,7 @@ public: mPort = FastPin::port(); } -#if defined(__MK20DX128__) - // We don't use the bitSetFast methods for ARM. -#else +#if defined(FASTLED_AVR) template inline static void bitSetFast(register data_ptr_t port, register data_t hi, register data_t lo, register uint8_t b) { // First cycle SET_HI; // 1/2 clock cycle if using out @@ -152,7 +153,7 @@ public: register data_t lo = *port & ~mask; *port = lo; -#if defined(__MK20DX128__) +#if defined(FASTLED_ARM) register uint32_t b; if(ADVANCE) { b = data[SKIP + RGB_BYTE0(RGB_ORDER)]; diff --git a/clockless2.h b/clockless2.h new file mode 100644 index 00000000..e6823447 --- /dev/null +++ b/clockless2.h @@ -0,0 +1,265 @@ +#ifndef __INC_CLOCKLESS2_H +#define __INC_CLOCKLESS2_H + +#include "controller.h" +#include "lib8tion.h" +#include "led_sysdefs.h" + +// Macro to convert from nano-seconds to clocks and clocks to nano-seconds +// #define NS(_NS) (_NS / (1000 / (F_CPU / 1000000L))) +#if F_CPU < 96000000 +#define NS(_NS) ( (_NS * (F_CPU / 1000000L))) / 1000 +#define CLKS_TO_MICROS(_CLKS) _CLKS / (F_CPU / 1000000L) +#else +#define NS(_NS) ( (_NS * (F_CPU / 2000000L))) / 1000 +#define CLKS_TO_MICROS(_CLKS) _CLKS / (F_CPU / 2000000L) +#endif + +// Macro for making sure there's enough time available +#define NO_TIME(A, B, C) (NS(A) < 3 || NS(B) < 3 || NS(C) < 6) + +#if defined(__MK20DX128__) + extern volatile uint32_t systick_millis_count; +# define MS_COUNTER systick_millis_count +#else +# if defined(CORE_TEENSY) + 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 + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// +// 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. +// +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +// Convinience macros to wrap around the toggling of hi vs. lo +#define SET2_LO FLIP ? FastPin::hi() : FastPin::lo() +#define SET2_HI FLIP ? FastPin::lo() : FastPin::hi() + +#define SET2_LO2 FLIP ? FastPin::hi() : FastPin::lo() +#define SET2_HI2 FLIP ? FastPin::lo() : FastPin::hi() + + +template +class ClocklessController2 : public CLEDController { + typedef typename FastPin::port_ptr_t data_ptr_t; + typedef typename FastPin::port_t data_t; + + CMinWait mWait; +public: + virtual void init() { + FastPin::setOutput(); + FastPin::setOutput(); + } + + + virtual void clearLeds(int nLeds) { + showColor(CRGB(0, 0, 0), nLeds, 0); + } + + // set all the leds on the controller to a given color + virtual void showColor(const struct CRGB & data, int nLeds, uint8_t scale = 255) { + mWait.wait(); + cli(); + + showRGBInternal<0, false>(nLeds, scale, (const byte*)&data, (const byte*)&data); + + // Adjust the timer + long microsTaken = CLKS_TO_MICROS(nLeds * 8 * (T1 + T2 + T3)); + MS_COUNTER += (microsTaken / 1000); + sei(); + mWait.mark(); + } + + virtual void show(const struct CRGB *rgbdata, int nLeds, uint8_t scale = 255) { + mWait.wait(); + cli(); + + showRGBInternal<0, true>(nLeds, scale, (const byte*)rgbdata, (const byte*)rgbdata); + + // Adjust the timer + long microsTaken = CLKS_TO_MICROS(nLeds * 8 * (T1 + T2 + T3)); + MS_COUNTER += (microsTaken / 1000); + sei(); + mWait.mark(); + } + + virtual void show(const struct CRGB *rgbdata, const struct CRGB *rgbdata2, int nLeds, uint8_t scale = 255) { + mWait.wait(); + cli(); + + showRGBInternal<0, true>(nLeds, scale, (const byte*)rgbdata, (const byte*)rgbdata2 ); + + // Adjust the timer + long microsTaken = CLKS_TO_MICROS(nLeds * 8 * (T1 + T2 + T3)); + MS_COUNTER += (microsTaken / 1000); + sei(); + mWait.mark(); + } + +#ifdef SUPPORT_ARGB + virtual void show(const struct CARGB *rgbdata, int nLeds, uint8_t scale = 255) { + mWait.wait(); + cli(); + + showRGBInternal<1, true>(nLeds, scale, (const byte*)rgbdata); + + // Adjust the timer + long microsTaken = CLKS_TO_MICROS(nLeds * 8 * (T1 + T2 + T3)); + MS_COUNTER += (microsTaken / 1000); + sei(); + mWait.mark(); + } +#endif + + // 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. + template static void showRGBInternal(register int nLeds, register uint8_t scale, register const byte *rgbdata, register const byte *rgbdata2) { + register byte *data = (byte*)rgbdata; + register byte *data2 = (byte*)rgbdata2; + + nLeds *= (3 + SKIP); + register uint8_t *end = data + nLeds; + +#if defined(__MK20DX128__) + register uint32_t b; + register uint32_t c; + if(ADVANCE) { + b = data[SKIP + RGB_BYTE0(RGB_ORDER)]; + c = data2[SKIP + RGB_BYTE0(RGB_ORDER)]; + } else { + b = rgbdata[SKIP + RGB_BYTE0(RGB_ORDER)]; + c = rgbdata2[SKIP + RGB_BYTE0(RGB_ORDER)]; + } + b = scale8(b, scale); + c = scale8(c, scale); + + while(data < end) { + // TODO: hand rig asm version of this method. The timings are based on adjusting/studying GCC compiler ouptut. This + // will bite me in the ass at some point, I know it. + for(register uint32_t i = 7; i > 0; i--) { + SET2_HI; delaycycles<3>(); SET2_HI2; + delaycycles(); // 6 cycles - 1/1 store, 1/1 test, 1/1 if, 1/1 port lookup + if(b & 0x80) { SET2_HI; } else { SET2_LO; } + if(c & 0x80) { SET2_HI2; } else { SET2_LO2; } + b <<= 1; c <<=1; + delaycycles(); // 3 cycles, 1/1 store, 1/1 store/skip, 1/1 shift , 1/1 port lookup + SET2_LO; SET2_LO2; + delaycycles(); // 4 cycles, 1/1 store, 1 sub, 1 branch backwards, 1/1 port lookup + } + // extra delay because branch is faster falling through + delaycycles<1>(); + + // 8th bit, interleave loading rest of data + SET2_HI; delaycycles<3>(); SET2_HI2; + delaycycles(); + if(b & 0x80) { SET2_HI; } else { SET2_LO; } + if(c & 0x80) { SET2_HI2; } else { SET2_LO2; } + delaycycles(); // 4 cycles, 2/2 store, 1/1 store/skip, 1/1 port lookup + SET2_LO; SET2_LO2; + + if(ADVANCE) { + b = data[SKIP + RGB_BYTE1(RGB_ORDER)]; + c = data2[SKIP + RGB_BYTE1(RGB_ORDER)]; + } else { + b = rgbdata[SKIP + RGB_BYTE1(RGB_ORDER)]; + c = rgbdata2[SKIP + RGB_BYTE1(RGB_ORDER)]; + } + b = scale8(b, scale); + c = scale8(c, scale); + + delaycycles(); // 1/1 store, 2/2 load, 1/1 mul, 1/1 shift, , 1/1 port lookup + + for(register uint32_t i = 7; i > 0; i--) { + SET2_HI; delaycycles<3>(); SET2_HI2; + delaycycles(); // 3 cycles - 1 store, 1 test, 1 if + if(b & 0x80) { SET2_HI; } else { SET2_LO; } + if(c & 0x80) { SET2_HI2; } else { SET2_LO2; } + b <<= 1; c <<= 1; + delaycycles(); // 6 cycles, 1/1 store, 1/1 store/skip, 1/1 shift , 1/1 port lookup + SET2_LO; SET2_LO2; + delaycycles(); // 4 cycles, 1/1 store, 1 sub, 1 branch backwards, 1/1 port lookup + } + // extra delay because branch is faster falling through + delaycycles<1>(); + + // 8th bit, interleave loading rest of data + SET2_HI; delaycycles<3>(); SET2_HI2; + delaycycles(); + if(b & 0x80) { SET2_HI; } else { SET2_LO; } + if(b & 0x80) { SET2_HI2; } else { SET2_LO2; } + delaycycles(); // 4 cycles, 2 store, store/skip, 1/1 port lookup + SET2_LO; SET2_LO2; + + if(ADVANCE) { + b = data[SKIP + RGB_BYTE2(RGB_ORDER)]; + c = data2[SKIP + RGB_BYTE2(RGB_ORDER)]; + } else { + b = rgbdata[SKIP + RGB_BYTE2(RGB_ORDER)]; + c = rgbdata2[SKIP + RGB_BYTE2(RGB_ORDER)]; + } + b = scale8(b, scale); + c = scale8(c, scale); + + data += 3 + SKIP; data2 += 3 + SKIP; + if((RGB_ORDER & 0070) == 0) { + delaycycles(); // 1/1 store, 2/2 load, 1/1 mul, 1/1 shift, 1/1 adds if BRG or GRB, 1/1 port lookup + } else { + delaycycles(); // 1/1 store, 2/2 load, 1/1 mul, 1/1 shift, , 1/1 port lookup + } + + for(register uint32_t i = 7; i > 0; i--) { + SET2_HI; delaycycles<3>(); SET2_HI2; + delaycycles(); // 3 cycles - 1 store, 1 test, 1 if + if(b & 0x80) { SET2_HI; } else { SET2_LO; } + if(c & 0x80) { SET2_HI2; } else { SET2_LO2; } + b <<= 1; c <<= 1; + delaycycles(); // 3 cycles, 1 store, 1 store/skip, 1 shift , 1/1 port lookup + SET2_LO; SET2_LO2; + delaycycles(); // 3 cycles, 1/1 store, 1 sub, 1 branch backwards, 1/1 port lookup + } + // extra delay because branch is faster falling through + delaycycles<1>(); + + // 8th bit, interleave loading rest of data + SET2_HI; delaycycles<3>(); SET2_HI2; + delaycycles(); + if(b & 0x80) { SET2_HI; } else { SET2_LO; } + if(c & 0x80) { SET2_HI2; } else { SET2_LO2; } + delaycycles(); // 4 cycles, 2/2 store, store/skip, 1/1 port lookup + SET2_LO; SET2_LO2; + + if(ADVANCE) { + b = data[SKIP + RGB_BYTE0(RGB_ORDER)]; + c = data2[SKIP + RGB_BYTE0(RGB_ORDER)]; + } else { + b = rgbdata[SKIP + RGB_BYTE0(RGB_ORDER)]; + c = rgbdata2[SKIP + RGB_BYTE0(RGB_ORDER)]; + } + b = scale8(b, scale); + c = scale8(c, scale); + delaycycles(); // 1/1 store, 2/2 load (with increment), 1/1 mul, 1/1 shift, 1 cmp, 1 branch backwards, 1 movim, 1/1 port lookup + }; +#endif + } + +#ifdef SUPPORT_ARGB + virtual void showARGB(struct CARGB *data, int nLeds) { + // TODO: IMPLEMENTME + } +#endif +}; + +#undef SET2_HI +#undef SET2_HI2 +#undef SET2_LO +#undef SET2_LO2 + +#endif \ No newline at end of file diff --git a/controller.h b/controller.h index 2c703f00..dd07130a 100644 --- a/controller.h +++ b/controller.h @@ -1,7 +1,7 @@ #ifndef __INC_CONTROLLER_H #define __INC_CONTROLLER_H -#include +#include "led_sysdefs.h" #include "pixeltypes.h" diff --git a/delay.h b/delay.h index 440ca97a..937e9b2a 100644 --- a/delay.h +++ b/delay.h @@ -17,6 +17,9 @@ template inline void delaycycles(); // TODO: ARM version of _delaycycles_ + +// usable definition +#if defined(FASTLED_AVR) // worker template - this will nop for LOOP * 3 + PAD cycles total template inline void _delaycycles_AVR() { delaycycles(); @@ -33,8 +36,6 @@ template inline void _delaycycles_AVR() { ); } -// usable definition -#if !defined(__MK20DX128__) template __attribute__((always_inline)) inline void delaycycles() { _delaycycles_AVR(); } diff --git a/examples/Fast2Dev/Fast2Dev.ino b/examples/Fast2Dev/Fast2Dev.ino index 52ee867d..e8dd6742 100644 --- a/examples/Fast2Dev/Fast2Dev.ino +++ b/examples/Fast2Dev/Fast2Dev.ino @@ -16,7 +16,7 @@ // ////////////////////////////////////////////////// -#define NUM_LEDS 15 +#define NUM_LEDS 256 CRGB leds[NUM_LEDS]; @@ -28,8 +28,8 @@ void setup() { // setting brightness to 25% brightness LEDS.setBrightness(64); - // LEDS.addLeds(leds, NUM_LEDS); - LEDS.addLeds(leds, NUM_LEDS); + LEDS.addLeds(leds, NUM_LEDS); + // LEDS.addLeds(leds, NUM_LEDS); // LEDS.addLeds(leds, NUM_LEDS); // LEDS.addLeds(leds, NUM_LEDS); // LEDS.addLeds(leds, NUM_LEDS); @@ -75,6 +75,9 @@ void loop() { delay(10); } + // leave the last pixel lit for a bit + delay(2000); + // fade up for(int x = 0; x < 128; x++) { // The showColor method sets all the leds in the strip to the same color diff --git a/fastpin.h b/fastpin.h index e91a272d..488f0fb9 100644 --- a/fastpin.h +++ b/fastpin.h @@ -1,10 +1,7 @@ #ifndef __INC_FASTPIN_H #define __INC_FASTPIN_H -#include - -// Arduino.h needed for convinience functions digitalPinToPort/BitMask/portOutputRegister and the pinMode methods. -#include +#include "led_sysdefs.h" #define NO_PIN 255 @@ -41,10 +38,10 @@ public: }; class Pin : public Selectable { - uint8_t mPinMask; + RwReg mPinMask; uint8_t mPin; - volatile uint8_t *mPort; - volatile uint8_t *mInPort; + volatile RwReg *mPort; + volatile RoReg *mInPort; void _init() { mPinMask = digitalPinToBitMask(mPin); @@ -54,8 +51,8 @@ class Pin : public Selectable { public: Pin(int pin) : mPin(pin) { _init(); } - typedef volatile uint8_t * port_ptr_t; - typedef uint8_t port_t; + typedef volatile RwReg * port_ptr_t; + typedef RwReg port_t; inline void setOutput() { pinMode(mPin, OUTPUT); } inline void setInput() { pinMode(mPin, INPUT); } @@ -107,17 +104,17 @@ public: /// Note that these classes are all static functions. So the proper usage is Pin<13>::hi(); or such. Instantiating objects is not recommended, /// as passing Pin objects around will likely -not- have the effect you're expecting. template class FastPin { - static uint8_t sPinMask; - static volatile uint8_t *sPort; - static volatile uint8_t *sInPort; + static RwReg sPinMask; + static volatile RwReg *sPort; + static volatile RoReg *sInPort; static void _init() { sPinMask = digitalPinToBitMask(PIN); sPort = portOutputRegister(digitalPinToPort(PIN)); sInPort = portInputRegister(digitalPinToPort(PIN)); } public: - typedef volatile uint8_t * port_ptr_t; - typedef uint8_t port_t; + typedef volatile RwReg * port_ptr_t; + typedef RwReg port_t; inline static void setOutput() { _init(); pinMode(PIN, OUTPUT); } inline static void setInput() { _init(); pinMode(PIN, INPUT); } @@ -141,8 +138,9 @@ public: static port_t mask() __attribute__ ((always_inline)) { return sPinMask; } }; -template uint8_t FastPin::sPinMask; -template volatile uint8_t *FastPin::sPort; +template RwReg FastPin::sPinMask; +template volatile RwReg *FastPin::sPort; +template volatile RoReg *FastPin::sInPort; /// 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. @@ -172,9 +170,40 @@ public: inline static port_t mask() __attribute__ ((always_inline)) { return _MASK; } }; +/// 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 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_t mask() __attribute__ ((always_inline)) { return _MASK; } +}; + /// 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 class _ARMPIN { public: typedef volatile uint32_t * port_ptr_t; @@ -249,8 +278,12 @@ typedef volatile uint32_t * ptr_reg32_t; template 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 USE_BITBAND 1 +#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 USE_BITBAND 0 #if USE_BITBAND == 0 + #define _DEFPIN_DUE(PIN, BIT, L) template<> class FastPin : public _DUEPIN {}; #define _DEFPIN_ARM(PIN, BIT, L) template<> class FastPin : public _ARMPIN {}; #else @@ -382,6 +415,35 @@ _DEFPIN_ARM(32, 18, B); _DEFPIN_ARM(33, 4, A); #define SPI_DATA 11 #define SPI_CLOCK 13 #define ARM_HARDWARE_SPI + +#elif defined(__SAM3X8E__) + +DUE_IO32(A); +DUE_IO32(B); +DUE_IO32(C); +DUE_IO32(D); + +_DEFPIN_DUE(0, 8, A); _DEFPIN_DUE(1, 9, A); _DEFPIN_DUE(2, 25, B); _DEFPIN_DUE(3, 28, C); +_DEFPIN_DUE(4, 29, A); _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, 28, A); _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); + #else #warning "No pin/port mappings found, pin access will be slightly slower. See fastpin.h for info." diff --git a/led_sysdefs.h b/led_sysdefs.h new file mode 100644 index 00000000..83fe3122 --- /dev/null +++ b/led_sysdefs.h @@ -0,0 +1,30 @@ +#ifndef __INC_LED_SYSDEFS_H +#define __INC_LED_SYSDEFS_H + +#ifndef __SAM3X8E__ +#include +#include // for cli/se definitions + +// Define the rgister 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 + +#else +// reuseing/abusing cli/sei defs for due +#define cli() __disable_irq() +#define sei() __enable_irq() + +#endif + +#if defined(__MK20DX128__) || defined(__SAM3X8E__) +#define FASTLED_ARM +#else +#define FASTLED_AVR +#endif + +// Arduino.h needed for convinience functions digitalPinToPort/BitMask/portOutputRegister and the pinMode methods. +#include + +#endif \ No newline at end of file -- cgit v1.2.3 From 9cbddfc41dea1f25e2668fb3843e0eca430fc14a Mon Sep 17 00:00:00 2001 From: "danielgarcia@gmail.com" Date: Thu, 20 Jun 2013 18:53:53 +0000 Subject: cleanup andcheckpointing --- chipsets.h | 12 ------------ clockless.h | 10 +++++----- delay.h | 16 ++++++++++++++++ fastpin.h | 41 ++++++++++++++++++++++++++++++++++++----- lib8tion.h | 4 ++-- 5 files changed, 59 insertions(+), 24 deletions(-) diff --git a/chipsets.h b/chipsets.h index 325e8b5b..6302a2e3 100644 --- a/chipsets.h +++ b/chipsets.h @@ -150,7 +150,6 @@ template SPI; SPI mSPI; - CMinWait<24> mWaitDelay; void writeBoundary() { mSPI.writeWord(0); mSPI.writeWord(0); } @@ -186,7 +185,6 @@ public: mSPI.waitFully(); mSPI.release(); - mWaitDelay.mark(); } virtual void show(const struct CRGB *data, int nLeds, uint8_t scale) { @@ -203,9 +201,7 @@ public: #ifdef SUPPORT_ARGB virtual void show(const struct CRGB *data, int nLeds, uint8_t scale) { - mWaitDelay.wait(); mSPI.template writeBytes3<1, RGB_ORDER>((byte*)data, nLeds * 4, scale); - mWaitDelay.mark(); } #endif }; @@ -296,8 +292,6 @@ public: // UCS1903 - 500ns, 1500ns, 500ns template -class UCS1903Controller400Mhz : public ClocklessController {}; -template class UCS1903Controller400Khz : public ClocklessController {}; #if NO_TIME(500, 1500, 500) #warning "Not enough clock cycles available for the UCS103" @@ -305,8 +299,6 @@ class UCS1903Controller400Khz : public ClocklessController -class TM1809Controller800Mhz : public ClocklessController {}; -template class TM1809Controller800Khz : public ClocklessController {}; #if NO_TIME(350, 350, 550) #warning "Not enough clock cycles available for the TM1809" @@ -314,8 +306,6 @@ class TM1809Controller800Khz : public ClocklessController -class WS2811Controller800Mhz : public ClocklessController {}; -template class WS2811Controller800Khz : public ClocklessController {}; template @@ -327,8 +317,6 @@ class WS2811Controller2800Khz : public ClocklessController2 -class TM1803Controller400Mhz : public ClocklessController {}; -template class TM1803Controller400Khz : public ClocklessController {}; #if NO_TIME(750, 750, 750) #warning "Not enough clock cycles available for the TM1803" diff --git a/clockless.h b/clockless.h index 2bd449bc..e13cd153 100644 --- a/clockless.h +++ b/clockless.h @@ -43,8 +43,8 @@ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Convinience macros to wrap around the toggling of hi vs. lo -#define SET_LO FLIP ? FastPin::fastset(port, hi) : FastPin::fastset(port, lo) -#define SET_HI FLIP ? FastPin::fastset(port, lo) : FastPin::fastset(port, hi) +#define SET_LO FLIP ? FastPin::fastset(port, hi) : FastPin::fastset(port, lo); +#define SET_HI FLIP ? FastPin::fastset(port, lo) : FastPin::fastset(port, hi); template class ClocklessController : public CLEDController { @@ -145,12 +145,12 @@ public: // gcc will use register Y for the this pointer. template static void showRGBInternal(register int nLeds, register uint8_t scale, register const byte *rgbdata) { register byte *data = (byte*)rgbdata; - register data_t mask = FastPin::mask(); + data_t mask = FastPin::mask(); register data_ptr_t port = FastPin::port(); nLeds *= (3 + SKIP); register uint8_t *end = data + nLeds; - register data_t hi = *port | mask; - register data_t lo = *port & ~mask; + register data_t hi = FastPin::hival(); + register data_t lo = FastPin::loval();; *port = lo; #if defined(FASTLED_ARM) diff --git a/delay.h b/delay.h index 937e9b2a..554705fe 100644 --- a/delay.h +++ b/delay.h @@ -40,7 +40,23 @@ template __attribute__((always_inline)) inline void delaycycles() { _delaycycles_AVR(); } #else +// template inline void _delaycycles_ARM() { +// delaycycles(); +// // the loop below is 3 cycles * LOOP. the LDI is one cycle, +// // the DEC is 1 cycle, the BRNE is 2 cycles if looping back and +// // 1 if not (the LDI balances out the BRNE being 1 cycle on exit) +// __asm__ __volatile__ ( +// " mov.w r9, %0\n" +// "L_%=: subs.w r9, r9, #1\n" +// " bne.n L_%=\n" +// : /* no outputs */ +// : "M" (LOOP) +// : "r9" +// ); +// } + template __attribute__((always_inline)) inline void delaycycles() { + // _delaycycles_ARM(); NOP; delaycycles(); } #endif diff --git a/fastpin.h b/fastpin.h index 488f0fb9..e68d04f2 100644 --- a/fastpin.h +++ b/fastpin.h @@ -14,7 +14,7 @@ public: void wait() { long diff = micros() - mLastMicros; - if(diff < WAIT) { + if(diff > 0 && diff < WAIT) { delayMicroseconds(WAIT - diff); } } @@ -200,6 +200,35 @@ public: 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 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; } +}; + /// 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. @@ -248,9 +277,9 @@ public: inline static void toggle() __attribute__ ((always_inline)) { *_PTOR::template rx<_BIT>() = 1; } - inline static void hi(register port_ptr_t port) __attribute__ ((always_inline)) { *port = 1; } - inline static void lo(register port_ptr_t port) __attribute__ ((always_inline)) { *port = 0; } - inline static void fastset(register port_ptr_t port, register port_t val) __attribute__ ((always_inline)) { *port = val; } + 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; } @@ -280,13 +309,15 @@ typedef volatile uint32_t * ptr_reg32_t; #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 USE_BITBAND 0 +#define USE_BITBAND 1 #if USE_BITBAND == 0 #define _DEFPIN_DUE(PIN, BIT, L) template<> class FastPin : public _DUEPIN {}; #define _DEFPIN_ARM(PIN, BIT, L) template<> class FastPin : public _ARMPIN {}; #else + #define _DEFPIN_DUE(PIN, BIT, L) template<> class FastPin : public _DUEPIN_BITBAND {}; #define _DEFPIN_ARM(PIN, BIT, L) template<> class FastPin : public _ARMPIN_BITBAND {}; #endif diff --git a/lib8tion.h b/lib8tion.h index 33a0abcc..0cb097f0 100644 --- a/lib8tion.h +++ b/lib8tion.h @@ -124,7 +124,7 @@ Lib8tion is pronounced like 'libation': lie-BAY-shun #include -#define LIB8STATIC __attribute__ ((unused)) static +#define LIB8STATIC __attribute__ ((unused)) static inline #if defined(__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__) || defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__) @@ -426,7 +426,7 @@ LIB8STATIC uint8_t sub8( uint8_t i, uint8_t j) // the numerator of a fraction whose denominator is 256 // In other words, it computes i * (scale / 256) // 4 clocks AVR, 2 clocks ARM -LIB8STATIC uint8_t scale8( uint8_t i, fract8 scale) +LIB8STATIC uint8_t scale8( uint8_t i, fract8 scale) { #if SCALE8_C == 1 return ((int)i * (int)(scale) ) >> 8; -- cgit v1.2.3 From a84fe168d38132ed393bc6a19da0340ae34e1776 Mon Sep 17 00:00:00 2001 From: "danielgarcia@gmail.com" Date: Tue, 25 Jun 2013 09:46:15 +0000 Subject: Preliminary clockless chip support for the due - works great w/ws2811 - still some glitching w/tm1809 - unclear if this is a timing issue or if the 3.3v logic is a problem. --- chipsets.h | 2 +- clockless.h | 435 ++++++++++++++++++++++++++++++++++++++++++++-------------- delay.h | 28 ++++ fastpin.h | 14 +- led_sysdefs.h | 6 +- 5 files changed, 367 insertions(+), 118 deletions(-) diff --git a/chipsets.h b/chipsets.h index 6302a2e3..9979f48d 100644 --- a/chipsets.h +++ b/chipsets.h @@ -300,7 +300,7 @@ class UCS1903Controller400Khz : public ClocklessController class TM1809Controller800Khz : public ClocklessController {}; -#if NO_TIME(350, 350, 550) +#if NO_TIME(320, 320, 550) #warning "Not enough clock cycles available for the TM1809" #endif diff --git a/clockless.h b/clockless.h index e13cd153..7c0a5d41 100644 --- a/clockless.h +++ b/clockless.h @@ -46,6 +46,7 @@ #define SET_LO FLIP ? FastPin::fastset(port, hi) : FastPin::fastset(port, lo); #define SET_HI FLIP ? FastPin::fastset(port, lo) : FastPin::fastset(port, hi); +#ifdef FASTLED_AVR template class ClocklessController : public CLEDController { typedef typename FastPin::port_ptr_t data_ptr_t; @@ -61,7 +62,6 @@ public: mPort = FastPin::port(); } -#if defined(FASTLED_AVR) template inline static void bitSetFast(register data_ptr_t port, register data_t hi, register data_t lo, register uint8_t b) { // First cycle SET_HI; // 1/2 clock cycle if using out @@ -93,8 +93,133 @@ public: SET_LO; // 1/2 clock cycle if using out delaycycles(); // 3rd cycle length minus 7 clocks for out, loop compare, jump, next uint8_t load } + + virtual void clearLeds(int nLeds) { + showColor(CRGB(0, 0, 0), nLeds, 0); + } + + // set all the leds on the controller to a given color + virtual void showColor(const struct CRGB & data, int nLeds, uint8_t scale = 255) { + mWait.wait(); + cli(); + + showRGBInternal<0, false>(nLeds, scale, (const byte*)&data); + + // Adjust the timer + long microsTaken = CLKS_TO_MICROS(nLeds * 8 * (T1 + T2 + T3)); + MS_COUNTER += (microsTaken / 1000); + sei(); + mWait.mark(); + } + + virtual void show(const struct CRGB *rgbdata, int nLeds, uint8_t scale = 255) { + mWait.wait(); + cli(); + + showRGBInternal<0, true>(nLeds, scale, (const byte*)rgbdata); + + // Adjust the timer + long microsTaken = CLKS_TO_MICROS(nLeds * 8 * (T1 + T2 + T3)); + MS_COUNTER += (microsTaken / 1000); + sei(); + mWait.mark(); + } + +#ifdef SUPPORT_ARGB + virtual void show(const struct CARGB *rgbdata, int nLeds, uint8_t scale = 255) { + mWait.wait(); + cli(); + + showRGBInternal<1, true>(nLeds, scale, (const byte*)rgbdata); + + // Adjust the timer + long microsTaken = CLKS_TO_MICROS(nLeds * 8 * (T1 + T2 + T3)); + MS_COUNTER += (microsTaken / 1000); + sei(); + mWait.mark(); + } #endif + // 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. + template static void showRGBInternal(register int nLeds, register uint8_t scale, register const byte *rgbdata) { + register byte *data = (byte*)rgbdata; + data_t mask = FastPin::mask(); + register data_ptr_t port = FastPin::port(); + nLeds *= (3 + SKIP); + register uint8_t *end = data + nLeds; + register data_t hi = FastPin::hival(); + register data_t lo = FastPin::loval();; + *port = lo; + + register uint8_t b; + + b = ADVANCE ? data[SKIP + RGB_BYTE0(RGB_ORDER)] :rgbdata[SKIP + RGB_BYTE0(RGB_ORDER)]; + b = scale8_LEAVING_R1_DIRTY(b, scale); + + register uint8_t c; + register uint8_t d; + while(data < end) { + for(register byte x=5; x; x--) { + bitSetLast<7, 4>(port, hi, lo, b); + b <<= 1; + } + delaycycles<1>(); + // Leave an extra 2 clocks for the next byte load + bitSetLast<7, 0>(port, hi, lo, b); + // Leave an extra 4 clocks for the scale + bitSetLast<6, 5>(port, hi, lo, b); + c = ADVANCE ? data[SKIP + RGB_BYTE1(RGB_ORDER)] :rgbdata[SKIP + RGB_BYTE1(RGB_ORDER)]; + c = scale8_LEAVING_R1_DIRTY(c, scale); + bitSetLast<5, 1>(port, hi, lo, b); + + for(register byte x=5; x; x--) { + bitSetLast<7, 4>(port, hi, lo, c); + c <<= 1; + } + delaycycles<1>(); + // Leave an extra 2 clocks for the next byte load + bitSetLast<7, 0>(port, hi, lo, c); + // Leave an extra 4 clocks for the scale + bitSetLast<6, 5>(port, hi, lo, c); + d = ADVANCE ? data[SKIP + RGB_BYTE2(RGB_ORDER)] :rgbdata[SKIP + RGB_BYTE2(RGB_ORDER)]; + d = scale8_LEAVING_R1_DIRTY(d, scale); + bitSetLast<5, 1>(port, hi, lo, c); + + for(register byte x=5; x; x--) { + bitSetLast<7, 4>(port, hi, lo, d); + d <<= 1; + } + delaycycles<1>(); + // Leave an extra 2 clocks for the next byte load + bitSetLast<7, 2>(port, hi, lo, d); + data += (SKIP + 3); + // Leave an extra 4 clocks for the scale + bitSetLast<6, 5>(port, hi, lo, d); + b = ADVANCE ? data[SKIP + RGB_BYTE0(RGB_ORDER)] :rgbdata[SKIP + RGB_BYTE0(RGB_ORDER)]; + b = scale8_LEAVING_R1_DIRTY(b, scale); + bitSetLast<5, 6>(port, hi, lo, d); + } + cleanup_R1(); + } +}; + +#elif defined(__MK20DX128__) +template +class ClocklessController : public CLEDController { + typedef typename FastPin::port_ptr_t data_ptr_t; + typedef typename FastPin::port_t data_t; + + data_t mPinMask; + data_ptr_t mPort; + CMinWait mWait; +public: + virtual void init() { + FastPin::setOutput(); + mPinMask = FastPin::mask(); + mPort = FastPin::port(); + } + virtual void clearLeds(int nLeds) { showColor(CRGB(0, 0, 0), nLeds, 0); } @@ -153,13 +278,8 @@ public: register data_t lo = FastPin::loval();; *port = lo; -#if defined(FASTLED_ARM) register uint32_t b; - if(ADVANCE) { - b = data[SKIP + RGB_BYTE0(RGB_ORDER)]; - } else { - b = rgbdata[SKIP + RGB_BYTE0(RGB_ORDER)]; - } + b = ADVANCE ? data[SKIP + RGB_BYTE0(RGB_ORDER)] :rgbdata[SKIP + RGB_BYTE0(RGB_ORDER)]; b = scale8(b, scale); while(data < end) { // TODO: hand rig asm version of this method. The timings are based on adjusting/studying GCC compiler ouptut. This @@ -183,11 +303,7 @@ public: delaycycles(); // 4 cycles, 2 store, store/skip SET_LO; - if(ADVANCE) { - b = data[SKIP + RGB_BYTE1(RGB_ORDER)]; - } else { - b = rgbdata[SKIP + RGB_BYTE1(RGB_ORDER)]; - } + b = ADVANCE ? data[SKIP + RGB_BYTE1(RGB_ORDER)] :rgbdata[SKIP + RGB_BYTE1(RGB_ORDER)]; b = scale8(b, scale); delaycycles(); // 1 store, 2 load, 1 mul, 1 shift, @@ -211,11 +327,7 @@ public: delaycycles(); // 4 cycles, 2 store, store/skip SET_LO; - if(ADVANCE) { - b = data[SKIP + RGB_BYTE2(RGB_ORDER)]; - } else { - b = rgbdata[SKIP + RGB_BYTE2(RGB_ORDER)]; - } + b = ADVANCE ? data[SKIP + RGB_BYTE2(RGB_ORDER)] :rgbdata[SKIP + RGB_BYTE2(RGB_ORDER)]; b = scale8(b, scale); data += 3 + SKIP; @@ -244,108 +356,219 @@ public: delaycycles(); // 4 cycles, 2 store, store/skip SET_LO; - if(ADVANCE) { - b = data[SKIP + RGB_BYTE0(RGB_ORDER)]; - } else { - b = rgbdata[SKIP + RGB_BYTE0(RGB_ORDER)]; - } + b = ADVANCE ? data[SKIP + RGB_BYTE0(RGB_ORDER)] :rgbdata[SKIP + RGB_BYTE0(RGB_ORDER)]; b = scale8(b, scale); delaycycles(); // 1 store, 2 load (with increment), 1 mul, 1 shift, 1 cmp, 1 branch backwards, 1 movim }; -#else -#if 0 - register uint8_t b = *data++; - while(data <= end) { - bitSetFast<7>(port, hi, lo, b); - bitSetFast<6>(port, hi, lo, b); - bitSetFast<5>(port, hi, lo, b); - bitSetFast<4>(port, hi, lo, b); - bitSetFast<3>(port, hi, lo, b); - // Leave an extra 2 clocks for the next byte load - bitSetLast<2, 2>(port, hi, lo, b); - register uint8_t next = *data++; - // Leave an extra 4 clocks for the scale - bitSetLast<1, 4>(port, hi, lo, b); - next = scale8(next, scale); - bitSetLast<0, END_OF_LOOP>(port, hi, lo, b); - b = next; - } -#else - register uint8_t b; + } +}; +#elif defined(__SAM3X8E__) - if(ADVANCE) { - b = data[SKIP + RGB_BYTE0(RGB_ORDER)]; - } else { - b = rgbdata[SKIP + RGB_BYTE0(RGB_ORDER)]; - } - b = scale8_LEAVING_R1_DIRTY(b, scale); +template +class ClocklessController : public CLEDController { + typedef typename FastPinBB::port_ptr_t data_ptr_t; + typedef typename FastPinBB::port_t data_t; + + data_t mPinMask; + data_ptr_t mPort; + CMinWait mWait; +public: + virtual void init() { + FastPinBB::setOutput(); + mPinMask = FastPinBB::mask(); + mPort = FastPinBB::port(); + } + + virtual void clearLeds(int nLeds) { + showColor(CRGB(0, 0, 0), nLeds, 0); + } + + // set all the leds on the controller to a given color + virtual void showColor(const struct CRGB & data, int nLeds, uint8_t scale = 255) { + mWait.wait(); + cli(); + SysClockSaver savedClock(T1 + T2 + T3); + + showRGBInternal<0, false>(nLeds, scale, (const byte*)&data); + + // Adjust the timer + long microsTaken = CLKS_TO_MICROS(nLeds * 8 * (T1 + T2 + T3)); + MS_COUNTER += (microsTaken / 1000); + savedClock.restore(); + sei(); + mWait.mark(); + } + + virtual void show(const struct CRGB *rgbdata, int nLeds, uint8_t scale = 255) { + mWait.wait(); + cli(); + SysClockSaver savedClock(T1 + T2 + T3); + + // FastPinBB::hi(); delay(1); FastPinBB::lo(); + showRGBInternal<0, true>(nLeds, scale, (const byte*)rgbdata); + + // Adjust the timer + long microsTaken = CLKS_TO_MICROS(nLeds * 8 * (T1 + T2 + T3)); + MS_COUNTER += (microsTaken / 1000); + savedClock.restore(); + sei(); + mWait.mark(); + } + +#ifdef SUPPORT_ARGB + virtual void show(const struct CARGB *rgbdata, int nLeds, uint8_t scale = 255) { + mWait.wait(); + cli(); + SysClockSaver savedClock(T1 + T2 + T3); + + showRGBInternal<1, true>(nLeds, scale, (const byte*)rgbdata); + + // Adjust the timer + long microsTaken = CLKS_TO_MICROS(nLeds * 8 * (T1 + T2 + T3)); + MS_COUNTER += (microsTaken / 1000); + savedClock.restore(); + sei(); + mWait.mark(); + } +#endif + +// I hate using defines for these, should find a better representation at some point +#define _CTRL CTPTR[0] +#define _LOAD CTPTR[1] +#define _VAL CTPTR[2] + + __attribute__((always_inline)) static inline void wait_loop_start(register volatile uint32_t *CTPTR) { + __asm__ __volatile__ ( + "L_%=: ldr.w r8, [%0]\n" + " tst.w r8, #65536\n" + " beq.n L_%=\n" + : /* no outputs */ + : "r" (CTPTR) + : "r8" + ); + } + + template __attribute__((always_inline)) static inline void wait_loop_mark(register volatile uint32_t *CTPTR) { + __asm__ __volatile__ ( + "L_%=: ldr.w r8, [%0, #8]\n" + " cmp.w r8, %1\n" + " bhi.n L_%=\n" + : /* no outputs */ + : "r" (CTPTR), "I" (MARK) + : "r8" + ); + } + + __attribute__((always_inline)) static inline void mark_port(register data_ptr_t port, register int val) { + __asm__ __volatile__ ( + " str.w %0, [%1]\n" + : /* no outputs */ + : "r" (val), "r" (port) + ); + } +#define AT_BIT_START(X) wait_loop_start(CTPTR); X; +#define AT_MARK(X) wait_loop_mark(CTPTR); { X; } +#define AT_END(X) wait_loop_mark(CTPTR); { X; } + +// #define AT_BIT_START(X) while(!(_CTRL & SysTick_CTRL_COUNTFLAG_Msk)); { X; } +// #define AT_MARK(X) while(_VAL > T1_MARK); { X; } +// #define AT_END(X) while(_VAL > T2_MARK); { X; } + +//#define AT_MARK(X) delayclocks_until(_VAL); X; +//#define AT_END(X) delayclocks_until(_VAL); X; + +#define TOTAL (T1 + T2 + T3) + +#define T1_MARK (TOTAL - T1) +#define T2_MARK (T1_MARK - T2) + template __attribute__((always_inline)) static inline void delayclocks_until(register byte b) { + __asm__ __volatile__ ( + " sub %0, %0, %1\n" + "L_%=: subs %0, %0, #2\n" + " bcs.n L_%=\n" + : /* no outputs */ + : "r" (b), "I" (MARK) + : /* no clobbers */ + ); + + } + +#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. + template static void showRGBInternal(register int nLeds, register uint8_t scale, register const byte *rgbdata) { + register data_ptr_t port asm("r7") = FastPinBB::port(); FORCE_REFERENCE(port); + register byte *data = (byte*)rgbdata; + register uint8_t *end = data + (nLeds*3 + SKIP); + + register volatile uint32_t *CTPTR asm("r6")= &SysTick->CTRL; FORCE_REFERENCE(CTPTR); + + *port = 0; + + register uint32_t b; + b = ADVANCE ? data[SKIP + RGB_BYTE0(RGB_ORDER)] :rgbdata[SKIP + RGB_BYTE0(RGB_ORDER)]; + b = scale8(b, scale); + + // Setup and start the clock + _LOAD = TOTAL; + _VAL = 0; + _CTRL |= SysTick_CTRL_CLKSOURCE_Msk; + _CTRL |= SysTick_CTRL_ENABLE_Msk; + + // read to clear the loop flag + _CTRL; - register uint8_t c; - register uint8_t d; while(data < end) { - for(register byte x=5; x; x--) { - bitSetLast<7, 4>(port, hi, lo, b); + // TODO: hand rig asm version of this method. The timings are based on adjusting/studying GCC compiler ouptut. This + // will bite me in the ass at some point, I know it. + for(register uint32_t i = 7; i > 0; i--) { + AT_BIT_START(*port = 1); + if(b& 0x80) {} else { AT_MARK(*port = 0); } + AT_END(*port = 0); b <<= 1; } - delaycycles<1>(); - // Leave an extra 2 clocks for the next byte load - bitSetLast<7, 0>(port, hi, lo, b); - // Leave an extra 4 clocks for the scale - bitSetLast<6, 5>(port, hi, lo, b); - if(ADVANCE) { - c = data[SKIP + RGB_BYTE1(RGB_ORDER)]; - } else { - c = rgbdata[SKIP + RGB_BYTE1(RGB_ORDER)]; - } - c = scale8_LEAVING_R1_DIRTY(c, scale); - bitSetLast<5, 1>(port, hi, lo, b); - - for(register byte x=5; x; x--) { - bitSetLast<7, 4>(port, hi, lo, c); - c <<= 1; - } - delaycycles<1>(); - // Leave an extra 2 clocks for the next byte load - bitSetLast<7, 0>(port, hi, lo, c); - // Leave an extra 4 clocks for the scale - bitSetLast<6, 5>(port, hi, lo, c); - if(ADVANCE) { - d = data[SKIP + RGB_BYTE2(RGB_ORDER)]; - } else { - d = rgbdata[SKIP + RGB_BYTE2(RGB_ORDER)]; - } - d = scale8_LEAVING_R1_DIRTY(d, scale); - bitSetLast<5, 1>(port, hi, lo, c); - - for(register byte x=5; x; x--) { - bitSetLast<7, 4>(port, hi, lo, d); - d <<= 1; + + AT_BIT_START(*port = 1); + if(b& 0x80) {} else { AT_MARK(*port = 0); } + AT_END(*port = 0); + + b = ADVANCE ? data[SKIP + RGB_BYTE1(RGB_ORDER)] : rgbdata[SKIP + RGB_BYTE1(RGB_ORDER)]; + b = scale8(b, scale); + + for(register uint32_t i = 7; i > 0; i--) { + AT_BIT_START(*port = 1); + if(b& 0x80) {} else { AT_MARK(*port = 0); } + AT_END(*port = 0); + b <<= 1; } - delaycycles<1>(); - // Leave an extra 2 clocks for the next byte load - bitSetLast<7, 2>(port, hi, lo, d); - data += (SKIP + 3); - // Leave an extra 4 clocks for the scale - bitSetLast<6, 5>(port, hi, lo, d); - if(ADVANCE) { - b = data[SKIP + RGB_BYTE0(RGB_ORDER)]; - } else { - b = rgbdata[SKIP + RGB_BYTE0(RGB_ORDER)]; + + AT_BIT_START(*port = 1); + if(b& 0x80) {} else { AT_MARK(*port = 0); } + AT_END(*port = 0); + + b = ADVANCE ? data[SKIP + RGB_BYTE2(RGB_ORDER)] : rgbdata[SKIP + RGB_BYTE2(RGB_ORDER)]; + b = scale8(b, scale); + data += (3 + SKIP); + + for(register uint32_t i = 7; i > 0; i--) { + AT_BIT_START(*port = 1); + if(b& 0x80) {} else { AT_MARK(*port = 0); } + AT_END(*port = 0); + b <<= 1; } - b = scale8_LEAVING_R1_DIRTY(b, scale); - bitSetLast<5, 6>(port, hi, lo, d); - } - cleanup_R1(); -#endif -#endif - } -#ifdef SUPPORT_ARGB - virtual void showARGB(struct CARGB *data, int nLeds) { - // TODO: IMPLEMENTME + AT_BIT_START(*port = 1); + if(b& 0x80) {} else { AT_MARK(*port = 0); } + AT_END(*port = 0); + + b = ADVANCE ? data[SKIP + RGB_BYTE0(RGB_ORDER)] : rgbdata[SKIP + RGB_BYTE0(RGB_ORDER)]; + b = scale8(b, scale); + }; } -#endif }; +#endif + #endif \ No newline at end of file diff --git a/delay.h b/delay.h index 554705fe..34a19363 100644 --- a/delay.h +++ b/delay.h @@ -55,6 +55,7 @@ template __attribute__((always_inline)) inline void delaycycles() { // ); // } + template __attribute__((always_inline)) inline void delaycycles() { // _delaycycles_ARM(); NOP; delaycycles(); @@ -73,4 +74,31 @@ template<> __attribute__((always_inline)) inline void delaycycles<3>() {NOP;NOP; template<> __attribute__((always_inline)) inline void delaycycles<4>() {NOP;NOP;NOP;NOP;} template<> __attribute__((always_inline)) inline void delaycycles<5>() {NOP;NOP;NOP;NOP;NOP;} +#ifdef __SAM3X8E__ +class SysClockSaver { + SysTick_Type m_Saved; +public: + SysClockSaver(int newTimeValue) { save(newTimeValue); } + void save(int newTimeValue) { + m_Saved.CTRL = SysTick->CTRL; + SysTick->CTRL &= ~(SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk); + m_Saved.LOAD = SysTick->LOAD; + m_Saved.VAL = SysTick->VAL; + + SysTick->VAL = 0; + SysTick->LOAD = newTimeValue; + SysTick->CTRL |= SysTick_CTRL_CLKSOURCE_Msk; + SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk; + } + + void restore() { + SysTick->CTRL &= ~(SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk); + SysTick->LOAD = m_Saved.LOAD; + SysTick->VAL = m_Saved.VAL; + SysTick->CTRL = m_Saved.CTRL; + } +}; + +#endif + #endif \ No newline at end of file diff --git a/fastpin.h b/fastpin.h index e68d04f2..355c316d 100644 --- a/fastpin.h +++ b/fastpin.h @@ -142,6 +142,8 @@ template RwReg FastPin::sPinMask; template volatile RwReg *FastPin::sPort; template volatile RoReg *FastPin::sInPort; +template class FastPinBB : public FastPin {}; + /// 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 class _AVRPIN { @@ -309,18 +311,14 @@ typedef volatile uint32_t * ptr_reg32_t; #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 USE_BITBAND 1 -#if USE_BITBAND == 0 #define _DEFPIN_DUE(PIN, BIT, L) template<> class FastPin : public _DUEPIN {}; \ + template<> class FastPinBB : public _DUEPIN_BITBAND {}; #define _DEFPIN_ARM(PIN, BIT, L) template<> class FastPin : public _ARMPIN {}; -#else - #define _DEFPIN_DUE(PIN, BIT, L) template<> class FastPin : public _DUEPIN_BITBAND {}; - #define _DEFPIN_ARM(PIN, BIT, L) template<> class FastPin : public _ARMPIN_BITBAND {}; \ + template<> class FastPinBB : public _ARMPIN_BITBAND {}; -#endif /////////////////////////////////////////////////////////////////////////////////////////////////////////// // diff --git a/led_sysdefs.h b/led_sysdefs.h index 83fe3122..b2118a09 100644 --- a/led_sysdefs.h +++ b/led_sysdefs.h @@ -6,15 +6,15 @@ #include // for cli/se definitions // Define the rgister types -#if defined(ARDUINO) && ARDUINO < 150 +#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 #else // reuseing/abusing cli/sei defs for due -#define cli() __disable_irq() -#define sei() __enable_irq() +#define cli() __disable_irq(); __disable_fault_irq(); +#define sei() __enable_irq(); __enable_fault_irq(); #endif -- cgit v1.2.3 From 3c6198af23d80fa439d8c661fc00c36db9c52dec Mon Sep 17 00:00:00 2001 From: "danielgarcia@gmail.com" Date: Thu, 27 Jun 2013 17:54:53 +0000 Subject: noise --- clockless.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/clockless.h b/clockless.h index 7c0a5d41..4f264100 100644 --- a/clockless.h +++ b/clockless.h @@ -521,8 +521,6 @@ public: _CTRL; while(data < end) { - // TODO: hand rig asm version of this method. The timings are based on adjusting/studying GCC compiler ouptut. This - // will bite me in the ass at some point, I know it. for(register uint32_t i = 7; i > 0; i--) { AT_BIT_START(*port = 1); if(b& 0x80) {} else { AT_MARK(*port = 0); } -- cgit v1.2.3 From 41b87ea511f965187661f32ab427dee170d318ab Mon Sep 17 00:00:00 2001 From: "danielgarcia@gmail.com" Date: Mon, 8 Jul 2013 17:53:56 +0000 Subject: Checkpoint clockless block controller --- FastSPI_LED2.h | 16 +++- block_clockless.h | 265 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ fastspi_arm.h | 23 ----- 3 files changed, 279 insertions(+), 25 deletions(-) create mode 100644 block_clockless.h diff --git a/FastSPI_LED2.h b/FastSPI_LED2.h index a2e8ab46..a1289037 100644 --- a/FastSPI_LED2.h +++ b/FastSPI_LED2.h @@ -5,6 +5,7 @@ #include "fastpin.h" #include "fastspi.h" #include "clockless.h" +#include "block_clockless.h" #include "clockless2.h" #include "lib8tion.h" #include "hsv2rgb.h" @@ -27,7 +28,11 @@ enum EClocklessChipsets { TM1829 }; -#define NUM_CONTROLLERS 8 +enum EBlockChipsets { + WS2811_PORTC +}; + +#define NUM_CONTROLLERS 32 class CFastSPI_LED2 { struct CControllerInfo { @@ -107,6 +112,13 @@ public: } } + template + CLEDController *addLeds(const struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) { + switch(CHIPSET) { + case WS2811_PORTC: return addLeds(new BlockClocklessController(), data, nLedsOrOffset, nLedsIfOffset); + } + } + void setBrightness(uint8_t scale) { m_nScale = scale; } /// Update all our controllers with the current led colors, using the passed in brightness @@ -128,4 +140,4 @@ extern CFastSPI_LED2 & FastSPI_LED2; extern CFastSPI_LED2 & FastLED; extern CFastSPI_LED2 LEDS; -#endif \ No newline at end of file +#endif diff --git a/block_clockless.h b/block_clockless.h new file mode 100644 index 00000000..d5b9e947 --- /dev/null +++ b/block_clockless.h @@ -0,0 +1,265 @@ + #ifndef __INC_BLOCK_CLOCKLESS_H +#define __INC_BLOCK_CLOCKLESS_H + +#include "controller.h" +#include "lib8tion.h" +#include "led_sysdefs.h" + +// Macro to convert from nano-seconds to clocks and clocks to nano-seconds +// #define NS(_NS) (_NS / (1000 / (F_CPU / 1000000L))) +#if F_CPU < 96000000 +#define NS(_NS) ( (_NS * (F_CPU / 1000000L))) / 1000 +#define CLKS_TO_MICROS(_CLKS) _CLKS / (F_CPU / 1000000L) +#else +#define NS(_NS) ( (_NS * (F_CPU / 2000000L))) / 1000 +#define CLKS_TO_MICROS(_CLKS) _CLKS / (F_CPU / 2000000L) +#endif + +// Macro for making sure there's enough time available +#define NO_TIME(A, B, C) (NS(A) < 3 || NS(B) < 3 || NS(C) < 6) + +#if defined(__MK20DX128__) + extern volatile uint32_t systick_millis_count; +# define MS_COUNTER systick_millis_count +#elif defined(__SAM3X8E__) + extern volatile uint32_t fuckit; +# define MS_COUNTER fuckit +#else +# if defined(CORE_TEENSY) + 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 + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// +// 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. +// +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +// Convinience macros to wrap around the toggling of hi vs. lo +#define SET_LO FLIP ? FastPin::fastset(port, hi) : FastPin::fastset(port, lo); +#define SET_HI FLIP ? FastPin::fastset(port, lo) : FastPin::fastset(port, hi); + +#define PORT_MASK 0x77EFF3FE +#define SKIPLIST ~PORT_MASK + +#if defined(__SAM3X8E__) + +template +class BlockClocklessController : public CLEDController { + typedef typename FastPinBB<1>::port_ptr_t data_ptr_t; + typedef typename FastPinBB<1>::port_t data_t; + + CMinWait mWait; + uint32_t *m_pBuffer; + + void transformData(uint8_t *leddata, int num_leds, uint8_t scale = 255) { + if(m_pBuffer == NULL) { + m_pBuffer = (uint32_t*)malloc(4 * 8 * 3 * num_leds); + } + + uint32_t *outputdata = m_pBuffer; + for(register int i = 0; i < num_leds; i++) { + // register byte rgboffset = R0; + for(int rgb = 0; rgb < 3; rgb++) { + register byte rgboffset = rgb; + register uint32_t mask = 0x01; // 0x01; + register uint32_t output[8] = {0,0,0,0,0,0,0,0}; + + // set the base address to skip through + uint8_t *database = leddata + (3*i) + rgboffset; + for(int j = 0; j < NUM_LANES; j++) { + register uint8_t byte = ~scale8(*database, scale); + if(byte & 0x80) { output[0] |= mask; } + if(byte & 0x40) { output[1] |= mask; } + if(byte & 0x20) { output[2] |= mask; } + if(byte & 0x10) { output[3] |= mask; } + if(byte & 0x08) { output[4] |= mask; } + if(byte & 0x04) { output[5] |= mask; } + if(byte & 0x02) { output[6] |= mask; } + if(byte & 0x01) { output[7] |= mask; } + + // SKIPLIST is a 32 bit constant that contains the bit positions that are off limits, courtesy of port stupidities + do { mask <<= 1; } while(SKIPLIST & mask); + + // move the data pointer forward a lane + database += (num_leds * 3); + } + + // cycle between rgb ordering according to RGB order set (may need per-lane rgb ordering? ugh ugh ugh, i hope not!) + // rgbbase = (rgbbase == RGB0(RGB_ORDER)) ? RGB1(RGB_ORDER) : (rgbbase == RGB1(RGB_ORDER) ? RGB2(RGB_ORDER) : RGB0(RGB_ORDER); + + // copy data out + for(int j = 0; j < 8; j++) { *outputdata++ = output[j]; } + } + } + } + +public: + virtual void init() { + //FastPinBB::setOutput(); + uint8_t pins[] = { 33, 34, 35, 36, 37, 38, 39, 40, 41, 51, 50, 49, 48, 47, 46,45, 44, 9, 8, 7, 6, 5, 4, 3, 10, 72, 0 }; + int i = 0; + while(pins[i]) { pinMode(pins[i++], OUTPUT); } + m_pBuffer = NULL; + } + + virtual void clearLeds(int nLeds) { + showColor(CRGB(0, 0, 0), nLeds, 0); + } + + // set all the leds on the controller to a given color + virtual void showColor(const struct CRGB & data, int nLeds, uint8_t scale = 255) { + mWait.wait(); + cli(); + SysClockSaver savedClock(T1 + T2 + T3); + + // showRGBInternal<0, false>(nLeds, scale, (const byte*)&data); + + // Adjust the timer + long microsTaken = CLKS_TO_MICROS(nLeds * 8 * (T1 + T2 + T3)); + MS_COUNTER += (microsTaken / 1000); + savedClock.restore(); + sei(); + mWait.mark(); + } + + virtual void show(const struct CRGB *rgbdata, int nLeds, uint8_t scale = 255) { + transformData((uint8_t*)rgbdata, nLeds, scale); + mWait.wait(); + cli(); + SysClockSaver savedClock(T1 + T2 + T3); + + // FastPinBB::hi(); delay(1); FastPinBB::lo(); + showRGBInternal<0, true>(nLeds); + + // Adjust the timer + long microsTaken = CLKS_TO_MICROS(nLeds * 8 * (T1 + T2 + T3)); + MS_COUNTER += (microsTaken / 1000); + savedClock.restore(); + sei(); + mWait.mark(); + } + +#ifdef SUPPORT_ARGB + virtual void show(const struct CARGB *rgbdata, int nLeds, uint8_t scale = 255) { + transformData((uint8_t*)rgbdata, nLeds, scale); + + mWait.wait(); + cli(); + SysClockSaver savedClock(T1 + T2 + T3); + + showRGBInternal<1, true>(nLeds, scale, (const byte*)rgbdata); + + // Adjust the timer + long microsTaken = CLKS_TO_MICROS(nLeds * 8 * (T1 + T2 + T3)); + MS_COUNTER += (microsTaken / 1000); + savedClock.restore(); + sei(); + mWait.mark(); + } +#endif + +// I hate using defines for these, should find a better representation at some point +#define _CTRL CTPTR[0] +#define _LOAD CTPTR[1] +#define _VAL CTPTR[2] + + __attribute__((always_inline)) static inline void wait_loop_start(register volatile uint32_t *CTPTR) { + __asm__ __volatile__ ( + "L_%=: ldr.w r8, [%0]\n" + " tst.w r8, #65536\n" + " beq.n L_%=\n" + : /* no outputs */ + : "r" (CTPTR) + : "r8" + ); + } + + template __attribute__((always_inline)) static inline void wait_loop_mark(register volatile uint32_t *CTPTR) { + __asm__ __volatile__ ( + "L_%=: ldr.w r8, [%0, #8]\n" + " cmp.w r8, %1\n" + " bhi.n L_%=\n" + : /* no outputs */ + : "r" (CTPTR), "I" (MARK) + : "r8" + ); + } + + __attribute__((always_inline)) static inline void mark_port(register data_ptr_t port, register int val) { + __asm__ __volatile__ ( + " str.w %0, [%1]\n" + : /* no outputs */ + : "r" (val), "r" (port) + ); + } +#define AT_BIT_START(X) wait_loop_start(CTPTR); X; +#define AT_MARK(X) wait_loop_mark(CTPTR); { X; } +#define AT_END(X) wait_loop_mark(CTPTR); { X; } + +// #define AT_BIT_START(X) while(!(_CTRL & SysTick_CTRL_COUNTFLAG_Msk)); { X; } +// #define AT_MARK(X) while(_VAL > T1_MARK); { X; } +// #define AT_END(X) while(_VAL > T2_MARK); { X; } + +//#define AT_MARK(X) delayclocks_until(_VAL); X; +//#define AT_END(X) delayclocks_until(_VAL); X; + +#define TOTAL (T1 + T2 + T3) + +#define T1_MARK (TOTAL - T1) +#define T2_MARK (T1_MARK - T2) + template __attribute__((always_inline)) static inline void delayclocks_until(register byte b) { + __asm__ __volatile__ ( + " sub %0, %0, %1\n" + "L_%=: subs %0, %0, #2\n" + " bcs.n L_%=\n" + : /* no outputs */ + : "r" (b), "I" (MARK) + : /* no clobbers */ + ); + + } + +#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. + template void showRGBInternal(register int nLeds) { + register uint32_t *data = m_pBuffer; + register uint32_t *end = data + 8*(nLeds*3); + + register volatile uint32_t *CTPTR asm("r6")= &SysTick->CTRL; FORCE_REFERENCE(CTPTR); + + // Setup and start the clock + _LOAD = TOTAL; + _VAL = 0; + _CTRL |= SysTick_CTRL_CLKSOURCE_Msk; + _CTRL |= SysTick_CTRL_ENABLE_Msk; + + // read to clear the loop flag + _CTRL; + + while(data < end) { + register uint32_t d = *data++; + // turn everything in the port on at the start + AT_BIT_START(REG_PIOC_SODR = PORT_MASK); + + // part way through early clear the ones that should be 0 bits + AT_MARK(REG_PIOC_CODR = d); + + // now all the way through zero everyone + AT_END(REG_PIOC_CODR= PORT_MASK); + }; + } +}; + +#endif + +#endif \ No newline at end of file diff --git a/fastspi_arm.h b/fastspi_arm.h index 76e0b0d1..747be855 100644 --- a/fastspi_arm.h +++ b/fastspi_arm.h @@ -118,29 +118,6 @@ public: } } - static inline void set_ctar1_bits(int bits) { - // Set ctar1 to 16 bits - int ctar = SPI0_CTAR1; - - // clear the FMSZ bits - ctar &= SPI_CTAR_FMSZ(0x0F); - ctar |= SPI_CTAR_FMSZ((bits-1) & 0x0F); - - update_ctar1(ctar); - } - - static inline void set_ctar0_bits(int bits) { - // Set ctar1 to 16 bits - int ctar = SPI0_CTAR1; - - // clear the FMSZ bits - ctar &= SPI_CTAR_FMSZ(0x0F); - ctar |= SPI_CTAR_FMSZ((bits-1) & 0x0F); - - update_ctar1(ctar); - } - - void setSPIRate() { // Configure CTAR0, defaulting to 8 bits and CTAR1, defaulting to 16 bits uint32_t _PBR = 0; -- cgit v1.2.3 From 24b3fd537c1dfa9ee5fe783b63c8112ef3fa9c21 Mon Sep 17 00:00:00 2001 From: "danielgarcia@gmail.com" Date: Tue, 23 Jul 2013 04:49:59 +0000 Subject: checkpointing --- FastSPI_LED2.h | 5 +++++ block_clockless.h | 65 +++++++++++++++++++++++++++---------------------------- clockless.h | 4 ---- fastpin.h | 2 +- 4 files changed, 38 insertions(+), 38 deletions(-) diff --git a/FastSPI_LED2.h b/FastSPI_LED2.h index 67235847..c2294707 100644 --- a/FastSPI_LED2.h +++ b/FastSPI_LED2.h @@ -104,6 +104,7 @@ public: case UCS1903: return addLeds(new UCS1903Controller400Khz(), data, nLedsOrOffset, nLedsIfOffset); case WS2811: return addLeds(new WS2811Controller800Khz(), data, nLedsOrOffset, nLedsIfOffset); } + return NULL; } template @@ -118,13 +119,17 @@ public: case UCS1903: return addLeds(new UCS1903Controller400Khz(), data, nLedsOrOffset, nLedsIfOffset); case WS2811: return addLeds(new WS2811Controller800Khz(), data, nLedsOrOffset, nLedsIfOffset); } + return NULL; } template CLEDController *addLeds(const struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) { switch(CHIPSET) { +#ifdef HAS_BLOCKLESS case WS2811_PORTC: return addLeds(new BlockClocklessController(), data, nLedsOrOffset, nLedsIfOffset); +#endif } + return NULL; } void setBrightness(uint8_t scale) { m_nScale = scale; } diff --git a/block_clockless.h b/block_clockless.h index d5b9e947..bf1b7cbe 100644 --- a/block_clockless.h +++ b/block_clockless.h @@ -50,7 +50,7 @@ #define SKIPLIST ~PORT_MASK #if defined(__SAM3X8E__) - +#define HAS_BLOCKLESS 1 template class BlockClocklessController : public CLEDController { typedef typename FastPinBB<1>::port_ptr_t data_ptr_t; @@ -66,38 +66,37 @@ class BlockClocklessController : public CLEDController { uint32_t *outputdata = m_pBuffer; for(register int i = 0; i < num_leds; i++) { - // register byte rgboffset = R0; - for(int rgb = 0; rgb < 3; rgb++) { - register byte rgboffset = rgb; - register uint32_t mask = 0x01; // 0x01; - register uint32_t output[8] = {0,0,0,0,0,0,0,0}; - - // set the base address to skip through - uint8_t *database = leddata + (3*i) + rgboffset; - for(int j = 0; j < NUM_LANES; j++) { - register uint8_t byte = ~scale8(*database, scale); - if(byte & 0x80) { output[0] |= mask; } - if(byte & 0x40) { output[1] |= mask; } - if(byte & 0x20) { output[2] |= mask; } - if(byte & 0x10) { output[3] |= mask; } - if(byte & 0x08) { output[4] |= mask; } - if(byte & 0x04) { output[5] |= mask; } - if(byte & 0x02) { output[6] |= mask; } - if(byte & 0x01) { output[7] |= mask; } - - // SKIPLIST is a 32 bit constant that contains the bit positions that are off limits, courtesy of port stupidities - do { mask <<= 1; } while(SKIPLIST & mask); - - // move the data pointer forward a lane - database += (num_leds * 3); - } - - // cycle between rgb ordering according to RGB order set (may need per-lane rgb ordering? ugh ugh ugh, i hope not!) - // rgbbase = (rgbbase == RGB0(RGB_ORDER)) ? RGB1(RGB_ORDER) : (rgbbase == RGB1(RGB_ORDER) ? RGB2(RGB_ORDER) : RGB0(RGB_ORDER); - - // copy data out - for(int j = 0; j < 8; j++) { *outputdata++ = output[j]; } - } + register byte rgboffset = RGB_BYTE0(RGB_ORDER); + for(int rgb = 0; rgb < 3; rgb++) { + register uint32_t mask = 0x01; // 0x01; + register uint32_t output[8] = {0,0,0,0,0,0,0,0}; + + // set the base address to skip through + uint8_t *database = leddata + (3*i) + rgboffset; + for(int j = 0; j < NUM_LANES; j++) { + register uint8_t byte = ~scale8(*database, scale); + if(byte & 0x80) { output[0] |= mask; } + if(byte & 0x40) { output[1] |= mask; } + if(byte & 0x20) { output[2] |= mask; } + if(byte & 0x10) { output[3] |= mask; } + if(byte & 0x08) { output[4] |= mask; } + if(byte & 0x04) { output[5] |= mask; } + if(byte & 0x02) { output[6] |= mask; } + if(byte & 0x01) { output[7] |= mask; } + + // SKIPLIST is a 32 bit constant that contains the bit positions that are off limits, courtesy of port stupidities + do { mask <<= 1; } while(SKIPLIST & mask); + + // move the data pointer forward a lane + database += (num_leds * 3); + + // cycle between rgb ordering according to RGB order set (may need per-lane rgb ordering? ugh ugh ugh, i hope not!) + rgboffset = (rgboffset == RGB_BYTE0(RGB_ORDER)) ? RGB_BYTE1(RGB_ORDER) : (rgboffset == RGB_BYTE1(RGB_ORDER) ? RGB_BYTE2(RGB_ORDER) : RGB_BYTE0(RGB_ORDER)); + + // copy data out + for(int j = 0; j < 8; j++) { *outputdata++ = output[j]; } + } + } } } diff --git a/clockless.h b/clockless.h index 4f264100..270fcfc5 100644 --- a/clockless.h +++ b/clockless.h @@ -144,7 +144,6 @@ public: // gcc will use register Y for the this pointer. template static void showRGBInternal(register int nLeds, register uint8_t scale, register const byte *rgbdata) { register byte *data = (byte*)rgbdata; - data_t mask = FastPin::mask(); register data_ptr_t port = FastPin::port(); nLeds *= (3 + SKIP); register uint8_t *end = data + nLeds; @@ -266,11 +265,8 @@ public: } #endif - // 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. template static void showRGBInternal(register int nLeds, register uint8_t scale, register const byte *rgbdata) { register byte *data = (byte*)rgbdata; - data_t mask = FastPin::mask(); register data_ptr_t port = FastPin::port(); nLeds *= (3 + SKIP); register uint8_t *end = data + nLeds; diff --git a/fastpin.h b/fastpin.h index 3ef291d1..88fa1134 100644 --- a/fastpin.h +++ b/fastpin.h @@ -385,7 +385,7 @@ _DEFPIN_AVR(20, 2, F); _DEFPIN_AVR(21, 1, F); _DEFPIN_AVR(22, 16, D); _DEFPIN_AV #define SPI_DATA 2 #define SPI_CLOCK 1 -#define SPI_SELECT 3 +#define SPI_SELECT 0 #define AVR_HARDWARE_SPI #elif defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__) -- cgit v1.2.3 From c82953d4b8106a7fc1a6e710bbfa4b4c8c839437 Mon Sep 17 00:00:00 2001 From: "danielgarcia@gmail.com" Date: Tue, 23 Jul 2013 23:15:54 +0000 Subject: Merge cleanup - add function to globally clear all led data without calling show --- FastSPI_LED2.cpp | 16 ++++++++++------ FastSPI_LED2.h | 3 ++- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/FastSPI_LED2.cpp b/FastSPI_LED2.cpp index 34849fa1..6d08dc2a 100644 --- a/FastSPI_LED2.cpp +++ b/FastSPI_LED2.cpp @@ -71,12 +71,16 @@ void CFastSPI_LED2::showColor(const struct CRGB & color, uint8_t scale) { void CFastSPI_LED2::clear(boolean includeLedData) { showColor(CRGB(0,0,0), 0); if(includeLedData) { - for(int i = 0; i < m_nControllers; i++) { - if(m_Controllers[i].pLedData != NULL) { - memset8((void*)m_Controllers[i].pLedData, 0, sizeof(struct CRGB) * m_Controllers[i].nLeds); - } else { - return; - } + clearData(); + } +} + +void CFastSPI_LED2::clearData() { + for(int i = 0; i < m_nControllers; i++) { + if(m_Controllers[i].pLedData != NULL) { + memset8((void*)m_Controllers[i].pLedData, 0, sizeof(struct CRGB) * m_Controllers[i].nLeds); + } else { + return; } } } \ No newline at end of file diff --git a/FastSPI_LED2.h b/FastSPI_LED2.h index 217735fb..196a9cc3 100644 --- a/FastSPI_LED2.h +++ b/FastSPI_LED2.h @@ -29,7 +29,6 @@ enum EClocklessChipsets { WS2812B, UCS1903, TM1829 - UCS1903 }; enum EBlockChipsets { @@ -151,6 +150,8 @@ public: void clear(boolean includeLedData = true); + void clearData(); + void showColor(const struct CRGB & color, uint8_t scale); void showColor(const struct CRGB & color) { showColor(color, m_nScale); } -- cgit v1.2.3 From 9fa0182de157f7bc5bcfffa8bcffd1fd0a11fed2 Mon Sep 17 00:00:00 2001 From: "danielgarcia@gmail.com" Date: Tue, 8 Oct 2013 04:58:31 +0000 Subject: Fix code typo --- FastSPI_LED2.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FastSPI_LED2.h b/FastSPI_LED2.h index 7cc4da4c..8bcedc93 100644 --- a/FastSPI_LED2.h +++ b/FastSPI_LED2.h @@ -144,7 +144,7 @@ public: } void setBrightness(uint8_t scale) { m_nScale = scale; } - void getBrightness() { return m_nScale; } + uint8_t getBrightness() { return m_nScale; } /// Update all our controllers with the current led colors, using the passed in brightness void show(uint8_t scale); -- cgit v1.2.3 From 7185b516211105fc9644063548240c0057d77012 Mon Sep 17 00:00:00 2001 From: "danielgarcia@gmail.com" Date: Tue, 8 Oct 2013 06:52:12 +0000 Subject: Adding code to test pin/port mappings. --- examples/Pintest/Pintest.ino | 105 +++++++++++++++++++++++++++++++++++++++++++ fastpin.h | 8 ++++ 2 files changed, 113 insertions(+) create mode 100644 examples/Pintest/Pintest.ino diff --git a/examples/Pintest/Pintest.ino b/examples/Pintest/Pintest.ino new file mode 100644 index 00000000..727341e7 --- /dev/null +++ b/examples/Pintest/Pintest.ino @@ -0,0 +1,105 @@ + +#include + +const char *getPort(void *portPtr) { +#ifdef PORTA + if(portPtr == (void*)&PORTA) { return "PORTA"; } +#endif +#ifdef PORTB + if(portPtr == (void*)&PORTB) { return "PORTB"; } +#endif +#ifdef PORTC + if(portPtr == (void*)&PORTC) { return "PORTC"; } +#endif +#ifdef PORTD + if(portPtr == (void*)&PORTD) { return "PORTD"; } +#endif +#ifdef PORTE + if(portPtr == (void*)&PORTE) { return "PORTE"; } +#endif +#ifdef PORTF + if(portPtr == (void*)&PORTF) { return "PORTF"; } +#endif +#ifdef PORTG + if(portPtr == (void*)&PORTG) { return "PORTG"; } +#endif +#ifdef PORTH + if(portPtr == (void*)&PORTH) { return "PORTH"; } +#endif +#ifdef PORTI + if(portPtr == (void*)&PORTI) { return "PORTI"; } +#endif +#ifdef PORTJ + if(portPtr == (void*)&PORTJ) { return "PORTJ"; } +#endif +#ifdef PORTK + if(portPtr == (void*)&PORTK) { return "PORTK"; } +#endif +#ifdef PORTL + if(portPtr == (void*)&PORTL) { return "PORTL"; } +#endif +#ifdef GPIO_A_PDOR + if(portPtr == (void*)&GPIO_A_PDOR) { return "GPIO_A_PDOR"; } +#endif +#ifdef GPIO_B_PDOR + if(portPtr == (void*)&GPIO_B_PDOR) { return "GPIO_B_PDOR"; } +#endif +#ifdef GPIO_C_PDOR + if(portPtr == (void*)&GPIO_C_PDOR) { return "GPIO_C_PDOR"; } +#endif +#ifdef GPIO_D_PDOR + if(portPtr == (void*)&GPIO_D_PDOR) { return "GPIO_D_PDOR"; } +#endif +#ifdef GPIO_E_PDOR + if(portPtr == (void*)&GPIO_E_PDOR) { return "GPIO_E_PDOR"; } +#endif +#ifdef REG_PIO_A_ODSR + if(portPtr == (void*)®_PIO_A_ODSR) { return "REG_PIO_A_ODSR"; } +#endif +#ifdef REG_PIO_B_ODSR + if(portPtr == (void*)®_PIO_B_ODSR) { return "REG_PIO_B_ODSR"; } +#endif +#ifdef REG_PIO_C_ODSR + if(portPtr == (void*)®_PIO_C_ODSR) { return "REG_PIO_C_ODSR"; } +#endif +#ifdef REG_PIO_D_ODSR + if(portPtr == (void*)®_PIO_D_ODSR) { return "REG_PIO_D_ODSR"; } +#endif + return "unknown"; +} + +template void CheckPin() +{ + CheckPin(); + + RwReg *systemThinksPortIs = portOutputRegister(digitalPinToPort(PIN)); + RwReg systemThinksMaskIs = digitalPinToBitMask(PIN); + + Serial.print("Pin "); Serial.print(PIN); Serial.print(": Port "); + + if(systemThinksPortIs == FastPin::port()) { + Serial.print("valid & mask "); + } else { + Serial.print("invalid, is "); Serial.print(getPort((void*)FastPin::port())); Serial.print(" should be "); + Serial.print(getPort((void*)systemThinksPortIs)); + Serial.print(" & mask "); + } + + if(systemThinksMaskIs == FastPin::mask()) { + Serial.println("valid."); + } else { + Serial.print("invalid, is "); Serial.print(FastPin::mask()); Serial.print(" should be "); Serial.println(systemThinksMaskIs); + } +} + +template<> void CheckPin<-1> () {} + +void setup() { + Serial.begin(38400); + Serial.println("resetting!"); +} + +void loop() { + CheckPin(); + delay(10000); +} \ No newline at end of file diff --git a/fastpin.h b/fastpin.h index 88fa1134..386fbb98 100644 --- a/fastpin.h +++ b/fastpin.h @@ -330,6 +330,8 @@ typedef volatile uint32_t * ptr_reg32_t; #if defined(__AVR_ATmega328P__) || defined(__AVR_ATmega168__) // 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); @@ -346,6 +348,7 @@ _DEFPIN_AVR(16, 0x04, C); _DEFPIN_AVR(17, 0x08, C); _DEFPIN_AVR(18, 0x10, C); _D _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); @@ -376,6 +379,7 @@ _DEFPIN_AVR(68, 64, K); _DEFPIN_AVR(69, 128, K); // 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); @@ -393,6 +397,7 @@ _DEFPIN_AVR(20, 2, F); _DEFPIN_AVR(21, 1, F); _DEFPIN_AVR(22, 16, D); _DEFPIN_AV _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); @@ -416,6 +421,7 @@ _DEFPIN_AVR(44, 64, F); _DEFPIN_AVR(45, 128, F); // leonard defs _IO(B); _IO(C); _IO(D); _IO(E); _IO(F); +#define MAX_PIN 23 _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); @@ -431,6 +437,7 @@ _DEFPIN_AVR(20, 32, F); _DEFPIN_AVR(21, 16, F); _DEFPIN_AVR(22, 2, F); _DEFPIN_A _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); @@ -452,6 +459,7 @@ 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); -- cgit v1.2.3 From 0dfb792d57ed7b2ce34985fe624d56c8640f1531 Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Sun, 10 Nov 2013 15:18:55 -0800 Subject: Removing unused files --- FastSPI_LED.cpp | 746 -------------------------------------------------------- FastSPI_LED.h | 142 ----------- 2 files changed, 888 deletions(-) delete mode 100644 FastSPI_LED.cpp delete mode 100644 FastSPI_LED.h diff --git a/FastSPI_LED.cpp b/FastSPI_LED.cpp deleted file mode 100644 index e4715da3..00000000 --- a/FastSPI_LED.cpp +++ /dev/null @@ -1,746 +0,0 @@ -#if defined(ARDUINO) && ARDUINO >= 100 - #include "Arduino.h" - #include -#else - #include "WProgram.h" - #include -#include "wiring.h" -#endif -#include "avr/interrupt.h" -#include "avr/io.h" -#include "FastSPI_LED.h" - -// #define DEBUG_SPI -#ifdef DEBUG_SPI -# define DPRINT Serial.print -# define DPRINTLN Serial.println -#else -# define DPRINT(x) -# define DPRINTLN(x) -#endif - -// #define COUNT_ROUNDS 1 - -// some spi defines -// Duemilanove and mini w/328 -#if defined(__AVR_ATmega328P__) || defined(__AVR_ATmega168__) -#define SPI_PORT PORTB -#define SPI_DDR DDRB -#define SPI_PIN PINB -#define SPI_MOSI 3 // Arduino pin 11. -#define SPI_MISO 4 // Arduino pin 12. -#define SPI_SCK 5 // Arduino pin 13. -#define SPI_SSN 2 // Arduino pin 10. -#define DATA_PIN 11 -#define SLAVE_PIN 12 -#define CLOCK_PIN 13 -#define LATCH_PIN 10 -#define TIMER_AVAILABLE 1 - -// Mega. -#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) -#define SPI_PORT PORTB -#define SPI_DDR DDRB -#define SPI_PIN PINB -#define SPI_MOSI 2 // Arduino pin 51. -#define SPI_MISO 3 // Arduino pin 50. -#define SPI_SCK 1 // Arduino pin 52. -#define SPI_SSN 0 // Arduino pin 53. -#define DATA_PIN 51 -#define SLAVE_PIN 50 -#define CLOCK_PIN 52 -#define LATCH_PIN 53 -#define TIMER_AVAILABLE 1 - -// Leonardo, teensy, blinkm -#elif defined(__AVR_ATmega32U4__) - -#define SPI_PORT PORTB -#define SPI_DDR DDRB -#define SPI_PIN PINB -#define SPI_MOSI 2 // Arduino pin 10. -#define SPI_MISO 3 // Arduino pin 11. -#define SPI_SCK 1 // Arduino pin 9. -#define SPI_SSN 0 // Arduino pin 8. -#define DATA_PIN 16 // PB2, pin 10, Digital16 -#define SLAVE_PIN 14 // PB3, pin 11, Digital14 -#define CLOCK_PIN 15 // PB1, pin 9, Digital15 -#define LATCH_PIN 17 // PB0, pin 8, Digital17 -#define TIMER_AVAILABLE 1 - -#elif defined(__MK20DX128__) // for Teensy 3.0 -#define SPI_PORT PORTB -#define SPI_DDR DDRB -#define SPI_PIN PINB -#define SPI_MOSI 2 // Arduino pin 10. -#define SPI_MISO 3 // Arduino pin 11. -#define SPI_SCK 1 // Arduino pin 9. -#define SPI_SSN 0 // Arduino pin 8. -#define DATA_PIN 11 // PB2, pin 10, Digital16 -#define SLAVE_PIN 12 // PB3, pin 11, Digital14 -#define CLOCK_PIN 13 // PB1, pin 9, Digital15 -#define LATCH_PIN 10 // PB0, pin 8, Digital17 - -#define NOT_A_PIN NULL -#define TIMER_AVAILABLE 0 -#endif - -#define BIT_HI(R, P) (R) |= _BV(P) -#define BIT_LO(R, P) (R) &= ~_BV(P) - -#define MASK_HI(R, P) (R) |= (P) -#define MASK_LO(R, P) (R) &= ~(P) - -// HL1606 defines -//Commands for each LED to be ORd together. - -#define TM_1606 153 - -#define Command B10000000 -#define Commandx2 B11000000 //Use this one to make dimming twice as fast. -#define BlueOff B00000000 -#define BlueOn B00010000 -#define BlueUp B00100000 -#define BlueDown B00110000 -#define RedOff B00000000 -#define RedOn B00000100 -#define RedUp B00001000 -#define RedDown B00001100 -#define GreenOff B00000000 -#define GreenOn B00000001 -#define GreenUp B00000010 -#define GreenDown B00000011 - -#define BRIGHT_MAX 256 - -// Some ASM defines -#if defined(__arm__) -# define NOP __asm__ __volatile__ ("nop\n"); -#else -# define NOP __asm__ __volatile__ ("cp r0,r0\n"); -#endif - -#define NOP2 NOP NOP -#define NOP1 NOP -#define NOP3 NOP NOP2 -#define NOP4 NOP NOP3 -#define NOP5 NOP NOP4 -#define NOP6 NOP NOP5 -#define NOP7 NOP NOP6 -#define NOP8 NOP NOP7 -#define NOP9 NOP NOP8 -#define NOP10 NOP NOP9 -#define NOP11 NOP NOP10 -#define NOP12 NOP NOP11 -#define NOP13 NOP NOP12 -#define NOP14 NOP NOP13 -#define NOP15 NOP10 NOP5 -#define NOP16 NOP14 NOP2 -#define NOP20 NOP10 NOP10 -#define NOP22 NOP20 NOP2 - -#define NOP_SHORT NOP2 -#define NOP_LONG NOP5 - -// TODO: Better: MASH_HI(_PORT,PIN); NOP; NOP; MASK_SET(_PORT, PIN, X & (1< 4) { nLedBlocks = 0; } - } else { - nLedBlocks = 0; - } - break; - case SPI_HL1606: - // nTimerKick = 153; // shooting for ~ 125,000 rounds/second - 66% cpu - nBrightIdx = (m_nLeds <= 20) ? (256 / 80) : (256 / 32); - nBrightMax = 256 - nBrightIdx; - nCount = nCountBase; - break; - case SPI_LPD6803: - nBrightIdx = 0; - break; - default: - // no one else does anything 'special' here - break; - - } - - // set default cpu percentage targets - switch(FastSPI_LED.m_eChip) { - case CFastSPI_LED::SPI_595: m_cpuPercentage = 53; break; - case CFastSPI_LED::SPI_LPD6803: m_cpuPercentage = 50; break; - case CFastSPI_LED::SPI_HL1606: m_cpuPercentage = 65; break; - case CFastSPI_LED::SPI_LPD8806: - case CFastSPI_LED::SPI_SM16716: - case CFastSPI_LED::SPI_WS2801: m_cpuPercentage = 25; break; - case CFastSPI_LED::SPI_TM1809: m_cpuPercentage = 5; break; - case CFastSPI_LED::SPI_UCS1903: m_cpuPercentage = 5; break; -} - - // set default spi rates -switch(m_eChip) { - case CFastSPI_LED::SPI_HL1606: - m_nDataRate = 2; - if(m_nLeds > 20) { - m_nDataRate = 3; - } - break; - case CFastSPI_LED::SPI_595: - case CFastSPI_LED::SPI_LPD6803: - case CFastSPI_LED::SPI_LPD8806: - case CFastSPI_LED::SPI_WS2801: - case CFastSPI_LED::SPI_SM16716: - case CFastSPI_LED::SPI_TM1809: - case CFastSPI_LED::SPI_UCS1903: - m_nDataRate = 0; - break; -} -} - -#if TIMER_AVAILABLE -// Why not use function pointers? They're expensive! Having TIMER1_OVF_vect call a chip -// specific interrupt function through a pointer adds approximately 1.3µs over the if/else blocks -// below per cycle. That doesn't sound like a lot, though, right? Wrong. For the HL-1606, with -// 40 leds, you may want to push up to 125,000 cycles/second. 1.3µs extra per cycle means 162.5 -// milliseconds. Put a different way, you just cost yourself 16.25% of your cpu time. This is on -// a 16Mhz processor. On an 8Mhz processor, the hit is even more severe, percentage wise. 1.3µs -// is also, for another point of data, only 20 clocks on a 20Mhz processor. Every extra register push/pop -// that needs to be added to the function is 4 cycles (2 for push, 2 for pop) - or .25µs. To call through -// a function pointer requires two pushes and two pops (to save r30/r31) or 8 cycles, plus the actual call -// which is 4 clocks, and then a reti which is another 4 clocks, plus the loading of the function pointer -// which is itself 4 clocks (2 clocks for each of loading the high and low bytes of the function's address) -// The asm below only adds 12 clocks (and did some other tightening in the hl1606 code to get us closer -// to being able to saturate as well) - wouldn't have to worry push/pop'ing r1 if someone out there wasn't -// misbehaving and using r1 for something other than zero! -extern "C" void TIMER1_OVF_vect(void) __attribute__ ((signal,naked,__INTR_ATTRS)); -void TIMER1_OVF_vect(void) { -#if 1 - __asm__ __volatile__ ( "push r1"); - __asm__ __volatile__ ( "lds r1, nChip" ); - __asm__ __volatile__ ( "sbrc r1, 1" ); // if(nChip == SPI_HL1606) { - __asm__ __volatile__ ( "rjmp do1606" ); // do1606(); - __asm__ __volatile__ ( "sbrs r1, 0" ); // } else if(nChip != SPI_595) { - __asm__ __volatile__ ( "rjmp do6803" ); // do6803(); - __asm__ __volatile__ ( "do595: pop r1" ); // } else if(nChip == SPI_595) { - __asm__ __volatile__ ( " jmp spi595" ); // do595(); - __asm__ __volatile__ ( "do6803: pop r1" ); // } - __asm__ __volatile__ ( " jmp spilpd6803" ); - __asm__ __volatile__ ( "do1606: pop r1" ); - __asm__ __volatile__ ( " jmp spihl1606" ); -#else - __asm__ __volatile__ ( "lds r1, nChip" ); - __asm__ __volatile__ ( "sbrc r1, 1" ); - __asm__ __volatile__ ( "jmp spihl1606" ); - __asm__ __volatile__ ( "sbrc r1, 2" ); - __asm__ __volatile__ ( "jmp spilpd6803"); - __asm__ __volatile__ ( "jmp spi595" ); -#endif -} - -// if(FastSPI_LED.m_eChip == CFastSPI_LED::SPI_HL1606) -ISR(spihl1606) -{ - static unsigned char nBrightness = 1; - register unsigned char aByte = Command; - - //if(pData == FastSPI_LED.m_pData) - if(nCount != 0) - { - register unsigned char nCheck = nBrightness; - if(*(--pData) > nCheck) { aByte |= BlueOn; } if(*(--pData) > nCheck) { aByte |= GreenOn; } if(*(--pData) > nCheck) { aByte |= RedOn; } - // SPI_B; - SPI_A(aByte); - nCount--; - return; -} -else -{ - BIT_HI(SPI_PORT,SPI_SSN); - pData = FastSPI_LED.m_pDataEnd; - BIT_LO(SPI_PORT,SPI_SSN); - if (nBrightness <= nBrightMax) { nBrightness += nBrightIdx; } - else { nBrightness = 1; } - BIT_HI(SPI_PORT,SPI_SSN); - // if( (nBrightness += nBrightIdx) > BRIGHT_MAX) { nBrightness = 1; } - nCount = nCountBase; - BIT_LO(SPI_PORT,SPI_SSN); - SPI_A(aByte); - return; -} -} - //else if(FastSPI_LED.m_eChip == CFastSPI_LED::SPI_595) -ISR(spi595) -{ - static unsigned char nBrightness = 1; - if(nBrightness > nBrightMax) { nBrightness = 1; } - else { nBrightness += nBrightIdx; } - // register unsigned char nCheck = nBrightness; - register unsigned char aByte; - //register unsigned char * - { - BIT_LO(SPI_PORT,SPI_SSN); - -#define BIT_SET(nBit) if(*(--pData) >= nBrightness) { aByte |= nBit; } -#define BLOCK8 aByte=0; BIT_SET(0x80); BIT_SET(0x40); BIT_SET(0x20); BIT_SET(0x10); BIT_SET(0x08); BIT_SET(0x04); BIT_SET(0x02); BIT_SET(0x01); -#define COMMANDA BLOCK8 ; SPI_A(aByte); -#define COMMANDB BLOCK8 ; SPI_B; SPI_A(aByte); -#define COM3A COMMANDA ; COMMANDB ; COMMANDB -#define COM3B COMMANDB ; COMMANDB ; COMMANDB -#define COM12 COM3A ; COM3B ; COM3B ; COM3B - - // If we have blocks of 3 8 bit shift registers, that gives us 8 rgb leds, we'll do some aggressive - // loop unrolling for cases where we have multiples of 3 shift registers - i should expand this out to - // handle a wider range of cases at some point - switch(nLedBlocks) { - case 4: COM12; break; - case 3: COM3A; COM3B; COM3B; break; - case 2: COM3A; COM3B; break; - case 1: COM3A; break; - default: - BLOCK8; - SPI_A(aByte); - for(register char i = FastSPI_LED.m_nLeds; i > 8; i-= 8) { - BLOCK8; - SPI_B; - SPI_A(aByte); - } - } - BIT_HI(SPI_PORT,SPI_SSN); - pData = FastSPI_LED.m_pDataEnd; - return; - } -} - //else // if(FastSPI_LED.m_eChip == CFastSPI_LED::SPI_LPD6803) -ISR(spilpd6803) -{ - static unsigned char nState=1; - if(FastSPI_LED.m_eChip == CFastSPI_LED::SPI_LPD6803) - { - if(nState==1) - { - SPI_A(0); - if(FastSPI_LED.m_nDirty==1) { - nState = 0; - FastSPI_LED.m_nDirty = 0; - SPI_B; - SPI_A(0); - pData = FastSPI_LED.m_pData; - return; - } - SPI_B; - SPI_A(0); - return; - } - else - { - register unsigned int command; - command = 0x8000; - command |= (*(pData++) & 0xF8) << 7; // red is the high 5 bits - command |= (*(pData++) & 0xF8) << 2; // green is the middle 5 bits - command |= *(pData++) >> 3 ; // blue is the low 5 bits - SPI_B; - SPI_A( (command>>8) &0xFF); - if(pData == FastSPI_LED.m_pDataEnd) { - nState = 1; - } - SPI_B; - SPI_A( command & 0xFF); - return; -} -} -} -#endif - -void CFastSPI_LED::show() { - static byte run=0; - - setDirty(); - if(FastSPI_LED.m_eChip == CFastSPI_LED::SPI_WS2801) - { - cli(); - register byte *p = m_pData; - register byte *e = m_pDataEnd; - - // If we haven't run through yet - nothing has primed the SPI bus, - // and the first SPI_B will block. - if(!run) { - run = 1; - SPI_A(*p++); - SPI_B; SPI_A(*p++); - SPI_B; SPI_A(*p++); - } - while(p != e) { - SPI_B; SPI_A(*p++); - SPI_B; SPI_A(*p++); - SPI_B; SPI_A(*p++); - } - m_nDirty = 0; - sei(); - } - else if(FastSPI_LED.m_eChip == CFastSPI_LED::SPI_SM16716) - { - cli(); - register byte *p = m_pData; - register byte *e = m_pDataEnd; - - // SM167176 starts with a control block of 50 bits - SPI_A(0); - SPI_B; SPI_A(0); - SPI_B; SPI_A(0); - SPI_B; SPI_A(0); - SPI_B; SPI_A(0); - SPI_B; SPI_A(0); - SPI_B; - SPI_BIT(0); - SPI_BIT(0); - - while(p != e) { - // every 24 bit block starts with a 1 bit being sent - SPI_BIT(1); - SPI_A(*p++); SPI_B; - SPI_A(*p++); SPI_B; - SPI_A(*p++); SPI_B; - } - m_nDirty = 0; - sei(); -}else if(FastSPI_LED.m_eChip == CFastSPI_LED::SPI_UCS1903) -{ - cli(); - m_nDirty = 0; - register byte *pData = m_pData; - for(int iPins = 0; iPins < m_nPins; iPins++) { - register byte *pEnd = pData + m_pPinLengths[iPins]; - register unsigned char PIN = digitalPinToBitMask(FastSPI_LED.m_pPins[iPins]); - register volatile uint8_t *pPort = m_pPorts[iPins]; - - if(pPort == NOT_A_PIN) { /* do nothing */ } - else { UCS1903_ALL(*pPort, pData, pEnd); } - } - sei(); -} -else if(FastSPI_LED.m_eChip == CFastSPI_LED::SPI_TM1809) -{ - cli(); - m_nDirty = 0; - register byte *pData = m_pData; - for(int iPins = 0; iPins < m_nPins; iPins++) { - register byte *pEnd = pData + m_pPinLengths[iPins]; - register unsigned char PIN = digitalPinToBitMask(FastSPI_LED.m_pPins[iPins]); - register volatile uint8_t *pPort = m_pPorts[iPins]; - - if(pPort == NOT_A_PIN) { /* do nothing */ } - else { TM1809_ALL(*pPort, pData, pEnd); } - } - sei(); -} -else if(FastSPI_LED.m_eChip == CFastSPI_LED::SPI_LPD8806) -{ - cli(); - register byte *p = m_pData; - register byte *e = m_pDataEnd; - - // The LPD8806 requires the high bit to be set - while(p != e) { - SPI_B; SPI_A( *p++ >> 1 | 0x80); - SPI_B; SPI_A( *p++ >> 1 | 0x80); - SPI_B; SPI_A( *p++ >> 1 | 0x80); - } - - // Latch out our 0's to set the data stream - int n = (m_nLeds + 191 )/ 192; - while(n--) { - SPI_B; SPI_A(0); - SPI_B; SPI_A(0); - SPI_B; SPI_A(0); - } - m_nDirty=0; - sei(); -} -} - -void CFastSPI_LED::setDataRate(int datarate) { - m_nDataRate = datarate; -} - -void CFastSPI_LED::setPinCount(int nPins) { - m_nPins = nPins; - m_pPins = (unsigned int*)malloc(sizeof(unsigned int) * nPins); - m_pPinLengths = (unsigned int*)malloc(sizeof(unsigned int) * nPins); - m_pPorts = (uint8_t**)malloc(sizeof(uint8_t*) * nPins); - for(int i = 0; i < nPins; i++) { - m_pPins[i] = m_pPinLengths[i] = 0; - m_pPorts[i] = NULL; - } -} - -void CFastSPI_LED::setPin(int iPins, int nPin, int nLength) { - m_pPins[iPins] = nPin; - m_pPinLengths[iPins] = nLength*3; - m_pPorts[iPins] = (uint8_t*)portOutputRegister(digitalPinToPort(nPin)); -} - -void CFastSPI_LED::setup_hardware_spi(void) { - byte clr; - - if(USE_SPI) { - pinMode(DATA_PIN,OUTPUT); - pinMode(LATCH_PIN,OUTPUT); - pinMode(CLOCK_PIN,OUTPUT); - pinMode(SLAVE_PIN,OUTPUT); - digitalWrite(DATA_PIN,LOW); - digitalWrite(LATCH_PIN,LOW); - digitalWrite(CLOCK_PIN,LOW); - digitalWrite(SLAVE_PIN,LOW); - - // spi prescaler: - // SPI2X SPR1 SPR0 - // 0 0 0 fosc/4 - // 0 0 1 fosc/16 - // 0 1 0 fosc/64 - // 0 1 1 fosc/128 - // 1 0 0 fosc/2 - // 1 0 1 fosc/8 - // 1 1 0 fosc/32 - // 1 1 1 fosc/64 - SPCR |= ( (1<>= 3) < RESOLUTION) clockSelectBits = _BV(CS11); // prescale by /8 - else if((cycles >>= 3) < RESOLUTION) clockSelectBits = _BV(CS11) | _BV(CS10); // prescale by /64 - else if((cycles >>= 2) < RESOLUTION) clockSelectBits = _BV(CS12); // prescale by /256 - else if((cycles >>= 2) < RESOLUTION) clockSelectBits = _BV(CS12) | _BV(CS10); // prescale by /1024 - else cycles = RESOLUTION - 1, clockSelectBits = _BV(CS12) | _BV(CS10); // request was out of bounds, set as maximum - ICR1 = cycles; // ICR1 is TOP in p & f correct pwm mode - TCCR1B &= ~(_BV(CS10) | _BV(CS11) | _BV(CS12)); - // call start explicitly TCCR1B |= clockSelectBits; // reset clock select register - - TIMSK1 = _BV(TOIE1); - sei(); -#endif -} - diff --git a/FastSPI_LED.h b/FastSPI_LED.h deleted file mode 100644 index 7e671b05..00000000 --- a/FastSPI_LED.h +++ /dev/null @@ -1,142 +0,0 @@ -#ifndef __INC_SPIRGB_H -#define __INC_SPIRGB_H -#if defined(ARDUINO) && ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" - #include -#endif -#include "HardwareSerial.h" -#include "string.h" -#include "avr/pgmspace.h" - -extern "C" { - void TIMER1_OVF_vect(void) __attribute__ ((signal,naked,__INTR_ATTRS)); - void SPI_STC_vect(void) __attribute__ ((signal,__INTR_ATTRS)); -}; - -/// A class for controlling a shift-register based LED decoder board such as this one: http://www.usledsupply.com/shop/rgb-32-spi-dmx-decoder.html -/// or using the hl1606 or the lpd6803 controller chips -class CFastSPI_LED { -public: - unsigned char clockSelectBits; - unsigned int m_cpuPercentage; - - // computed time to run 10 cycles - unsigned long m_adjustedUSecTime; - - // timer setup functions - will auto-calibrate (timer1, at least) based on other decisions user has made - void setup_timer1_ovf(); - void setup_hardware_spi(); - - friend void TIMER1_OVF_vect(void); - friend void SPI_STC_vect(void); -public: - enum EChipSet { - SPI_595 = 0x01, - SPI_HL1606 = 0x02, - SPI_LPD6803 = 0x04, - SPI_WS2801 = 0x08, - SPI_TM1809 = 0x10, - SPI_WS2811 = 0x10, - SPI_TM1804 = 0x10, - SPI_LPD8806 = 0x20, - SPI_UCS1903 = 0x40, - SPI_SM16716 = 0x80 - }; - -public: - int m_nLeds; - unsigned char m_nDataRate; - unsigned char m_nDirty; - unsigned char m_eChip; - unsigned long m_nCounter; - unsigned char *m_pData; - unsigned char *m_pDataEnd; - unsigned int *m_pPins; // used by tm1809 - unsigned int *m_pPinLengths; - unsigned int m_nPins; - uint8_t **m_pPorts; - unsigned int m_nDDR; -public: - CFastSPI_LED() {m_nDataRate=0; m_cpuPercentage=50; m_nCounter = 0; m_nDirty=0; m_eChip = SPI_595; m_adjustedUSecTime=0; m_nPins = 0; m_pPins = NULL; m_pPinLengths=NULL;} - - // set the number of rgb leds - void setLeds(int nLeds) { m_nLeds = nLeds * 3; m_nCounter = 0; m_nDirty = 0; m_pData = (unsigned char*)malloc(m_nLeds); memset(m_pData,0,m_nLeds); m_pDataEnd = m_pData + m_nLeds; } - - // set the chipset being used - note: this will reset default values for cpuPercentage and refresh/color level rates - void setChipset(EChipSet); - - // set the desired cpu percentage - changes won't take effect until calling init - void setCPUPercentage(unsigned int perc) { m_cpuPercentage = perc; } - - // set the desired number of color levels (only useful for software pwm chipsets (e.g. 595 or hl1606), chipsets - // like the lpd6803 offload pwm to the chip, meaning the number of color levels is hardwired to some predefined - // number, e.g. 32 for the lpd6803. Note that raising this value will lower the refresh rate in hz that you - // have. Maxes out at 255 - void setColorLevels(unsigned int nLevels) { } - - // set the desired refresh rate in hz (only useful for software pwm chipsets, e.g. 595 or hl1606). - // note that increasining the desired refresh rate may reduce the number of color levels you have available - // to you. Note that your requested refresh rate may not be possible. - void setRefreshRate(unsigned int nDesiredRate) { } - - // initialize the engine - note this will also be re-called if one of the auto-calibration values - // (e.g. percentage, refresh rate, brightness levels) is changed - void init(); - - // start the rgb output - void start(); - - // stop the rgb output - void stop(); - - // call this method whenever you want to output a block of rgb data. It is assumed that - // rgbData is nNumLeds * 3 bytes long. - void setRGBData(unsigned char *rgbData) { memcpy(m_pData,rgbData,m_nLeds); m_nDirty=1;} - - // call this method to get a pointer to the raw rgb data - unsigned char *getRGBData() { return m_pData; } - - // mark the current data as 'dirty' (used by some chipsets) - should be called - // when writing data in manually using getRGBData instead of setRGBData - void setDirty(); - - // 'show' or push the current led data (note, with some chipsets, data shows up in the - // leds as soon as it is written to the array returned by getRGBData. - void show(); - - // get a count of how many output cycles have been performed. Only useful during debugging, this - // will often return 0 - unsigned long getCounter() { return m_nCounter; } - - // clear the output cycle counter. - void clearCounter() { m_nCounter=0; } - - // get the time in µs to run one cycle of output - unsigned long getCycleTime() { return m_adjustedUSecTime / 10; } - - // get the target number of cycles per second - cycleTarget / nLeds - total number of full updates for lights - // available per second. For manually PWM'd chipsets like 595 or hl1606, that base number is also - // desiredHz * colorLevels - higher refresh rate means fewer color levels, which may mean more flickering - unsigned long getCycleTarget() { return (((unsigned long)m_cpuPercentage) * 100000) / m_adjustedUSecTime; } - - // override the spi data rate - the library sets a default data rate for each chipset. You - // can forcibly change the data rate that you want used, with 0 being the fastest and 7 being - // the slowest. Note that you may need to play around with the max cpu percentage a bit if you - // change the data rate. Call this after you have set the chipset to override the chipset's data rate - void setDataRate(int datarate); - - // set the pin used for output. Note, at the moment this only makes sense for the TM1809 based leds, as everything - // else makes use of the spi infrastructure for its work. Setting pins is done in two parts. First, set the number - // of pins (even if only one, for now, we'll do saner defaults later). Then set each individual pin and how many - // leds you want it to take up. Note that this is linear, so if pin 0 has 20 leds, pin 1 will start at the 21st led - void setPinCount(int nPins); - void setPin(int iPins, int nPin, int nLength); - void setPin(int nPin) { setPinCount(1); setPin(0, nPin, m_nLeds / 3); } - int lengthAtPin(int nPin) { return m_pPinLengths[nPin]; } -}; - -extern CFastSPI_LED FastSPI_LED; -#endif - -- cgit v1.2.3 From 6c1d150d5d13234b6b583650af871d63268bc645 Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Mon, 18 Nov 2013 18:24:34 -0500 Subject: Removing some cruft from the first light program --- examples/FirstLight/FirstLight.ino | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/examples/FirstLight/FirstLight.ino b/examples/FirstLight/FirstLight.ino index e86325a5..8f82c370 100644 --- a/examples/FirstLight/FirstLight.ino +++ b/examples/FirstLight/FirstLight.ino @@ -1,5 +1,7 @@ -#define FORCE_SOFTWARE_SPI -#define FORCE_SOFTWARE_PINS +// Use if you want to force the software SPI subsystem to be used for some reason (generally, you don't) +// #define FORCE_SOFTWARE_SPI +// Use if you want to force non-accelerated pin access (hint: you really don't, it breaks lots of things) +// #define FORCE_SOFTWARE_PINS #include "FastLED.h" /////////////////////////////////////////////////////////////////////////////////////////// @@ -29,8 +31,7 @@ void setup() { // FastLED.addLeds(leds, NUM_LEDS); // FastLED.addLeds(leds, NUM_LEDS); // FastLED.addLeds(leds, NUM_LEDS); - // FastLED.addLeds(leds+18, NUM_LEDS/3); - // FastLED.addLeds(leds + 225, NUM_LEDS/4); + // FastLED.addLeds(leds, NUM_LEDS); // FastLED.addLeds(leds, NUM_LEDS); // FastLED.addLeds(leds, NUM_LEDS); // FastLED.addLeds(leds, NUM_LEDS); -- cgit v1.2.3 From 4db5cba81454e2c66aeeab72e29a419ccae47ecb Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Fri, 29 Nov 2013 14:25:12 -0800 Subject: Fixing due build post-mainline merge --- FastLED.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FastLED.cpp b/FastLED.cpp index 3969a712..a7cf3c5f 100644 --- a/FastLED.cpp +++ b/FastLED.cpp @@ -75,7 +75,7 @@ void CFastLED::clear(boolean writeData) { clearData(); } -void CFastSPI_LED2::clearData() { +void CFastLED::clearData() { for(int i = 0; i < m_nControllers; i++) { if(m_Controllers[i].pLedData != NULL) { memset8((void*)m_Controllers[i].pLedData, 0, sizeof(struct CRGB) * m_Controllers[i].nLeds); -- cgit v1.2.3 From 193d0f54dbe62e2d556e60644832a2152499e125 Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Mon, 20 Jan 2014 21:20:04 -0800 Subject: Fixing build --- block_clockless.h | 30 +----------------------------- chipsets.h | 2 ++ clockless.h | 38 +------------------------------------- clockless2.h | 26 +------------------------- delay.h | 4 ++++ led_sysdefs.h | 8 ++++++++ 6 files changed, 17 insertions(+), 91 deletions(-) diff --git a/block_clockless.h b/block_clockless.h index bf1b7cbe..beb742a9 100644 --- a/block_clockless.h +++ b/block_clockless.h @@ -4,35 +4,7 @@ #include "controller.h" #include "lib8tion.h" #include "led_sysdefs.h" - -// Macro to convert from nano-seconds to clocks and clocks to nano-seconds -// #define NS(_NS) (_NS / (1000 / (F_CPU / 1000000L))) -#if F_CPU < 96000000 -#define NS(_NS) ( (_NS * (F_CPU / 1000000L))) / 1000 -#define CLKS_TO_MICROS(_CLKS) _CLKS / (F_CPU / 1000000L) -#else -#define NS(_NS) ( (_NS * (F_CPU / 2000000L))) / 1000 -#define CLKS_TO_MICROS(_CLKS) _CLKS / (F_CPU / 2000000L) -#endif - -// Macro for making sure there's enough time available -#define NO_TIME(A, B, C) (NS(A) < 3 || NS(B) < 3 || NS(C) < 6) - -#if defined(__MK20DX128__) - extern volatile uint32_t systick_millis_count; -# define MS_COUNTER systick_millis_count -#elif defined(__SAM3X8E__) - extern volatile uint32_t fuckit; -# define MS_COUNTER fuckit -#else -# if defined(CORE_TEENSY) - 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 +#include "delay.h" ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // diff --git a/chipsets.h b/chipsets.h index 00cedf0d..f2398de5 100644 --- a/chipsets.h +++ b/chipsets.h @@ -370,4 +370,6 @@ class TM1829Controller1600Khz : public ClocklessController() -# warning "No hardware multiply, inline brightness scaling disabled" -#else -# define INLINE_SCALE(B, SCALE) B = scale8_LEAVING_R1_DIRTY(B, SCALE) -#endif +#include "delay.h" ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // diff --git a/clockless2.h b/clockless2.h index e6823447..ba39b262 100644 --- a/clockless2.h +++ b/clockless2.h @@ -4,32 +4,8 @@ #include "controller.h" #include "lib8tion.h" #include "led_sysdefs.h" +#include "delay.h" -// Macro to convert from nano-seconds to clocks and clocks to nano-seconds -// #define NS(_NS) (_NS / (1000 / (F_CPU / 1000000L))) -#if F_CPU < 96000000 -#define NS(_NS) ( (_NS * (F_CPU / 1000000L))) / 1000 -#define CLKS_TO_MICROS(_CLKS) _CLKS / (F_CPU / 1000000L) -#else -#define NS(_NS) ( (_NS * (F_CPU / 2000000L))) / 1000 -#define CLKS_TO_MICROS(_CLKS) _CLKS / (F_CPU / 2000000L) -#endif - -// Macro for making sure there's enough time available -#define NO_TIME(A, B, C) (NS(A) < 3 || NS(B) < 3 || NS(C) < 6) - -#if defined(__MK20DX128__) - extern volatile uint32_t systick_millis_count; -# define MS_COUNTER systick_millis_count -#else -# if defined(CORE_TEENSY) - 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/delay.h b/delay.h index 1f5ffa77..6e0051f5 100644 --- a/delay.h +++ b/delay.h @@ -94,9 +94,13 @@ template<> __attribute__((always_inline)) inline void delaycycles<5>() {NOP2;NOP // Macro for making sure there's enough time available #define NO_TIME(A, B, C) (NS(A) < 3 || NS(B) < 3 || NS(C) < 6) + #if defined(__MK20DX128__) extern volatile uint32_t systick_millis_count; # define MS_COUNTER systick_millis_count +#elif defined(__SAM3X8E__) + extern volatile uint32_t fuckit; +# define MS_COUNTER fuckit #else # if defined(CORE_TEENSY) extern volatile unsigned long timer0_millis_count; diff --git a/led_sysdefs.h b/led_sysdefs.h index b2118a09..4ef4b6bb 100644 --- a/led_sysdefs.h +++ b/led_sysdefs.h @@ -27,4 +27,12 @@ typedef volatile uint8_t RwReg; /**< Read-Write 8-bit register (volatile u // Arduino.h needed for convinience functions digitalPinToPort/BitMask/portOutputRegister and the pinMode methods. #include +// Scaling macro choice +#if defined(LIB8_ATTINY) +# define INLINE_SCALE(B, SCALE) delaycycles<3>() +# warning "No hardware multiply, inline brightness scaling disabled" +#else +# define INLINE_SCALE(B, SCALE) B = scale8_LEAVING_R1_DIRTY(B, SCALE) +#endif + #endif \ No newline at end of file -- cgit v1.2.3 From 878a6a96afec3803f327c7a3c31183f7283b23bf Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Mon, 20 Jan 2014 21:49:58 -0800 Subject: Preliminary teensy 3.1 support (aka, it compiles) --- clockless.h | 2 +- clockless2.h | 2 +- delay.h | 2 +- fastpin.h | 2 +- fastspi.h | 2 +- fastspi_arm.h | 2 +- fastspi_avr.h | 4 ---- led_sysdefs.h | 5 ++++- lib8tion.h | 2 +- 9 files changed, 11 insertions(+), 12 deletions(-) diff --git a/clockless.h b/clockless.h index 854f21be..ae6e8917 100644 --- a/clockless.h +++ b/clockless.h @@ -181,7 +181,7 @@ public: } }; -#elif defined(__MK20DX128__) +#elif defined(FASTLED_TEENSY3) template class ClocklessController : public CLEDController { typedef typename FastPin::port_ptr_t data_ptr_t; diff --git a/clockless2.h b/clockless2.h index ba39b262..b137f6a8 100644 --- a/clockless2.h +++ b/clockless2.h @@ -104,7 +104,7 @@ public: nLeds *= (3 + SKIP); register uint8_t *end = data + nLeds; -#if defined(__MK20DX128__) +#if defined(FASTLED_TEENSY3) register uint32_t b; register uint32_t c; if(ADVANCE) { diff --git a/delay.h b/delay.h index 6e0051f5..7c7a50ea 100644 --- a/delay.h +++ b/delay.h @@ -95,7 +95,7 @@ template<> __attribute__((always_inline)) inline void delaycycles<5>() {NOP2;NOP #define NO_TIME(A, B, C) (NS(A) < 3 || NS(B) < 3 || NS(C) < 6) -#if defined(__MK20DX128__) +#if defined(FASTLED_TEENSY3) extern volatile uint32_t systick_millis_count; # define MS_COUNTER systick_millis_count #elif defined(__SAM3X8E__) diff --git a/fastpin.h b/fastpin.h index 1fc1f249..7a943ae4 100644 --- a/fastpin.h +++ b/fastpin.h @@ -453,7 +453,7 @@ _DEFPIN_AVR(20, 32, F); _DEFPIN_AVR(21, 16, F); _DEFPIN_AVR(22, 2, F); _DEFPIN_A #define SPI_CLOCK 15 #define AVR_HARDWARE_SPI -#elif defined(__MK20DX128__) && defined(CORE_TEENSY) +#elif defined(FASTLED_TEENSY3) && defined(CORE_TEENSY) _IO32(A); _IO32(B); _IO32(C); _IO32(D); _IO32(E); diff --git a/fastspi.h b/fastspi.h index 00747137..5a0e2974 100644 --- a/fastspi.h +++ b/fastspi.h @@ -62,7 +62,7 @@ class SoftwareSPIOutput : public AVRSoftwareSPIOutput<_DATA_PIN, _CLOCK_PIN, _SP #ifndef FORCE_SOFTWARE_SPI #if defined(SPI_DATA) && defined(SPI_CLOCK) -#if defined(__MK20DX128__) && defined(CORE_TEENSY) +#if defined(FASTLED_TEENSY3) && defined(CORE_TEENSY) template class SPIOutput : public ARMHardwareSPIOutput {}; diff --git a/fastspi_arm.h b/fastspi_arm.h index ace799c5..8db42ac3 100644 --- a/fastspi_arm.h +++ b/fastspi_arm.h @@ -2,7 +2,7 @@ #define __INC_FASTSPI_ARM_H -#if defined(__MK20DX128__) && defined(CORE_TEENSY) +#if defined(FASTLED_TEENSY3) && defined(CORE_TEENSY) #ifndef SPI_PUSHR_CONT #define SPI_PUSHR_CONT SPI0_PUSHR_CONT diff --git a/fastspi_avr.h b/fastspi_avr.h index af116cab..84b1d5f6 100644 --- a/fastspi_avr.h +++ b/fastspi_avr.h @@ -83,12 +83,8 @@ public: uint8_t *end = data + len; select(); while(data != end) { -#if defined(__MK20DX128__) - writeByte(D::adjust(*data++)); -#else // 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>(); -#endif } D::postBlock(len); release(); diff --git a/led_sysdefs.h b/led_sysdefs.h index 4ef4b6bb..adbd10b6 100644 --- a/led_sysdefs.h +++ b/led_sysdefs.h @@ -18,7 +18,10 @@ typedef volatile uint8_t RwReg; /**< Read-Write 8-bit register (volatile u #endif -#if defined(__MK20DX128__) || defined(__SAM3X8E__) +#if defined(__MK20DX128__) || defined(__MK20DX256__) +#define FASTLED_TEENSY3 +#define FASTLED_ARM +#elif defined(__SAM3X8E__) #define FASTLED_ARM #else #define FASTLED_AVR diff --git a/lib8tion.h b/lib8tion.h index 65aa6fcb..280def94 100644 --- a/lib8tion.h +++ b/lib8tion.h @@ -134,7 +134,7 @@ Lib8tion is pronounced like 'libation': lie-BAY-shun #if defined(__arm__) -#if defined(__MK20DX128__) +#if defined(FASTLED_TEENSY3) // Can use Cortex M4 DSP instructions #define QADD8_C 0 #define QADD7_C 0 -- cgit v1.2.3 From 064e7002382158ebc62839e67037daecba9d3cf7 Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Mon, 20 Jan 2014 22:04:08 -0800 Subject: Adding preview changes notes --- preview_changes.txt | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 preview_changes.txt diff --git a/preview_changes.txt b/preview_changes.txt new file mode 100644 index 00000000..60562fef --- /dev/null +++ b/preview_changes.txt @@ -0,0 +1,8 @@ +* ALL UNTESTED, USE AT YOUR OWN RISK! +* Preliminary teensy 3.1 support +* Preliminary due support (no hardware SPI, yet) +* Preliminary P9813 (aka Cool Neon Total Control Lighting support) +* Preliminary 2-way ws2812 support +* Preliminary n-way clockless support on due +* Preliminary TM1829 support (broken, don't use!) +* Random code changes and cleanups -- cgit v1.2.3 From b6697b8fff3dcd3d0e7f639a6f6344aa75284db7 Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Tue, 21 Jan 2014 09:41:25 -0800 Subject: Fixing build error for avr and p9813 --- fastspi_avr.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fastspi_avr.h b/fastspi_avr.h index 84b1d5f6..95e1c977 100644 --- a/fastspi_avr.h +++ b/fastspi_avr.h @@ -208,6 +208,8 @@ public: static void wait() __attribute__((always_inline)) { if(shouldWait()) { while(!(SPSR & (1<>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); } -- cgit v1.2.3 From 954d1df0defd533df4573a107d603c60dda04a31 Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Tue, 21 Jan 2014 09:47:45 -0800 Subject: Tweak/fix P9813 code according to data sheet --- chipsets.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chipsets.h b/chipsets.h index f5ac7865..08c32b2b 100644 --- a/chipsets.h +++ b/chipsets.h @@ -159,7 +159,7 @@ class P9813Controller : public CLEDController { register uint8_t g = scale8(data[RGB_BYTE1(RGB_ORDER)], scale); register uint8_t b = scale8(data[RGB_BYTE2(RGB_ORDER)], scale); - register uint8_t top = 0xC0 | (~b & 0xC0) >> 2 | (~g & 0xC0) >> 4 | (~r & 0xC0); + register uint8_t top = 0xC0 | ((~b & 0xC0) >> 2) | ((~g & 0xC0) >> 4) | ((~r & 0xC0) >> 6); mSPI.writeByte(top); mSPI.writeByte(b); mSPI.writeByte(g); mSPI.writeByte(r); } -- cgit v1.2.3 From ceb238fa0d0420eb974369838461a95669c5e344 Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Tue, 21 Jan 2014 09:50:27 -0800 Subject: Tweak/fix P9813 timing according to data sheet --- chipsets.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chipsets.h b/chipsets.h index 08c32b2b..624c075a 100644 --- a/chipsets.h +++ b/chipsets.h @@ -146,7 +146,7 @@ public: // ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -template +template class P9813Controller : public CLEDController { typedef SPIOutput SPI; SPI mSPI; -- cgit v1.2.3 From e269d3cf04a87a1258de3be3e822ad4c16408350 Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Sun, 26 Jan 2014 16:47:23 -0800 Subject: Resolve #16 - adding support for the UCS1903B everywhere. --- FastLED.h | 3 +++ chipsets.h | 19 ++++++++++++++++--- examples/Blink/Blink.ino | 5 +++-- examples/Fast2Dev/Fast2Dev.ino | 4 +++- examples/FirstLight/FirstLight.ino | 6 ++++-- examples/RGBCalibrate/RGBCalibrate.ino | 1 + 6 files changed, 30 insertions(+), 8 deletions(-) diff --git a/FastLED.h b/FastLED.h index 19df7ace..b3ef74d3 100644 --- a/FastLED.h +++ b/FastLED.h @@ -29,6 +29,7 @@ enum EClocklessChipsets { WS2812, WS2812B, UCS1903, + UCS1903B, WS2811_400, NEOPIXEL, TM1829 @@ -109,6 +110,7 @@ public: case TM1809: { static TM1809Controller800Khz controller; return addLeds(&controller, data, nLedsOrOffset, nLedsIfOffset); } case TM1803: { static TM1803Controller400Khz controller; return addLeds(&controller, data, nLedsOrOffset, nLedsIfOffset); } case UCS1903: { static UCS1903Controller400Khz controller; return addLeds(&controller, data, nLedsOrOffset, nLedsIfOffset); } + case UCS1903B: { static UCS1903BController800Khz controller; return addLeds(&controller, data, nLedsOrOffset, nLedsIfOffset); } case WS2812: case WS2812B: case WS2811: { static WS2811Controller800Khz controller; return addLeds(&controller, data, nLedsOrOffset, nLedsIfOffset); } @@ -129,6 +131,7 @@ public: case TM1809: { static TM1809Controller800Khz controller; return addLeds(&controller, data, nLedsOrOffset, nLedsIfOffset); } case TM1803: { static TM1803Controller400Khz controller; return addLeds(&controller, data, nLedsOrOffset, nLedsIfOffset); } case UCS1903: { static UCS1903Controller400Khz controller; return addLeds(&controller, data, nLedsOrOffset, nLedsIfOffset); } + case UCS1903B: { static UCS1903BController800Khz controller; return addLeds(&controller, data, nLedsOrOffset, nLedsIfOffset); } case WS2812: case WS2812B: case NEOPIXEL: diff --git a/chipsets.h b/chipsets.h index 624c075a..ef71a2da 100644 --- a/chipsets.h +++ b/chipsets.h @@ -290,7 +290,7 @@ public: // ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -#if defined(LIB8_ATTINY) && (F_CPU == 8000000) +#if defined(LIB8_ATTINY) && (F_CPU == 8000000) // 125ns/clock // WS2811@8Mhz 2 clocks, 5 clocks, 3 clocks template class WS2811Controller800Khz : public ClocklessController_Trinket {}; @@ -301,13 +301,16 @@ class WS2811Controller400Khz : public ClocklessController_Trinket class UCS1903Controller400Khz : public ClocklessController_Trinket {}; +template +class UCS1903BController800Khz : public ClocklessController_Trinket {}; + template class TM1809Controller800Khz : public ClocklessController {}; template class TM1803Controller400Khz : public ClocklessController {}; -#elif defined(LIB8_ATTINY) && (F_CPU == 16000000) +#elif defined(LIB8_ATTINY) && (F_CPU == 16000000) // 62.5ns/clock // WS2811@16Mhz 4 clocks, 10 clocks, 6 clocks template @@ -319,6 +322,9 @@ class WS2811Controller400Khz : public ClocklessController_Trinket class UCS1903Controller400Khz : public ClocklessController_Trinket {}; +template +class UCS1903BController800Khz : public ClocklessController_Trinket {}; + template class TM1809Controller800Khz : public ClocklessController {}; @@ -330,7 +336,14 @@ class TM1803Controller400Khz : public ClocklessController class UCS1903Controller400Khz : public ClocklessController {}; #if NO_TIME(500, 1500, 500) -#warning "Not enough clock cycles available for the UCS103" +#warning "Not enough clock cycles available for the UCS103@400khz" +#endif + +// UCS1903B - 400ns, 450ns, 450ns +template +class UCS1903BController800Khz : public ClocklessController {}; +#if NO_TIME(400, 450, 450) +#warning "Not enough clock cycles available for the UCS103B@800khz" #endif // TM1809 - 350ns, 350ns, 550ns diff --git a/examples/Blink/Blink.ino b/examples/Blink/Blink.ino index bc5c84d2..1d7f1fa7 100644 --- a/examples/Blink/Blink.ino +++ b/examples/Blink/Blink.ino @@ -20,9 +20,10 @@ void setup() { // FastLED.addLeds(leds, NUM_LEDS); // FastLED.addLeds(leds, NUM_LEDS); // FastLED.addLeds(leds, NUM_LEDS); - FastLED.addLeds(leds, NUM_LEDS); + // FastLED.addLeds(leds, NUM_LEDS); // FastLED.addLeds(leds, NUM_LEDS); - + FastLED.addLeds(leds, NUM_LEDS); + // FastLED.addLeds(leds, NUM_LEDS); // FastLED.addLeds(leds, NUM_LEDS); // FastLED.addLeds(leds, NUM_LEDS); diff --git a/examples/Fast2Dev/Fast2Dev.ino b/examples/Fast2Dev/Fast2Dev.ino index cacf1506..3ae799c0 100644 --- a/examples/Fast2Dev/Fast2Dev.ino +++ b/examples/Fast2Dev/Fast2Dev.ino @@ -28,12 +28,14 @@ void setup() { // setting brightness to 25% brightness LEDS.setBrightness(64); - LEDS.addLeds(leds, NUM_LEDS); + // LEDS.addLeds(leds, NUM_LEDS); // LEDS.addLeds(leds, NUM_LEDS); // LEDS.addLeds(leds, NUM_LEDS); // LEDS.addLeds(leds, NUM_LEDS); // LEDS.addLeds(leds, NUM_LEDS); + FastLED.addLeds(leds, NUM_LEDS); + // LEDS.addLeds(leds, NUM_LEDS); // LEDS.addLeds(leds, NUM_LEDS); // LEDS.addLeds(leds, NUM_LEDS); diff --git a/examples/FirstLight/FirstLight.ino b/examples/FirstLight/FirstLight.ino index dff123b9..1572dad6 100644 --- a/examples/FirstLight/FirstLight.ino +++ b/examples/FirstLight/FirstLight.ino @@ -34,15 +34,17 @@ void setup() { // FastLED.addLeds(leds, NUM_LEDS); // FastLED.addLeds(leds, NUM_LEDS); // FastLED.addLeds(leds, NUM_LEDS); - FastLED.addLeds(leds, NUM_LEDS); + // FastLED.addLeds(leds, NUM_LEDS); // FastLED.addLeds(leds, NUM_LEDS); // FastLED.addLeds(leds, NUM_LEDS); // FastLED.addLeds(leds, NUM_LEDS); + FastLED.addLeds(leds, NUM_LEDS); // FastLED.addLeds(leds, NUM_LEDS); // FastLED.addLeds(leds, NUM_LEDS); // FastLED.addLeds(leds, NUM_LEDS); - + // FastLED.addLeds(leds, NUM_LEDS); + // FastLED.addLeds(leds, NUM_LEDS); // FastLED.addLeds(leds, NUM_LEDS); // FastLED.addLeds(leds, NUM_LEDS); diff --git a/examples/RGBCalibrate/RGBCalibrate.ino b/examples/RGBCalibrate/RGBCalibrate.ino index 55661052..7be08c7c 100644 --- a/examples/RGBCalibrate/RGBCalibrate.ino +++ b/examples/RGBCalibrate/RGBCalibrate.ino @@ -44,6 +44,7 @@ void setup() { // FastLED.addLeds(leds, NUM_LEDS); // FastLED.addLeds(leds, NUM_LEDS); // FastLED.addLeds(leds, NUM_LEDS); + // FastLED.addLeds(leds, NUM_LEDS); // FastLED.addLeds(leds, NUM_LEDS); // FastLED.addLeds(leds, NUM_LEDS); -- cgit v1.2.3 From 98b6ac00509f2c1756dd0e5ce8d5a809dee9a658 Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Sun, 26 Jan 2014 17:13:58 -0800 Subject: splitting out clockless code into all its own header files --- FastLED.h | 3 - block_clockless.h | 4 - clockless.h | 503 +--------------------------------------------------- clockless2.h | 6 +- clockless_arm_k20.h | 139 +++++++++++++++ clockless_arm_sam.h | 213 ++++++++++++++++++++++ clockless_avr.h | 173 ++++++++++++++++++ clockless_trinket.h | 3 + 8 files changed, 536 insertions(+), 508 deletions(-) create mode 100644 clockless_arm_k20.h create mode 100644 clockless_arm_sam.h create mode 100644 clockless_avr.h diff --git a/FastLED.h b/FastLED.h index b3ef74d3..89e94d92 100644 --- a/FastLED.h +++ b/FastLED.h @@ -5,9 +5,6 @@ #include "fastpin.h" #include "fastspi.h" #include "clockless.h" -#include "block_clockless.h" -#include "clockless2.h" -#include "clockless_trinket.h" #include "lib8tion.h" #include "hsv2rgb.h" #include "chipsets.h" diff --git a/block_clockless.h b/block_clockless.h index beb742a9..350e0d65 100644 --- a/block_clockless.h +++ b/block_clockless.h @@ -14,10 +14,6 @@ // ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Convinience macros to wrap around the toggling of hi vs. lo -#define SET_LO FLIP ? FastPin::fastset(port, hi) : FastPin::fastset(port, lo); -#define SET_HI FLIP ? FastPin::fastset(port, lo) : FastPin::fastset(port, hi); - #define PORT_MASK 0x77EFF3FE #define SKIPLIST ~PORT_MASK diff --git a/clockless.h b/clockless.h index ae6e8917..c7d3b49f 100644 --- a/clockless.h +++ b/clockless.h @@ -18,503 +18,10 @@ #define SET_LO FLIP ? FastPin::fastset(port, hi) : FastPin::fastset(port, lo); #define SET_HI FLIP ? FastPin::fastset(port, lo) : FastPin::fastset(port, hi); -#ifdef FASTLED_AVR -template -class ClocklessController : public CLEDController { - typedef typename FastPin::port_ptr_t data_ptr_t; - typedef typename FastPin::port_t data_t; - - data_t mPinMask; - data_ptr_t mPort; - CMinWait mWait; -public: - virtual void init() { - FastPin::setOutput(); - mPinMask = FastPin::mask(); - mPort = FastPin::port(); - } - - template inline static void bitSetLast(register data_ptr_t port, register data_t hi, register data_t lo, register uint8_t b) { - // First cycle - SET_HI; // 1 clock cycle if using out, 2 otherwise - delaycycles(); // 1st cycle length minus 1 clock for out, 1 clock for sbrs - __asm__ __volatile__ ("sbrs %0, %1" :: "r" (b), "M" (N) :); // 1 clock for check (+1 if skipping, next op is also 1 clock) - - // Second cycle - SET_LO; // 1/2 clock cycle if using out - delaycycles(); // 2nd cycle length minus 1/2 clock for out - - // Third cycle - SET_LO; // 1/2 clock cycle if using out - delaycycles(); // 3rd cycle length minus 7 clocks for out, loop compare, jump, next uint8_t load - } - - virtual void clearLeds(int nLeds) { - showColor(CRGB(0, 0, 0), nLeds, 0); - } - - // set all the leds on the controller to a given color - virtual void showColor(const struct CRGB & data, int nLeds, uint8_t scale = 255) { - mWait.wait(); - cli(); - - showRGBInternal<0, false>(nLeds, scale, (const byte*)&data); - - // Adjust the timer - long microsTaken = CLKS_TO_MICROS((long)nLeds * 8 * (T1 + T2 + T3)); - MS_COUNTER += (microsTaken / 1000); - sei(); - mWait.mark(); - } - - virtual void show(const struct CRGB *rgbdata, int nLeds, uint8_t scale = 255) { - mWait.wait(); - cli(); - - showRGBInternal<0, true>(nLeds, scale, (const byte*)rgbdata); - - // Adjust the timer - long microsTaken = CLKS_TO_MICROS((long)nLeds * 8 * (T1 + T2 + T3)); - MS_COUNTER += (microsTaken / 1000); - sei(); - mWait.mark(); - } - -#ifdef SUPPORT_ARGB - virtual void show(const struct CARGB *rgbdata, int nLeds, uint8_t scale = 255) { - mWait.wait(); - cli(); - - showRGBInternal<1, true>((long)nLeds, scale, (const byte*)rgbdata); - - // Adjust the timer - long microsTaken = CLKS_TO_MICROS((long)nLeds * 8 * (T1 + T2 + T3)); - MS_COUNTER += (microsTaken / 1000); - sei(); - mWait.mark(); - } -#endif - - // 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. - template static void showRGBInternal(register int nLeds, register uint8_t scale, register const byte *rgbdata) { - register byte *data = (byte*)rgbdata; - register data_ptr_t port = FastPin::port(); - nLeds *= (3 + SKIP); - register uint8_t *end = data + nLeds; - register data_t hi = FastPin::hival(); - register data_t lo = FastPin::loval();; - *port = lo; - - register uint8_t b; - - if(ADVANCE) { - b = data[SKIP + RGB_BYTE0(RGB_ORDER)]; - } else { - b = rgbdata[SKIP + RGB_BYTE0(RGB_ORDER)]; - } - b = scale8_LEAVING_R1_DIRTY(b, scale); - - register uint8_t c; - register uint8_t d; - while(data < end) { - for(register byte x=5; x; x--) { - bitSetLast<7, 4>(port, hi, lo, b); - b <<= 1; - } - delaycycles<1>(); - // Leave an extra 2 clocks for the next byte load - bitSetLast<7, 1>(port, hi, lo, b); - delaycycles<1>(); - - // Leave an extra 4 clocks for the scale - bitSetLast<6, 6>(port, hi, lo, b); - if(ADVANCE) { - c = data[SKIP + RGB_BYTE1(RGB_ORDER)]; - } else { - c = rgbdata[SKIP + RGB_BYTE1(RGB_ORDER)]; - delaycycles<1>(); - } - INLINE_SCALE(c, scale); - bitSetLast<5, 1>(port, hi, lo, b); - - for(register byte x=5; x; x--) { - bitSetLast<7, 4>(port, hi, lo, c); - c <<= 1; - } - delaycycles<1>(); - // Leave an extra 2 clocks for the next byte load - bitSetLast<7, 1>(port, hi, lo, c); - delaycycles<1>(); - - // Leave an extra 4 clocks for the scale - bitSetLast<6, 6>(port, hi, lo, c); - if(ADVANCE) { - d = data[SKIP + RGB_BYTE2(RGB_ORDER)]; - } else { - d = rgbdata[SKIP + RGB_BYTE2(RGB_ORDER)]; - delaycycles<1>(); - } - INLINE_SCALE(d, scale); - bitSetLast<5, 1>(port, hi, lo, c); - - for(register byte x=5; x; x--) { - bitSetLast<7, 4>(port, hi, lo, d); - d <<= 1; - } - delaycycles<1>(); - // Leave an extra 2 clocks for the next byte load - bitSetLast<7, 2>(port, hi, lo, d); - data += (SKIP + 3); - // Leave an extra 4 clocks for the scale - bitSetLast<6, 6>(port, hi, lo, d); - if(ADVANCE) { - b = data[SKIP + RGB_BYTE0(RGB_ORDER)]; - } else { - b = rgbdata[SKIP + RGB_BYTE0(RGB_ORDER)]; - delaycycles<1>(); - } - INLINE_SCALE(b, scale); - bitSetLast<5, 6>(port, hi, lo, d); - } - cleanup_R1(); - } -}; - -#elif defined(FASTLED_TEENSY3) -template -class ClocklessController : public CLEDController { - typedef typename FastPin::port_ptr_t data_ptr_t; - typedef typename FastPin::port_t data_t; - - data_t mPinMask; - data_ptr_t mPort; - CMinWait mWait; -public: - virtual void init() { - FastPin::setOutput(); - mPinMask = FastPin::mask(); - mPort = FastPin::port(); - } - - virtual void clearLeds(int nLeds) { - showColor(CRGB(0, 0, 0), nLeds, 0); - } - - // set all the leds on the controller to a given color - virtual void showColor(const struct CRGB & data, int nLeds, uint8_t scale = 255) { - mWait.wait(); - cli(); - - showRGBInternal<0, false>(nLeds, scale, (const byte*)&data); - - // Adjust the timer - long microsTaken = CLKS_TO_MICROS((long)nLeds * 8 * (T1 + T2 + T3)); - MS_COUNTER += (microsTaken / 1000); - sei(); - mWait.mark(); - } - - virtual void show(const struct CRGB *rgbdata, int nLeds, uint8_t scale = 255) { - mWait.wait(); - cli(); - - showRGBInternal<0, true>(nLeds, scale, (const byte*)rgbdata); - - // Adjust the timer - long microsTaken = CLKS_TO_MICROS((long)nLeds * 8 * (T1 + T2 + T3)); - MS_COUNTER += (microsTaken / 1000); - sei(); - mWait.mark(); - } - -#ifdef SUPPORT_ARGB - virtual void show(const struct CARGB *rgbdata, int nLeds, uint8_t scale = 255) { - mWait.wait(); - cli(); - - showRGBInternal<1, true>(nLeds, scale, (const byte*)rgbdata); - - // Adjust the timer - long microsTaken = CLKS_TO_MICROS((long)nLeds * 8 * (T1 + T2 + T3)); - MS_COUNTER += (microsTaken / 1000); - sei(); - mWait.mark(); - } -#endif - - inline static void write8Bits(register data_ptr_t port, register data_t hi, register data_t lo, register uint32_t & b) __attribute__ ((always_inline)) { - // TODO: hand rig asm version of this method. The timings are based on adjusting/studying GCC compiler ouptut. This - // will bite me in the ass at some point, I know it. - for(register uint32_t i = 7; i > 0; i--) { - FastPin::fastset(port, hi); - delaycycles(); // 5 cycles - 2 store, 1 and, 1 test, 1 if - if(b & 0x80) { FastPin::fastset(port, hi); } else { FastPin::fastset(port, lo); } - b <<= 1; - delaycycles(); // 2 cycles, 1 store/skip, 1 shift - FastPin::fastset(port, lo); - delaycycles(); // 3 cycles, 2 store, 1 sub, 1 branch backwards - } - // delay an extra cycle because falling out of the loop takes on less cycle than looping around - delaycycles<1>(); - - FastPin::fastset(port, hi); - delaycycles(); - if(b & 0x80) { FastPin::fastset(port, hi); } else { FastPin::fastset(port, lo); } - delaycycles(); // 4 cycles, 2 store, store/skip - FastPin::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. - template static void showRGBInternal(register int nLeds, register uint8_t scale, register const byte *rgbdata) { - register byte *data = (byte*)rgbdata; - register data_t mask = FastPin::mask(); - register data_ptr_t port = FastPin::port(); - nLeds *= (3 + SKIP); - register uint8_t *end = data + nLeds; - register data_t hi = *port | mask; - register data_t lo = *port & ~mask; - *port = lo; - - register uint32_t b; - b = ((ADVANCE)?data:rgbdata)[SKIP + RGB_BYTE0(RGB_ORDER)]; - b = scale8(b, scale); - while(data < end) { - // Write first byte, read next byte - write8Bits(port, hi, lo, b); - - b = ((ADVANCE)?data:rgbdata)[SKIP + RGB_BYTE1(RGB_ORDER)]; - INLINE_SCALE(b, scale); - delaycycles(); // 1 store, 2 load, 1 mul, 1 shift, - - // Write second byte - write8Bits(port, hi, lo, b); - - b = ((ADVANCE)?data:rgbdata)[SKIP + RGB_BYTE2(RGB_ORDER)]; - INLINE_SCALE(b, scale); - - data += 3 + SKIP; - if((RGB_ORDER & 0070) == 0) { - delaycycles(); // 1 store, 2 load, 1 mul, 1 shift, 1 adds if BRG or GRB - } else { - delaycycles(); // 1 store, 2 load, 1 mul, 1 shift, - } - - // Write third byte - write8Bits(port, hi, lo, b); - - b = ((ADVANCE)?data:rgbdata)[SKIP + RGB_BYTE0(RGB_ORDER)]; - INLINE_SCALE(b, scale); - - delaycycles(); // 1 store, 2 load (with increment), 1 mul, 1 shift, 1 cmp, 1 branch backwards, 1 movim - }; - } -}; -#elif defined(__SAM3X8E__) - -template -class ClocklessController : public CLEDController { - typedef typename FastPinBB::port_ptr_t data_ptr_t; - typedef typename FastPinBB::port_t data_t; - - data_t mPinMask; - data_ptr_t mPort; - CMinWait mWait; -public: - virtual void init() { - FastPinBB::setOutput(); - mPinMask = FastPinBB::mask(); - mPort = FastPinBB::port(); - } - - virtual void clearLeds(int nLeds) { - showColor(CRGB(0, 0, 0), nLeds, 0); - } - - // set all the leds on the controller to a given color - virtual void showColor(const struct CRGB & data, int nLeds, uint8_t scale = 255) { - mWait.wait(); - cli(); - SysClockSaver savedClock(T1 + T2 + T3); - - showRGBInternal<0, false>(nLeds, scale, (const byte*)&data); - - // Adjust the timer - long microsTaken = CLKS_TO_MICROS((long)nLeds * 8 * (T1 + T2 + T3)); - MS_COUNTER += (microsTaken / 1000); - savedClock.restore(); - sei(); - mWait.mark(); - } - - virtual void show(const struct CRGB *rgbdata, int nLeds, uint8_t scale = 255) { - mWait.wait(); - cli(); - SysClockSaver savedClock(T1 + T2 + T3); - - // FastPinBB::hi(); delay(1); FastPinBB::lo(); - showRGBInternal<0, true>(nLeds, scale, (const byte*)rgbdata); - - // Adjust the timer - long microsTaken = CLKS_TO_MICROS((long)nLeds * 8 * (T1 + T2 + T3)); - MS_COUNTER += (microsTaken / 1000); - savedClock.restore(); - sei(); - mWait.mark(); - } - -#ifdef SUPPORT_ARGB - virtual void show(const struct CARGB *rgbdata, int nLeds, uint8_t scale = 255) { - mWait.wait(); - cli(); - SysClockSaver savedClock(T1 + T2 + T3); - - showRGBInternal<1, true>(nLeds, scale, (const byte*)rgbdata); - - // Adjust the timer - long microsTaken = CLKS_TO_MICROS((long)nLeds * 8 * (T1 + T2 + T3)); - MS_COUNTER += (microsTaken / 1000); - savedClock.restore(); - sei(); - mWait.mark(); - } -#endif - -// I hate using defines for these, should find a better representation at some point -#define _CTRL CTPTR[0] -#define _LOAD CTPTR[1] -#define _VAL CTPTR[2] - - __attribute__((always_inline)) static inline void wait_loop_start(register volatile uint32_t *CTPTR) { - __asm__ __volatile__ ( - "L_%=: ldr.w r8, [%0]\n" - " tst.w r8, #65536\n" - " beq.n L_%=\n" - : /* no outputs */ - : "r" (CTPTR) - : "r8" - ); - } - - template __attribute__((always_inline)) static inline void wait_loop_mark(register volatile uint32_t *CTPTR) { - __asm__ __volatile__ ( - "L_%=: ldr.w r8, [%0, #8]\n" - " cmp.w r8, %1\n" - " bhi.n L_%=\n" - : /* no outputs */ - : "r" (CTPTR), "I" (MARK) - : "r8" - ); - } - - __attribute__((always_inline)) static inline void mark_port(register data_ptr_t port, register int val) { - __asm__ __volatile__ ( - " str.w %0, [%1]\n" - : /* no outputs */ - : "r" (val), "r" (port) - ); - } -#define AT_BIT_START(X) wait_loop_start(CTPTR); X; -#define AT_MARK(X) wait_loop_mark(CTPTR); { X; } -#define AT_END(X) wait_loop_mark(CTPTR); { X; } - -// #define AT_BIT_START(X) while(!(_CTRL & SysTick_CTRL_COUNTFLAG_Msk)); { X; } -// #define AT_MARK(X) while(_VAL > T1_MARK); { X; } -// #define AT_END(X) while(_VAL > T2_MARK); { X; } - -//#define AT_MARK(X) delayclocks_until(_VAL); X; -//#define AT_END(X) delayclocks_until(_VAL); X; - -#define TOTAL (T1 + T2 + T3) - -#define T1_MARK (TOTAL - T1) -#define T2_MARK (T1_MARK - T2) - template __attribute__((always_inline)) static inline void delayclocks_until(register byte b) { - __asm__ __volatile__ ( - " sub %0, %0, %1\n" - "L_%=: subs %0, %0, #2\n" - " bcs.n L_%=\n" - : /* no outputs */ - : "r" (b), "I" (MARK) - : /* no clobbers */ - ); - - } - -#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. - template static void showRGBInternal(register int nLeds, register uint8_t scale, register const byte *rgbdata) { - register data_ptr_t port asm("r7") = FastPinBB::port(); FORCE_REFERENCE(port); - register byte *data = (byte*)rgbdata; - register uint8_t *end = data + (nLeds*3 + SKIP); - - register volatile uint32_t *CTPTR asm("r6")= &SysTick->CTRL; FORCE_REFERENCE(CTPTR); - - *port = 0; - - register uint32_t b; - b = ADVANCE ? data[SKIP + RGB_BYTE0(RGB_ORDER)] :rgbdata[SKIP + RGB_BYTE0(RGB_ORDER)]; - b = scale8(b, scale); - - // Setup and start the clock - _LOAD = TOTAL; - _VAL = 0; - _CTRL |= SysTick_CTRL_CLKSOURCE_Msk; - _CTRL |= SysTick_CTRL_ENABLE_Msk; - - // read to clear the loop flag - _CTRL; - - while(data < end) { - for(register uint32_t i = 7; i > 0; i--) { - AT_BIT_START(*port = 1); - if(b& 0x80) {} else { AT_MARK(*port = 0); } - AT_END(*port = 0); - b <<= 1; - } - - AT_BIT_START(*port = 1); - if(b& 0x80) {} else { AT_MARK(*port = 0); } - AT_END(*port = 0); - - b = ADVANCE ? data[SKIP + RGB_BYTE1(RGB_ORDER)] : rgbdata[SKIP + RGB_BYTE1(RGB_ORDER)]; - b = scale8(b, scale); - - for(register uint32_t i = 7; i > 0; i--) { - AT_BIT_START(*port = 1); - if(b& 0x80) {} else { AT_MARK(*port = 0); } - AT_END(*port = 0); - b <<= 1; - } - - AT_BIT_START(*port = 1); - if(b& 0x80) {} else { AT_MARK(*port = 0); } - AT_END(*port = 0); - - b = ADVANCE ? data[SKIP + RGB_BYTE2(RGB_ORDER)] : rgbdata[SKIP + RGB_BYTE2(RGB_ORDER)]; - b = scale8(b, scale); - data += (3 + SKIP); - - for(register uint32_t i = 7; i > 0; i--) { - AT_BIT_START(*port = 1); - if(b& 0x80) {} else { AT_MARK(*port = 0); } - AT_END(*port = 0); - b <<= 1; - } - - AT_BIT_START(*port = 1); - if(b& 0x80) {} else { AT_MARK(*port = 0); } - AT_END(*port = 0); - - b = ADVANCE ? data[SKIP + RGB_BYTE0(RGB_ORDER)] : rgbdata[SKIP + RGB_BYTE0(RGB_ORDER)]; - b = scale8(b, scale); - }; - } -}; - -#endif +#include "clockless_avr.h" +#include "clockless_arm_k20.h" +#include "clockless_arm_sam.h" +#include "clockless2.h" +#include "block_clockless.h" #endif diff --git a/clockless2.h b/clockless2.h index b137f6a8..68e6477a 100644 --- a/clockless2.h +++ b/clockless2.h @@ -6,7 +6,7 @@ #include "led_sysdefs.h" #include "delay.h" - +#ifdef FASTLED_TEENSY3 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // Base template for clockless controllers. These controllers have 3 control points in their cycle for each bit. The first point @@ -104,7 +104,6 @@ public: nLeds *= (3 + SKIP); register uint8_t *end = data + nLeds; -#if defined(FASTLED_TEENSY3) register uint32_t b; register uint32_t c; if(ADVANCE) { @@ -223,7 +222,6 @@ public: c = scale8(c, scale); delaycycles(); // 1/1 store, 2/2 load (with increment), 1/1 mul, 1/1 shift, 1 cmp, 1 branch backwards, 1 movim, 1/1 port lookup }; -#endif } #ifdef SUPPORT_ARGB @@ -238,4 +236,6 @@ public: #undef SET2_LO #undef SET2_LO2 +#endif + #endif \ No newline at end of file diff --git a/clockless_arm_k20.h b/clockless_arm_k20.h new file mode 100644 index 00000000..a0cf0998 --- /dev/null +++ b/clockless_arm_k20.h @@ -0,0 +1,139 @@ +#ifndef __INC_CLOCKLESS_ARM_K20_H +#define __INC_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) +template +class ClocklessController : public CLEDController { + typedef typename FastPin::port_ptr_t data_ptr_t; + typedef typename FastPin::port_t data_t; + + data_t mPinMask; + data_ptr_t mPort; + CMinWait mWait; +public: + virtual void init() { + FastPin::setOutput(); + mPinMask = FastPin::mask(); + mPort = FastPin::port(); + } + + virtual void clearLeds(int nLeds) { + showColor(CRGB(0, 0, 0), nLeds, 0); + } + + // set all the leds on the controller to a given color + virtual void showColor(const struct CRGB & data, int nLeds, uint8_t scale = 255) { + mWait.wait(); + cli(); + + showRGBInternal<0, false>(nLeds, scale, (const byte*)&data); + + // Adjust the timer + long microsTaken = CLKS_TO_MICROS((long)nLeds * 8 * (T1 + T2 + T3)); + MS_COUNTER += (microsTaken / 1000); + sei(); + mWait.mark(); + } + + virtual void show(const struct CRGB *rgbdata, int nLeds, uint8_t scale = 255) { + mWait.wait(); + cli(); + + showRGBInternal<0, true>(nLeds, scale, (const byte*)rgbdata); + + // Adjust the timer + long microsTaken = CLKS_TO_MICROS((long)nLeds * 8 * (T1 + T2 + T3)); + MS_COUNTER += (microsTaken / 1000); + sei(); + mWait.mark(); + } + +#ifdef SUPPORT_ARGB + virtual void show(const struct CARGB *rgbdata, int nLeds, uint8_t scale = 255) { + mWait.wait(); + cli(); + + showRGBInternal<1, true>(nLeds, scale, (const byte*)rgbdata); + + // Adjust the timer + long microsTaken = CLKS_TO_MICROS((long)nLeds * 8 * (T1 + T2 + T3)); + MS_COUNTER += (microsTaken / 1000); + sei(); + mWait.mark(); + } +#endif + + inline static void write8Bits(register data_ptr_t port, register data_t hi, register data_t lo, register uint32_t & b) __attribute__ ((always_inline)) { + // TODO: hand rig asm version of this method. The timings are based on adjusting/studying GCC compiler ouptut. This + // will bite me in the ass at some point, I know it. + for(register uint32_t i = 7; i > 0; i--) { + FastPin::fastset(port, hi); + delaycycles(); // 5 cycles - 2 store, 1 and, 1 test, 1 if + if(b & 0x80) { FastPin::fastset(port, hi); } else { FastPin::fastset(port, lo); } + b <<= 1; + delaycycles(); // 2 cycles, 1 store/skip, 1 shift + FastPin::fastset(port, lo); + delaycycles(); // 3 cycles, 2 store, 1 sub, 1 branch backwards + } + // delay an extra cycle because falling out of the loop takes on less cycle than looping around + delaycycles<1>(); + + FastPin::fastset(port, hi); + delaycycles(); + if(b & 0x80) { FastPin::fastset(port, hi); } else { FastPin::fastset(port, lo); } + delaycycles(); // 4 cycles, 2 store, store/skip + FastPin::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. + template static void showRGBInternal(register int nLeds, register uint8_t scale, register const byte *rgbdata) { + register byte *data = (byte*)rgbdata; + register data_t mask = FastPin::mask(); + register data_ptr_t port = FastPin::port(); + nLeds *= (3 + SKIP); + register uint8_t *end = data + nLeds; + register data_t hi = *port | mask; + register data_t lo = *port & ~mask; + *port = lo; + + register uint32_t b; + b = ((ADVANCE)?data:rgbdata)[SKIP + RGB_BYTE0(RGB_ORDER)]; + b = scale8(b, scale); + while(data < end) { + // Write first byte, read next byte + write8Bits(port, hi, lo, b); + + b = ((ADVANCE)?data:rgbdata)[SKIP + RGB_BYTE1(RGB_ORDER)]; + INLINE_SCALE(b, scale); + delaycycles(); // 1 store, 2 load, 1 mul, 1 shift, + + // Write second byte + write8Bits(port, hi, lo, b); + + b = ((ADVANCE)?data:rgbdata)[SKIP + RGB_BYTE2(RGB_ORDER)]; + INLINE_SCALE(b, scale); + + data += 3 + SKIP; + if((RGB_ORDER & 0070) == 0) { + delaycycles(); // 1 store, 2 load, 1 mul, 1 shift, 1 adds if BRG or GRB + } else { + delaycycles(); // 1 store, 2 load, 1 mul, 1 shift, + } + + // Write third byte + write8Bits(port, hi, lo, b); + + b = ((ADVANCE)?data:rgbdata)[SKIP + RGB_BYTE0(RGB_ORDER)]; + INLINE_SCALE(b, scale); + + delaycycles(); // 1 store, 2 load (with increment), 1 mul, 1 shift, 1 cmp, 1 branch backwards, 1 movim + }; + } +}; +#endif + +#endif + diff --git a/clockless_arm_sam.h b/clockless_arm_sam.h new file mode 100644 index 00000000..f8b1e0bd --- /dev/null +++ b/clockless_arm_sam.h @@ -0,0 +1,213 @@ +#ifndef __INC_CLOCKLESS_ARM_SAM_H +#define __INC_CLOCKLESS_ARM_SAM_H + +// 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__) + +template +class ClocklessController : public CLEDController { + typedef typename FastPinBB::port_ptr_t data_ptr_t; + typedef typename FastPinBB::port_t data_t; + + data_t mPinMask; + data_ptr_t mPort; + CMinWait mWait; +public: + virtual void init() { + FastPinBB::setOutput(); + mPinMask = FastPinBB::mask(); + mPort = FastPinBB::port(); + } + + virtual void clearLeds(int nLeds) { + showColor(CRGB(0, 0, 0), nLeds, 0); + } + + // set all the leds on the controller to a given color + virtual void showColor(const struct CRGB & data, int nLeds, uint8_t scale = 255) { + mWait.wait(); + cli(); + SysClockSaver savedClock(T1 + T2 + T3); + + showRGBInternal<0, false>(nLeds, scale, (const byte*)&data); + + // Adjust the timer + long microsTaken = CLKS_TO_MICROS((long)nLeds * 8 * (T1 + T2 + T3)); + MS_COUNTER += (microsTaken / 1000); + savedClock.restore(); + sei(); + mWait.mark(); + } + + virtual void show(const struct CRGB *rgbdata, int nLeds, uint8_t scale = 255) { + mWait.wait(); + cli(); + SysClockSaver savedClock(T1 + T2 + T3); + + // FastPinBB::hi(); delay(1); FastPinBB::lo(); + showRGBInternal<0, true>(nLeds, scale, (const byte*)rgbdata); + + // Adjust the timer + long microsTaken = CLKS_TO_MICROS((long)nLeds * 8 * (T1 + T2 + T3)); + MS_COUNTER += (microsTaken / 1000); + savedClock.restore(); + sei(); + mWait.mark(); + } + +#ifdef SUPPORT_ARGB + virtual void show(const struct CARGB *rgbdata, int nLeds, uint8_t scale = 255) { + mWait.wait(); + cli(); + SysClockSaver savedClock(T1 + T2 + T3); + + showRGBInternal<1, true>(nLeds, scale, (const byte*)rgbdata); + + // Adjust the timer + long microsTaken = CLKS_TO_MICROS((long)nLeds * 8 * (T1 + T2 + T3)); + MS_COUNTER += (microsTaken / 1000); + savedClock.restore(); + sei(); + mWait.mark(); + } +#endif + +// I hate using defines for these, should find a better representation at some point +#define _CTRL CTPTR[0] +#define _LOAD CTPTR[1] +#define _VAL CTPTR[2] + + __attribute__((always_inline)) static inline void wait_loop_start(register volatile uint32_t *CTPTR) { + __asm__ __volatile__ ( + "L_%=: ldr.w r8, [%0]\n" + " tst.w r8, #65536\n" + " beq.n L_%=\n" + : /* no outputs */ + : "r" (CTPTR) + : "r8" + ); + } + + template __attribute__((always_inline)) static inline void wait_loop_mark(register volatile uint32_t *CTPTR) { + __asm__ __volatile__ ( + "L_%=: ldr.w r8, [%0, #8]\n" + " cmp.w r8, %1\n" + " bhi.n L_%=\n" + : /* no outputs */ + : "r" (CTPTR), "I" (MARK) + : "r8" + ); + } + + __attribute__((always_inline)) static inline void mark_port(register data_ptr_t port, register int val) { + __asm__ __volatile__ ( + " str.w %0, [%1]\n" + : /* no outputs */ + : "r" (val), "r" (port) + ); + } +#define AT_BIT_START(X) wait_loop_start(CTPTR); X; +#define AT_MARK(X) wait_loop_mark(CTPTR); { X; } +#define AT_END(X) wait_loop_mark(CTPTR); { X; } + +// #define AT_BIT_START(X) while(!(_CTRL & SysTick_CTRL_COUNTFLAG_Msk)); { X; } +// #define AT_MARK(X) while(_VAL > T1_MARK); { X; } +// #define AT_END(X) while(_VAL > T2_MARK); { X; } + +//#define AT_MARK(X) delayclocks_until(_VAL); X; +//#define AT_END(X) delayclocks_until(_VAL); X; + +#define TOTAL (T1 + T2 + T3) + +#define T1_MARK (TOTAL - T1) +#define T2_MARK (T1_MARK - T2) + template __attribute__((always_inline)) static inline void delayclocks_until(register byte b) { + __asm__ __volatile__ ( + " sub %0, %0, %1\n" + "L_%=: subs %0, %0, #2\n" + " bcs.n L_%=\n" + : /* no outputs */ + : "r" (b), "I" (MARK) + : /* no clobbers */ + ); + + } + +#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. + template static void showRGBInternal(register int nLeds, register uint8_t scale, register const byte *rgbdata) { + register data_ptr_t port asm("r7") = FastPinBB::port(); FORCE_REFERENCE(port); + register byte *data = (byte*)rgbdata; + register uint8_t *end = data + (nLeds*3 + SKIP); + + register volatile uint32_t *CTPTR asm("r6")= &SysTick->CTRL; FORCE_REFERENCE(CTPTR); + + *port = 0; + + register uint32_t b; + b = ADVANCE ? data[SKIP + RGB_BYTE0(RGB_ORDER)] :rgbdata[SKIP + RGB_BYTE0(RGB_ORDER)]; + b = scale8(b, scale); + + // Setup and start the clock + _LOAD = TOTAL; + _VAL = 0; + _CTRL |= SysTick_CTRL_CLKSOURCE_Msk; + _CTRL |= SysTick_CTRL_ENABLE_Msk; + + // read to clear the loop flag + _CTRL; + + while(data < end) { + for(register uint32_t i = 7; i > 0; i--) { + AT_BIT_START(*port = 1); + if(b& 0x80) {} else { AT_MARK(*port = 0); } + AT_END(*port = 0); + b <<= 1; + } + + AT_BIT_START(*port = 1); + if(b& 0x80) {} else { AT_MARK(*port = 0); } + AT_END(*port = 0); + + b = ADVANCE ? data[SKIP + RGB_BYTE1(RGB_ORDER)] : rgbdata[SKIP + RGB_BYTE1(RGB_ORDER)]; + b = scale8(b, scale); + + for(register uint32_t i = 7; i > 0; i--) { + AT_BIT_START(*port = 1); + if(b& 0x80) {} else { AT_MARK(*port = 0); } + AT_END(*port = 0); + b <<= 1; + } + + AT_BIT_START(*port = 1); + if(b& 0x80) {} else { AT_MARK(*port = 0); } + AT_END(*port = 0); + + b = ADVANCE ? data[SKIP + RGB_BYTE2(RGB_ORDER)] : rgbdata[SKIP + RGB_BYTE2(RGB_ORDER)]; + b = scale8(b, scale); + data += (3 + SKIP); + + for(register uint32_t i = 7; i > 0; i--) { + AT_BIT_START(*port = 1); + if(b& 0x80) {} else { AT_MARK(*port = 0); } + AT_END(*port = 0); + b <<= 1; + } + + AT_BIT_START(*port = 1); + if(b& 0x80) {} else { AT_MARK(*port = 0); } + AT_END(*port = 0); + + b = ADVANCE ? data[SKIP + RGB_BYTE0(RGB_ORDER)] : rgbdata[SKIP + RGB_BYTE0(RGB_ORDER)]; + b = scale8(b, scale); + }; + } +}; + +#endif + +#endif diff --git a/clockless_avr.h b/clockless_avr.h new file mode 100644 index 00000000..a71f23b2 --- /dev/null +++ b/clockless_avr.h @@ -0,0 +1,173 @@ +#ifndef __CLOCKLESS_AVR_H +#define __CLOCKLESS_AVR_H + +#ifdef FASTLED_AVR + +// Definition for a single channel clockless controller for the avr family of chips, like those used in +// the arduino and teensy 2.x. Note that there is a special case for hardware-mul-less versions of the avr, +// which are tracked in clockless_trinket.h +template +class ClocklessController : public CLEDController { + typedef typename FastPin::port_ptr_t data_ptr_t; + typedef typename FastPin::port_t data_t; + + data_t mPinMask; + data_ptr_t mPort; + CMinWait mWait; +public: + virtual void init() { + FastPin::setOutput(); + mPinMask = FastPin::mask(); + mPort = FastPin::port(); + } + + template inline static void bitSetLast(register data_ptr_t port, register data_t hi, register data_t lo, register uint8_t b) { + // First cycle + SET_HI; // 1 clock cycle if using out, 2 otherwise + delaycycles(); // 1st cycle length minus 1 clock for out, 1 clock for sbrs + __asm__ __volatile__ ("sbrs %0, %1" :: "r" (b), "M" (N) :); // 1 clock for check (+1 if skipping, next op is also 1 clock) + + // Second cycle + SET_LO; // 1/2 clock cycle if using out + delaycycles(); // 2nd cycle length minus 1/2 clock for out + + // Third cycle + SET_LO; // 1/2 clock cycle if using out + delaycycles(); // 3rd cycle length minus 7 clocks for out, loop compare, jump, next uint8_t load + } + + virtual void clearLeds(int nLeds) { + showColor(CRGB(0, 0, 0), nLeds, 0); + } + + // set all the leds on the controller to a given color + virtual void showColor(const struct CRGB & data, int nLeds, uint8_t scale = 255) { + mWait.wait(); + cli(); + + showRGBInternal<0, false>(nLeds, scale, (const byte*)&data); + + // Adjust the timer + long microsTaken = CLKS_TO_MICROS((long)nLeds * 8 * (T1 + T2 + T3)); + MS_COUNTER += (microsTaken / 1000); + sei(); + mWait.mark(); + } + + virtual void show(const struct CRGB *rgbdata, int nLeds, uint8_t scale = 255) { + mWait.wait(); + cli(); + + showRGBInternal<0, true>(nLeds, scale, (const byte*)rgbdata); + + // Adjust the timer + long microsTaken = CLKS_TO_MICROS((long)nLeds * 8 * (T1 + T2 + T3)); + MS_COUNTER += (microsTaken / 1000); + sei(); + mWait.mark(); + } + +#ifdef SUPPORT_ARGB + virtual void show(const struct CARGB *rgbdata, int nLeds, uint8_t scale = 255) { + mWait.wait(); + cli(); + + showRGBInternal<1, true>((long)nLeds, scale, (const byte*)rgbdata); + + // Adjust the timer + long microsTaken = CLKS_TO_MICROS((long)nLeds * 8 * (T1 + T2 + T3)); + MS_COUNTER += (microsTaken / 1000); + sei(); + mWait.mark(); + } +#endif + + // 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. + template static void showRGBInternal(register int nLeds, register uint8_t scale, register const byte *rgbdata) { + register byte *data = (byte*)rgbdata; + register data_ptr_t port = FastPin::port(); + nLeds *= (3 + SKIP); + register uint8_t *end = data + nLeds; + register data_t hi = FastPin::hival(); + register data_t lo = FastPin::loval();; + *port = lo; + + register uint8_t b; + + if(ADVANCE) { + b = data[SKIP + RGB_BYTE0(RGB_ORDER)]; + } else { + b = rgbdata[SKIP + RGB_BYTE0(RGB_ORDER)]; + } + b = scale8_LEAVING_R1_DIRTY(b, scale); + + register uint8_t c; + register uint8_t d; + while(data < end) { + for(register byte x=5; x; x--) { + bitSetLast<7, 4>(port, hi, lo, b); + b <<= 1; + } + delaycycles<1>(); + // Leave an extra 2 clocks for the next byte load + bitSetLast<7, 1>(port, hi, lo, b); + delaycycles<1>(); + + // Leave an extra 4 clocks for the scale + bitSetLast<6, 6>(port, hi, lo, b); + if(ADVANCE) { + c = data[SKIP + RGB_BYTE1(RGB_ORDER)]; + } else { + c = rgbdata[SKIP + RGB_BYTE1(RGB_ORDER)]; + delaycycles<1>(); + } + INLINE_SCALE(c, scale); + bitSetLast<5, 1>(port, hi, lo, b); + + for(register byte x=5; x; x--) { + bitSetLast<7, 4>(port, hi, lo, c); + c <<= 1; + } + delaycycles<1>(); + // Leave an extra 2 clocks for the next byte load + bitSetLast<7, 1>(port, hi, lo, c); + delaycycles<1>(); + + // Leave an extra 4 clocks for the scale + bitSetLast<6, 6>(port, hi, lo, c); + if(ADVANCE) { + d = data[SKIP + RGB_BYTE2(RGB_ORDER)]; + } else { + d = rgbdata[SKIP + RGB_BYTE2(RGB_ORDER)]; + delaycycles<1>(); + } + INLINE_SCALE(d, scale); + bitSetLast<5, 1>(port, hi, lo, c); + + for(register byte x=5; x; x--) { + bitSetLast<7, 4>(port, hi, lo, d); + d <<= 1; + } + delaycycles<1>(); + // Leave an extra 2 clocks for the next byte load + bitSetLast<7, 2>(port, hi, lo, d); + data += (SKIP + 3); + // Leave an extra 4 clocks for the scale + bitSetLast<6, 6>(port, hi, lo, d); + if(ADVANCE) { + b = data[SKIP + RGB_BYTE0(RGB_ORDER)]; + } else { + b = rgbdata[SKIP + RGB_BYTE0(RGB_ORDER)]; + delaycycles<1>(); + } + INLINE_SCALE(b, scale); + bitSetLast<5, 6>(port, hi, lo, d); + } + cleanup_R1(); + } +}; +#endif + +#endif + diff --git a/clockless_trinket.h b/clockless_trinket.h index 168ba670..7fb593dd 100644 --- a/clockless_trinket.h +++ b/clockless_trinket.h @@ -6,6 +6,7 @@ #include "delay.h" #include // for cli/se definitions +#if defined(LIB8_ATTINY) // Scaling macro choice #ifndef TRINKET_SCALE @@ -277,3 +278,5 @@ public: }; #endif + +#endif -- cgit v1.2.3 From a06777a8c930f595a5b88662f5958c99ddbf71fb Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Sun, 26 Jan 2014 17:32:04 -0800 Subject: Splitting pin definitions out into platform specific files --- clockless_avr.h | 6 +- fastpin.h | 352 ++-------------------------------------------------- fastspi.h | 2 +- fastspi_arm.h | 363 ------------------------------------------------------ fastspi_arm_k20.h | 363 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 376 insertions(+), 710 deletions(-) delete mode 100644 fastspi_arm.h create mode 100644 fastspi_arm_k20.h diff --git a/clockless_avr.h b/clockless_avr.h index a71f23b2..a822fb4e 100644 --- a/clockless_avr.h +++ b/clockless_avr.h @@ -24,16 +24,16 @@ public: template inline static void bitSetLast(register data_ptr_t port, register data_t hi, register data_t lo, register uint8_t b) { // First cycle SET_HI; // 1 clock cycle if using out, 2 otherwise - delaycycles(); // 1st cycle length minus 1 clock for out, 1 clock for sbrs + delaycycles(); // 1st cycle length minus 1 clock for out, 1 clock for sbrs __asm__ __volatile__ ("sbrs %0, %1" :: "r" (b), "M" (N) :); // 1 clock for check (+1 if skipping, next op is also 1 clock) // Second cycle SET_LO; // 1/2 clock cycle if using out - delaycycles(); // 2nd cycle length minus 1/2 clock for out + delaycycles(); // 2nd cycle length minus 1/2 clock for out // Third cycle SET_LO; // 1/2 clock cycle if using out - delaycycles(); // 3rd cycle length minus 7 clocks for out, loop compare, jump, next uint8_t load + delaycycles(); // 3rd cycle length minus 7 clocks for out, loop compare, jump, next uint8_t load } virtual void clearLeds(int nLeds) { diff --git a/fastpin.h b/fastpin.h index 7a943ae4..4455089a 100644 --- a/fastpin.h +++ b/fastpin.h @@ -28,12 +28,6 @@ public: // ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) -#define _CYCLES(_PIN) (((_PIN >= 62 ) || (_PIN>=42 && _PIN<=49) || (_PIN>=14 && _PIN <=17) || (_PIN>=6 && _PIN <=9)) ? 2 : 1) -#else -#define _CYCLES(_PIN) ((_PIN >= 24) ? 2 : 1) -#endif - class Selectable { public: virtual void select() = 0; @@ -148,181 +142,11 @@ template volatile RoReg *FastPin::sInPort; template class FastPinBB : public FastPin {}; -/// 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 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; } -}; - -/// 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 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_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 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; } -}; - -/// 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 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_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 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; } -}; - -/// 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 : public _AVRPIN {}; - -// ARM definitions -#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))) typedef volatile uint32_t & reg32_t; typedef volatile uint32_t * ptr_reg32_t; -#define _RD32(T) struct __gen_struct_ ## T { static __attribute__((always_inline)) inline reg32_t r() { return T; } \ - template 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 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 : public _DUEPIN {}; \ - template<> class FastPinBB : public _DUEPIN_BITBAND {}; - #define _DEFPIN_ARM(PIN, BIT, L) template<> class FastPin : public _ARMPIN {}; \ - template<> class FastPinBB : public _ARMPIN_BITBAND {}; /////////////////////////////////////////////////////////////////////////////////////////////////////////// // @@ -331,180 +155,22 @@ typedef volatile uint32_t * ptr_reg32_t; // /////////////////////////////////////////////////////////////////////////////////////////////////////////// #if defined(FORCE_SOFTWARE_PINS) + #warning "Softwrae pin support forced pin access will be slightly slower. See fastpin.h for info." #define NO_HARDWARE_PIN_SUPPORT - -#elif defined(__AVR_ATtiny85__) -_IO(B); - -_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); - -#elif(__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__) || defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) -_IO(A); _IO(B); - -_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); - -#elif defined(__AVR_ATmega328P__) || defined(__AVR_ATmega168__) -// 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 - -#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 - -// 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 - -#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 - -#elif defined(__AVR_ATmega32U4__) - -// leonard defs -_IO(B); _IO(C); _IO(D); _IO(E); _IO(F); - -#define MAX_PIN 23 -_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, 0, F); - -#define SPI_DATA 16 -#define SPI_CLOCK 15 -#define AVR_HARDWARE_SPI - -#elif 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 ARM_HARDWARE_SPI - -#elif 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); +#undef HAS_HARDWARE_PIN_SUPPORT #else +// We want hardware pin support, include the hardware pin header files +#include "fastpin_avr.h" +#include "fastpin_arm_k20.h" +#include "fastpin_arm_sam.h" + +#ifndef HAS_HARDWARE_PIN_SUPPORT #warning "No pin/port mappings found, pin access will be slightly slower. See fastpin.h for info." #define NO_HARDWARE_PIN_SUPPORT +#endif #endif diff --git a/fastspi.h b/fastspi.h index 5a0e2974..831bae34 100644 --- a/fastspi.h +++ b/fastspi.h @@ -42,7 +42,7 @@ public: // Include the various specific SPI implementations #include "fastspi_bitbang.h" -#include "fastspi_arm.h" +#include "fastspi_arm_k20.h" #include "fastspi_avr.h" #include "fastspi_dma.h" diff --git a/fastspi_arm.h b/fastspi_arm.h deleted file mode 100644 index 8db42ac3..00000000 --- a/fastspi_arm.h +++ /dev/null @@ -1,363 +0,0 @@ -#ifndef __INC_FASTSPI_ARM_H -#define __INC_FASTSPI_ARM_H - - -#if defined(FASTLED_TEENSY3) && defined(CORE_TEENSY) - -#ifndef SPI_PUSHR_CONT -#define SPI_PUSHR_CONT SPI0_PUSHR_CONT -#define SPI_PUSHR_CTAS(X) SPI0_PUSHR_CTAS(X) -#define SPI_PUSHR_EOQ SPI0_PUSHR_EOQ -#define SPI_PUSHR_CTCNT SPI0_PUSHR_CTCNT -#define SPI_PUSHR_PCS(X) SPI0_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 class BitWork { - public: - static int highestBit() __attribute__((always_inline)) { return (VAL & 1 << BIT) ? BIT : BitWork::highestBit(); } -}; -template class BitWork { - public: - static int highestBit() __attribute__((always_inline)) { return 0; } -}; - -#define MAX(A, B) (( (A) > (B) ) ? (A) : (B)) - -#define USE_CONT 0 - -// Templated function to translate a clock divider value into the prescalar, scalar, and clock doubling setting for the world. -template 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::highestBit(); - int p3 = BitWork::highestBit(); - int p5 = BitWork::highestBit(); - int p7 = BitWork::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; -} - - -template -class ARMHardwareSPIOutput { - Selectable *m_pSelect; - - // Borrowed from the teensy3 SPSR emulation code - static inline void enable_pins(void) __attribute__((always_inline)) { - //serial_print("enable_pins\n"); - CORE_PIN11_CONFIG = PORT_PCR_DSE | PORT_PCR_MUX(2); - CORE_PIN12_CONFIG = PORT_PCR_MUX(2); - CORE_PIN13_CONFIG = PORT_PCR_DSE | PORT_PCR_MUX(2); - } - - // Borrowed from the teensy3 SPSR emulation code - static inline void disable_pins(void) __attribute__((always_inline)) { - //serial_print("disable_pins\n"); - CORE_PIN11_CONFIG = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1); - CORE_PIN12_CONFIG = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1); - CORE_PIN13_CONFIG = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1); - } - -public: - ARMHardwareSPIOutput() { m_pSelect = NULL; } - ARMHardwareSPIOutput(Selectable *pSelect) { m_pSelect = pSelect; } - void setSelect(Selectable *pSelect) { m_pSelect = pSelect; } - - static inline void update_ctar0(uint32_t ctar) __attribute__((always_inline)) { - if (SPI0_CTAR0 == ctar) return; - uint32_t mcr = SPI0_MCR; - if (mcr & SPI_MCR_MDIS) { - SPI0_CTAR0 = ctar; - } else { - SPI0_MCR = mcr | SPI_MCR_MDIS | SPI_MCR_HALT; - SPI0_CTAR0 = ctar; - - SPI0_MCR = mcr; - } - } - - static inline void update_ctar1(uint32_t ctar) __attribute__((always_inline)) { - if (SPI0_CTAR1 == ctar) return; - uint32_t mcr = SPI0_MCR; - if (mcr & SPI_MCR_MDIS) { - SPI0_CTAR1 = ctar; - } else { - SPI0_MCR = mcr | SPI_MCR_MDIS | SPI_MCR_HALT; - SPI0_CTAR1 = ctar; - SPI0_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_ctar0(ctar0); - update_ctar1(ctar1); - - } - - void init() { - // set the pins to output - FastPin<_DATA_PIN>::setOutput(); - FastPin<_CLOCK_PIN>::setOutput(); - release(); - - // Enable SPI0 clock - uint32_t sim6 = SIM_SCGC6; - if (!(sim6 & SIM_SCGC6_SPI0)) { - //serial_print("init1\n"); - SIM_SCGC6 = sim6 | SIM_SCGC6_SPI0; - SPI0_CTAR0 = SPI_CTAR_FMSZ(7) | SPI_CTAR_PBR(1) | SPI_CTAR_BR(1); - } - - setSPIRate(); - - // Configure SPI as the master and enable - SPI0_MCR |= SPI_MCR_MSTR; // | SPI_MCR_CONT_SCKE); - SPI0_MCR &= ~(SPI_MCR_MDIS | SPI_MCR_HALT); - - enable_pins(); - } - - static void waitFully() __attribute__((always_inline)) { - while( (SPI0_SR & 0xF000) > 0); - while (!(SPI0_SR & SPI_SR_TCF)); - SPI0_SR |= (SPI_SR_TCF | SPI_SR_EOQF); - } - - static bool needwait() __attribute__((always_inline)) { return (SPI0_SR & 0x4000); } - static void wait() __attribute__((always_inline)) { while( (SPI0_SR & 0x4000) ); } - static void wait1() __attribute__((always_inline)) { while( (SPI0_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 class Write { - public: - static void writeWord(uint16_t w) __attribute__((always_inline)) { - if(WAIT_STATE == PRE) { wait(); } - SPI0_PUSHR = ((LAST_STATE == LAST) ? SPI_PUSHR_EOQ : 0) | - ((CONT_STATE == CONT) ? SPI_PUSHR_CONT : 0) | - SPI_PUSHR_CTAS(1) | (w & 0xFFFF); - if(WAIT_STATE == POST) { wait(); } - } - - static void writeByte(uint8_t b) __attribute__((always_inline)) { - if(WAIT_STATE == PRE) { wait(); } - SPI0_PUSHR = ((LAST_STATE == LAST) ? SPI_PUSHR_EOQ : 0) | - ((CONT_STATE == CONT) ? SPI_PUSHR_CONT : 0) | - SPI_PUSHR_CTAS(0) | (b & 0xFF); - if(WAIT_STATE == POST) { wait(); } - } - }; - - static void writeWord(uint16_t w) __attribute__((always_inline)) { wait(); SPI0_PUSHR = SPI_PUSHR_CTAS(1) | (w & 0xFFFF); } - static void writeWordNoWait(uint16_t w) __attribute__((always_inline)) { SPI0_PUSHR = SPI_PUSHR_CTAS(1) | (w & 0xFFFF); } - - static void writeByte(uint8_t b) __attribute__((always_inline)) { wait(); SPI0_PUSHR = SPI_PUSHR_CTAS(0) | (b & 0xFF); } - static void writeBytePostWait(uint8_t b) __attribute__((always_inline)) { SPI0_PUSHR = SPI_PUSHR_CTAS(0) | (b & 0xFF); wait(); } - static void writeByteNoWait(uint8_t b) __attribute__((always_inline)) { SPI0_PUSHR = SPI_PUSHR_CTAS(0) | (b & 0xFF); } - - static void writeWordCont(uint16_t w) __attribute__((always_inline)) { wait(); SPI0_PUSHR = SPI_PUSHR_CONT | SPI_PUSHR_CTAS(1) | (w & 0xFFFF); } - static void writeWordContNoWait(uint16_t w) __attribute__((always_inline)) { SPI0_PUSHR = SPI_PUSHR_CONT | SPI_PUSHR_CTAS(1) | (w & 0xFFFF); } - - static void writeByteCont(uint8_t b) __attribute__((always_inline)) { wait(); SPI0_PUSHR = SPI_PUSHR_CONT | SPI_PUSHR_CTAS(0) | (b & 0xFF); } - static void writeByteContPostWait(uint8_t b) __attribute__((always_inline)) { SPI0_PUSHR = SPI_PUSHR_CONT | SPI_PUSHR_CTAS(0) | (b & 0xFF); wait(); } - static void writeByteContNoWait(uint8_t b) __attribute__((always_inline)) { SPI0_PUSHR = SPI_PUSHR_CONT | SPI_PUSHR_CTAS(0) | (b & 0xFF); } - - // not the most efficient mechanism in the world - but should be enough for sm16716 and friends - template inline static void writeBit(uint8_t b) { - uint32_t ctar1_save = SPI0_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(0); - update_ctar1(ctar1); - - writeWord( (b & (1 << BIT)) != 0); - - update_ctar1(ctar1_save); - } - - void inline select() __attribute__((always_inline)) { if(m_pSelect != NULL) { m_pSelect->select(); } } - void inline release() __attribute__((always_inline)) { if(m_pSelect != NULL) { m_pSelect->release(); } } - - static void writeBytesValueRaw(uint8_t value, int len) { - while(len--) { Write::writeByte(value); } - } - - void writeBytesValue(uint8_t value, int len) { - setSPIRate(); - select(); - while(len--) { - writeByte(value); - } - waitFully(); - release(); - } - - // Write a block of n uint8_ts out - template void writeBytes(register uint8_t *data, int len) { - setSPIRate(); - uint8_t *end = data + len; - select(); - while(data != end) { - writeByte(D::adjust(*data++)); - } - D::postBlock(len); - waitFully(); - release(); - } - - void writeBytes(register uint8_t *data, int len) { writeBytes(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 void writeBytes3(register uint8_t *data, int len, register uint8_t scale) { - // setSPIRate(); - uint8_t *end = data + len; - select(); - if((SKIP & FLAG_START_BIT) == 0) { - //If no start bit stupiditiy, write out as many 16-bit blocks as we can - uint8_t *first_end = end - (len % (SPI_ADVANCE * 2)); - - while(data != first_end) { - if(WM == NONE) { wait1(); } - Write::writeWord(D::adjust(data[SPI_B0], scale) << 8 | D::adjust(data[SPI_B1], scale)); - Write::writeWord(D::adjust(data[SPI_B2], scale) << 8 | D::adjust(data[SPI_ADVANCE + SPI_B0], scale)); - Write::writeWord(D::adjust(data[SPI_ADVANCE + SPI_B1], scale) << 8 | D::adjust(data[SPI_ADVANCE + SPI_B2], scale)); - data += (SPI_ADVANCE + SPI_ADVANCE); - } - - if(data != end) { - if(WM == NONE) { wait1(); } - // write out the rest as alternating 16/8-bit blocks (likely to be just one) - Write::writeWord(D::adjust(data[SPI_B0], scale) << 8 | D::adjust(data[SPI_B1], scale)); - Write::writeByte(D::adjust(data[SPI_B2], scale)); - } - - D::postBlock(len); - waitFully(); - } else if(SKIP & FLAG_START_BIT) { - uint32_t ctar1_save = SPI0_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(data != end) { - writeWord( 0x100 | D::adjust(data[SPI_B0], scale)); - writeByte(D::adjust(data[SPI_B1], scale)); - writeByte(D::adjust(data[SPI_B2], scale)); - data += SPI_ADVANCE; - } - D::postBlock(len); - waitFully(); - - // restore ctar1 - update_ctar1(ctar1_save); - // } else { - // while(data != end) { - // writeByte(D::adjust(data[SPI_B0], scale); - // writeWord(D::adjust(data[SPI_B1], scale) << 8 | D::adjust(data[SPI_B2], scale)); - // data += SPI_ADVANCE; - // } - // waitFully(); - } - release(); - } - - - template void writeBytes3(register uint8_t *data, int len, register uint8_t scale) { - writeBytes3(data, len, scale); - } - template void writeBytes3(register uint8_t *data, int len, register uint8_t scale) { - writeBytes3<0, D, RGB_ORDER>(data, len, scale); - } - template void writeBytes3(register uint8_t *data, int len, register uint8_t scale) { - writeBytes3<0, DATA_NOP, RGB_ORDER>(data, len, scale); - } - void writeBytes3(register uint8_t *data, int len, register uint8_t scale) { - writeBytes3<0, DATA_NOP, RGB>(data, len, scale); - } -}; -#endif - -#endif diff --git a/fastspi_arm_k20.h b/fastspi_arm_k20.h new file mode 100644 index 00000000..8db42ac3 --- /dev/null +++ b/fastspi_arm_k20.h @@ -0,0 +1,363 @@ +#ifndef __INC_FASTSPI_ARM_H +#define __INC_FASTSPI_ARM_H + + +#if defined(FASTLED_TEENSY3) && defined(CORE_TEENSY) + +#ifndef SPI_PUSHR_CONT +#define SPI_PUSHR_CONT SPI0_PUSHR_CONT +#define SPI_PUSHR_CTAS(X) SPI0_PUSHR_CTAS(X) +#define SPI_PUSHR_EOQ SPI0_PUSHR_EOQ +#define SPI_PUSHR_CTCNT SPI0_PUSHR_CTCNT +#define SPI_PUSHR_PCS(X) SPI0_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 class BitWork { + public: + static int highestBit() __attribute__((always_inline)) { return (VAL & 1 << BIT) ? BIT : BitWork::highestBit(); } +}; +template class BitWork { + public: + static int highestBit() __attribute__((always_inline)) { return 0; } +}; + +#define MAX(A, B) (( (A) > (B) ) ? (A) : (B)) + +#define USE_CONT 0 + +// Templated function to translate a clock divider value into the prescalar, scalar, and clock doubling setting for the world. +template 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::highestBit(); + int p3 = BitWork::highestBit(); + int p5 = BitWork::highestBit(); + int p7 = BitWork::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; +} + + +template +class ARMHardwareSPIOutput { + Selectable *m_pSelect; + + // Borrowed from the teensy3 SPSR emulation code + static inline void enable_pins(void) __attribute__((always_inline)) { + //serial_print("enable_pins\n"); + CORE_PIN11_CONFIG = PORT_PCR_DSE | PORT_PCR_MUX(2); + CORE_PIN12_CONFIG = PORT_PCR_MUX(2); + CORE_PIN13_CONFIG = PORT_PCR_DSE | PORT_PCR_MUX(2); + } + + // Borrowed from the teensy3 SPSR emulation code + static inline void disable_pins(void) __attribute__((always_inline)) { + //serial_print("disable_pins\n"); + CORE_PIN11_CONFIG = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1); + CORE_PIN12_CONFIG = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1); + CORE_PIN13_CONFIG = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1); + } + +public: + ARMHardwareSPIOutput() { m_pSelect = NULL; } + ARMHardwareSPIOutput(Selectable *pSelect) { m_pSelect = pSelect; } + void setSelect(Selectable *pSelect) { m_pSelect = pSelect; } + + static inline void update_ctar0(uint32_t ctar) __attribute__((always_inline)) { + if (SPI0_CTAR0 == ctar) return; + uint32_t mcr = SPI0_MCR; + if (mcr & SPI_MCR_MDIS) { + SPI0_CTAR0 = ctar; + } else { + SPI0_MCR = mcr | SPI_MCR_MDIS | SPI_MCR_HALT; + SPI0_CTAR0 = ctar; + + SPI0_MCR = mcr; + } + } + + static inline void update_ctar1(uint32_t ctar) __attribute__((always_inline)) { + if (SPI0_CTAR1 == ctar) return; + uint32_t mcr = SPI0_MCR; + if (mcr & SPI_MCR_MDIS) { + SPI0_CTAR1 = ctar; + } else { + SPI0_MCR = mcr | SPI_MCR_MDIS | SPI_MCR_HALT; + SPI0_CTAR1 = ctar; + SPI0_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_ctar0(ctar0); + update_ctar1(ctar1); + + } + + void init() { + // set the pins to output + FastPin<_DATA_PIN>::setOutput(); + FastPin<_CLOCK_PIN>::setOutput(); + release(); + + // Enable SPI0 clock + uint32_t sim6 = SIM_SCGC6; + if (!(sim6 & SIM_SCGC6_SPI0)) { + //serial_print("init1\n"); + SIM_SCGC6 = sim6 | SIM_SCGC6_SPI0; + SPI0_CTAR0 = SPI_CTAR_FMSZ(7) | SPI_CTAR_PBR(1) | SPI_CTAR_BR(1); + } + + setSPIRate(); + + // Configure SPI as the master and enable + SPI0_MCR |= SPI_MCR_MSTR; // | SPI_MCR_CONT_SCKE); + SPI0_MCR &= ~(SPI_MCR_MDIS | SPI_MCR_HALT); + + enable_pins(); + } + + static void waitFully() __attribute__((always_inline)) { + while( (SPI0_SR & 0xF000) > 0); + while (!(SPI0_SR & SPI_SR_TCF)); + SPI0_SR |= (SPI_SR_TCF | SPI_SR_EOQF); + } + + static bool needwait() __attribute__((always_inline)) { return (SPI0_SR & 0x4000); } + static void wait() __attribute__((always_inline)) { while( (SPI0_SR & 0x4000) ); } + static void wait1() __attribute__((always_inline)) { while( (SPI0_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 class Write { + public: + static void writeWord(uint16_t w) __attribute__((always_inline)) { + if(WAIT_STATE == PRE) { wait(); } + SPI0_PUSHR = ((LAST_STATE == LAST) ? SPI_PUSHR_EOQ : 0) | + ((CONT_STATE == CONT) ? SPI_PUSHR_CONT : 0) | + SPI_PUSHR_CTAS(1) | (w & 0xFFFF); + if(WAIT_STATE == POST) { wait(); } + } + + static void writeByte(uint8_t b) __attribute__((always_inline)) { + if(WAIT_STATE == PRE) { wait(); } + SPI0_PUSHR = ((LAST_STATE == LAST) ? SPI_PUSHR_EOQ : 0) | + ((CONT_STATE == CONT) ? SPI_PUSHR_CONT : 0) | + SPI_PUSHR_CTAS(0) | (b & 0xFF); + if(WAIT_STATE == POST) { wait(); } + } + }; + + static void writeWord(uint16_t w) __attribute__((always_inline)) { wait(); SPI0_PUSHR = SPI_PUSHR_CTAS(1) | (w & 0xFFFF); } + static void writeWordNoWait(uint16_t w) __attribute__((always_inline)) { SPI0_PUSHR = SPI_PUSHR_CTAS(1) | (w & 0xFFFF); } + + static void writeByte(uint8_t b) __attribute__((always_inline)) { wait(); SPI0_PUSHR = SPI_PUSHR_CTAS(0) | (b & 0xFF); } + static void writeBytePostWait(uint8_t b) __attribute__((always_inline)) { SPI0_PUSHR = SPI_PUSHR_CTAS(0) | (b & 0xFF); wait(); } + static void writeByteNoWait(uint8_t b) __attribute__((always_inline)) { SPI0_PUSHR = SPI_PUSHR_CTAS(0) | (b & 0xFF); } + + static void writeWordCont(uint16_t w) __attribute__((always_inline)) { wait(); SPI0_PUSHR = SPI_PUSHR_CONT | SPI_PUSHR_CTAS(1) | (w & 0xFFFF); } + static void writeWordContNoWait(uint16_t w) __attribute__((always_inline)) { SPI0_PUSHR = SPI_PUSHR_CONT | SPI_PUSHR_CTAS(1) | (w & 0xFFFF); } + + static void writeByteCont(uint8_t b) __attribute__((always_inline)) { wait(); SPI0_PUSHR = SPI_PUSHR_CONT | SPI_PUSHR_CTAS(0) | (b & 0xFF); } + static void writeByteContPostWait(uint8_t b) __attribute__((always_inline)) { SPI0_PUSHR = SPI_PUSHR_CONT | SPI_PUSHR_CTAS(0) | (b & 0xFF); wait(); } + static void writeByteContNoWait(uint8_t b) __attribute__((always_inline)) { SPI0_PUSHR = SPI_PUSHR_CONT | SPI_PUSHR_CTAS(0) | (b & 0xFF); } + + // not the most efficient mechanism in the world - but should be enough for sm16716 and friends + template inline static void writeBit(uint8_t b) { + uint32_t ctar1_save = SPI0_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(0); + update_ctar1(ctar1); + + writeWord( (b & (1 << BIT)) != 0); + + update_ctar1(ctar1_save); + } + + void inline select() __attribute__((always_inline)) { if(m_pSelect != NULL) { m_pSelect->select(); } } + void inline release() __attribute__((always_inline)) { if(m_pSelect != NULL) { m_pSelect->release(); } } + + static void writeBytesValueRaw(uint8_t value, int len) { + while(len--) { Write::writeByte(value); } + } + + void writeBytesValue(uint8_t value, int len) { + setSPIRate(); + select(); + while(len--) { + writeByte(value); + } + waitFully(); + release(); + } + + // Write a block of n uint8_ts out + template void writeBytes(register uint8_t *data, int len) { + setSPIRate(); + uint8_t *end = data + len; + select(); + while(data != end) { + writeByte(D::adjust(*data++)); + } + D::postBlock(len); + waitFully(); + release(); + } + + void writeBytes(register uint8_t *data, int len) { writeBytes(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 void writeBytes3(register uint8_t *data, int len, register uint8_t scale) { + // setSPIRate(); + uint8_t *end = data + len; + select(); + if((SKIP & FLAG_START_BIT) == 0) { + //If no start bit stupiditiy, write out as many 16-bit blocks as we can + uint8_t *first_end = end - (len % (SPI_ADVANCE * 2)); + + while(data != first_end) { + if(WM == NONE) { wait1(); } + Write::writeWord(D::adjust(data[SPI_B0], scale) << 8 | D::adjust(data[SPI_B1], scale)); + Write::writeWord(D::adjust(data[SPI_B2], scale) << 8 | D::adjust(data[SPI_ADVANCE + SPI_B0], scale)); + Write::writeWord(D::adjust(data[SPI_ADVANCE + SPI_B1], scale) << 8 | D::adjust(data[SPI_ADVANCE + SPI_B2], scale)); + data += (SPI_ADVANCE + SPI_ADVANCE); + } + + if(data != end) { + if(WM == NONE) { wait1(); } + // write out the rest as alternating 16/8-bit blocks (likely to be just one) + Write::writeWord(D::adjust(data[SPI_B0], scale) << 8 | D::adjust(data[SPI_B1], scale)); + Write::writeByte(D::adjust(data[SPI_B2], scale)); + } + + D::postBlock(len); + waitFully(); + } else if(SKIP & FLAG_START_BIT) { + uint32_t ctar1_save = SPI0_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(data != end) { + writeWord( 0x100 | D::adjust(data[SPI_B0], scale)); + writeByte(D::adjust(data[SPI_B1], scale)); + writeByte(D::adjust(data[SPI_B2], scale)); + data += SPI_ADVANCE; + } + D::postBlock(len); + waitFully(); + + // restore ctar1 + update_ctar1(ctar1_save); + // } else { + // while(data != end) { + // writeByte(D::adjust(data[SPI_B0], scale); + // writeWord(D::adjust(data[SPI_B1], scale) << 8 | D::adjust(data[SPI_B2], scale)); + // data += SPI_ADVANCE; + // } + // waitFully(); + } + release(); + } + + + template void writeBytes3(register uint8_t *data, int len, register uint8_t scale) { + writeBytes3(data, len, scale); + } + template void writeBytes3(register uint8_t *data, int len, register uint8_t scale) { + writeBytes3<0, D, RGB_ORDER>(data, len, scale); + } + template void writeBytes3(register uint8_t *data, int len, register uint8_t scale) { + writeBytes3<0, DATA_NOP, RGB_ORDER>(data, len, scale); + } + void writeBytes3(register uint8_t *data, int len, register uint8_t scale) { + writeBytes3<0, DATA_NOP, RGB>(data, len, scale); + } +}; +#endif + +#endif -- cgit v1.2.3 From d23d69c681e7b965a80d16154d42d58124a74d15 Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Sun, 26 Jan 2014 17:33:49 -0800 Subject: actually add the new split out fastpin header files --- fastpin_arm_k20.h | 97 +++++++++++++++++++++++++++++ fastpin_arm_sam.h | 104 +++++++++++++++++++++++++++++++ fastpin_avr.h | 180 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 381 insertions(+) create mode 100644 fastpin_arm_k20.h create mode 100644 fastpin_arm_sam.h create mode 100644 fastpin_avr.h diff --git a/fastpin_arm_k20.h b/fastpin_arm_k20.h new file mode 100644 index 00000000..0eaa11d6 --- /dev/null +++ b/fastpin_arm_k20.h @@ -0,0 +1,97 @@ +#ifndef __FASTPIN_ARM_K20_H +#define __FASTPIN_ARM_K20_H + +/// 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 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_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 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 _RD32(T) struct __gen_struct_ ## T { static __attribute__((always_inline)) inline reg32_t r() { return T; } \ + template 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 : public _ARMPIN {}; \ + template<> class FastPinBB : public _ARMPIN_BITBAND {}; + +// 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 ARM_HARDWARE_SPI +#define HAS_HARDWARE_PIN_SUPPORT +#endif + +#endif diff --git a/fastpin_arm_sam.h b/fastpin_arm_sam.h new file mode 100644 index 00000000..9aad9425 --- /dev/null +++ b/fastpin_arm_sam.h @@ -0,0 +1,104 @@ +#ifndef __INC_FASTPIN_ARM_SAM_H +#define __INC_FASTPIN_ARM_SAM_H + +/// 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 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_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 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 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 : public _DUEPIN {}; \ + template<> class FastPinBB : public _DUEPIN_BITBAND {}; + +#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); + +#define HAS_HARDWARE_PIN_SUPPORT + +#endif + + +#endif diff --git a/fastpin_avr.h b/fastpin_avr.h new file mode 100644 index 00000000..cb1e04ee --- /dev/null +++ b/fastpin_avr.h @@ -0,0 +1,180 @@ +#ifndef __INC_FASTPIN_AVR_H +#define __INC_FASTPIN_AVR_H + +#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) +#define AVR_PIN_CYCLES(_PIN) (((_PIN >= 62 ) || (_PIN>=42 && _PIN<=49) || (_PIN>=14 && _PIN <=17) || (_PIN>=6 && _PIN <=9)) ? 2 : 1) +#else +#define AVR_PIN_CYCLES(_PIN) ((_PIN >= 24) ? 2 : 1) +#endif + + +/// 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 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 : public _AVRPIN {}; + +#if defined(__AVR_ATtiny85__) +_IO(B); + +_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(__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__) || defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) +_IO(A); _IO(B); + +_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(__AVR_ATmega328P__) || defined(__AVR_ATmega168__) +// 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 + +#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 + +#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 + +#elif defined(__AVR_ATmega32U4__) + +// leonard defs +_IO(B); _IO(C); _IO(D); _IO(E); _IO(F); + +#define MAX_PIN 23 +_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, 0, F); + +#define SPI_DATA 16 +#define SPI_CLOCK 15 +#define AVR_HARDWARE_SPI 1 +#define HAS_HARDWARE_PIN_SUPPORT 1 + +#endif + +#endif \ No newline at end of file -- cgit v1.2.3 From 456845727cd8b9ea33fc4ed40e5f090a5a53f1d4 Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Mon, 27 Jan 2014 11:04:56 -0800 Subject: Some more tweaking/spreading out of the SPI code --- fastspi_arm_sam.h | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++ fastspi_nop.h | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 123 insertions(+) create mode 100644 fastspi_arm_sam.h create mode 100644 fastspi_nop.h diff --git a/fastspi_arm_sam.h b/fastspi_arm_sam.h new file mode 100644 index 00000000..2e17634d --- /dev/null +++ b/fastspi_arm_sam.h @@ -0,0 +1,60 @@ +#ifndef __INC_FASTSPI_ARM_SAM_H +#define __INC_FASTSPI_ARM_SAM_H + +template +class SAMHardwareSPIOutput { + +public: + SAMHardwareSPIOutput() { /* TODO */ } + SAMHArdwareSPIOutput(Selectable *pSelect) { /* TODO */ } + + // set the object representing the selectable + void setSelect(Selectable *pSelect) { /* TODO */ } + + // initialize the SPI subssytem + void init() { /* TODO */ } + + // latch the CS select + void select() { /* TODO */ } + + // release the CS select + void release() { /* TODO */ } + + // wait until all queued up data has been written + void waitFully(); + + // write a byte out via SPI (returns immediately on writing register) + void writeByte(uint8_t b) { /* TODO */ } + // write a word out via SPI (returns immediately on writing register) + void writeWord(uint16_t w) { /* TODO */ } + + // A raw set of writing byte values, assumes setup/init/waiting done elsewhere + void writeBytesValueRaw(uint8_t value, int len) { /* TODO */ } + + // A full cycle of writing a value for len bytes, including select, release, and waiting + void writeBytesValue(uint8_t value, int len) { /* TODO */ } + + // A full cycle of writing a raw block of data out, including select, release, and waiting + void writeBytes(uint8_t *data, int len) { /* TODO */ } + + // write a single bit out, which bit from the passed in byte is determined by template parameter + template inline static void writeBit(uint8_t b) { /* TODO */ } + + template void writeBytes3(register uint8_t *data, int len, register uint8_t scale) { /* TODO*/ } + + // template instantiations for writeBytes 3 + template void writeBytes3(register uint8_t *data, int len, register uint8_t scale) { + writeBytes3(data, len, scale); + } + template void writeBytes3(register uint8_t *data, int len, register uint8_t scale) { + writeBytes3<0, D, RGB_ORDER>(data, len, scale); + } + template void writeBytes3(register uint8_t *data, int len, register uint8_t scale) { + writeBytes3<0, DATA_NOP, RGB_ORDER>(data, len, scale); + } + void writeBytes3(register uint8_t *data, int len, register uint8_t scale) { + writeBytes3<0, DATA_NOP, RGB>(data, len, scale); + +}; + +#endif \ No newline at end of file diff --git a/fastspi_nop.h b/fastspi_nop.h new file mode 100644 index 00000000..64cd5128 --- /dev/null +++ b/fastspi_nop.h @@ -0,0 +1,63 @@ +#ifndef __INC_FASTSPI_NOP_H +#define __INC_FASTSPI_NOP_H + +// 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 +class NOPSPIOutput { + +public: + NOPSPIOutput() { /* TODO */ } + NOPSPIOutput(Selectable *pSelect) { /* TODO */ } + + // set the object representing the selectable + void setSelect(Selectable *pSelect) { /* TODO */ } + + // initialize the SPI subssytem + void init() { /* TODO */ } + + // latch the CS select + void select() { /* TODO */ } + + // release the CS select + void release() { /* TODO */ } + + // wait until all queued up data has been written + void waitFully(); + + // write a byte out via SPI (returns immediately on writing register) + void writeByte(uint8_t b) { /* TODO */ } + // write a word out via SPI (returns immediately on writing register) + void writeWord(uint16_t w) { /* TODO */ } + + // 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) { /* TODO */ } + + // A full cycle of writing a value for len bytes, including select, release, and waiting + void writeBytesValue(uint8_t value, int len) { /* TODO */ } + + // A full cycle of writing a raw block of data out, including select, release, and waiting + void writeBytes(uint8_t *data, int len) { /* TODO */ } + + // write a single bit out, which bit from the passed in byte is determined by template parameter + template inline static void writeBit(uint8_t b) { /* TODO */ } + + template void writeBytes3(register uint8_t *data, int len, register uint8_t scale) { /* TODO*/ } + + // template instantiations for writeBytes 3 + template void writeBytes3(register uint8_t *data, int len, register uint8_t scale) { + writeBytes3(data, len, scale); + } + template void writeBytes3(register uint8_t *data, int len, register uint8_t scale) { + writeBytes3<0, D, RGB_ORDER>(data, len, scale); + } + template void writeBytes3(register uint8_t *data, int len, register uint8_t scale) { + writeBytes3<0, DATA_NOP, RGB_ORDER>(data, len, scale); + } + void writeBytes3(register uint8_t *data, int len, register uint8_t scale) { + writeBytes3<0, DATA_NOP, RGB>(data, len, scale); + +}; + +#endif \ No newline at end of file -- cgit v1.2.3 From aace2bd49c5a94fab137a9531d0a5b009f700051 Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Tue, 28 Jan 2014 14:02:07 -0800 Subject: Adding grey aliases for the gray colors. --- pixeltypes.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/pixeltypes.h b/pixeltypes.h index 6d3f67f2..e1dfa610 100644 --- a/pixeltypes.h +++ b/pixeltypes.h @@ -424,6 +424,7 @@ struct CRGB { DarkCyan=0x008B8B, DarkGoldenrod=0xB8860B, DarkGray=0xA9A9A9, + DarkGrey=0xA9A9A9, DarkGreen=0x006400, DarkKhaki=0xBDB76B, DarkMagenta=0x8B008B, @@ -435,11 +436,13 @@ struct CRGB { DarkSeaGreen=0x8FBC8F, DarkSlateBlue=0x483D8B, DarkSlateGray=0x2F4F4F, + DarkSlateGrey=0x2F4F4F, DarkTurquoise=0x00CED1, DarkViolet=0x9400D3, DeepPink=0xFF1493, DeepSkyBlue=0x00BFFF, DimGray=0x696969, + DimGrey=0x696969, DodgerBlue=0x1E90FF, FireBrick=0xB22222, FloralWhite=0xFFFAF0, @@ -450,6 +453,7 @@ struct CRGB { Gold=0xFFD700, Goldenrod=0xDAA520, Gray=0x808080, + Grey=0x808080, Green=0x008000, GreenYellow=0xADFF2F, Honeydew=0xF0FFF0, @@ -473,6 +477,7 @@ struct CRGB { LightSeaGreen=0x20B2AA, LightSkyBlue=0x87CEFA, LightSlateGray=0x778899, + LightSlateGrey=0x778899, LightSteelBlue=0xB0C4DE, LightYellow=0xFFFFE0, Lime=0x00FF00, @@ -526,6 +531,7 @@ struct CRGB { SkyBlue=0x87CEEB, SlateBlue=0x6A5ACD, SlateGray=0x708090, + SlateGrey=0x708090, Snow=0xFFFAFA, SpringGreen=0x00FF7F, SteelBlue=0x4682B4, -- cgit v1.2.3 From a927ba4f1e59b7d5f118a2795f0da30b029d5077 Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Thu, 6 Feb 2014 09:57:26 -0500 Subject: Fixing build error on some platforms --- lib8tion.h | 1 + 1 file changed, 1 insertion(+) diff --git a/lib8tion.h b/lib8tion.h index 280def94..2dfdcb1b 100644 --- a/lib8tion.h +++ b/lib8tion.h @@ -220,6 +220,7 @@ Lib8tion is pronounced like 'libation': lie-BAY-shun #define SCALE16_C 1 #define ABS8_C 1 #define MUL8_C 1 +#define QMUL8_C 1 #define ADD8_C 1 #define SUB8_C 1 #define EASE8_C 1 -- cgit v1.2.3 From 277672e070f6a8a01246c527bbeb7465e74aa86b Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Thu, 6 Feb 2014 09:57:54 -0500 Subject: Changing max LPD8806 speed to match datasheet --- chipsets.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chipsets.h b/chipsets.h index ef71a2da..f0188d1b 100644 --- a/chipsets.h +++ b/chipsets.h @@ -9,7 +9,7 @@ // ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -template +template class LPD8806Controller : public CLEDController { typedef SPIOutput SPI; -- cgit v1.2.3 From 46661e13e10f707f9ca19d57b627b89d7d09fec0 Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Mon, 10 Feb 2014 16:06:20 -0500 Subject: Fix issues #26 (ensure LPD8806's 8-7bit conversion doesn't drop non-black pixel values to black) and #25 (ensure that we get the right clockless chip timings when running on 8Mhz AVRs, regardless of whether or not we have hardware mul - aka the adafruit Flora) --- chipsets.h | 18 ++++++++++++------ fastspi_arm_k20.h | 1 - lib8tion.h | 1 - 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/chipsets.h b/chipsets.h index f0188d1b..2864b5c7 100644 --- a/chipsets.h +++ b/chipsets.h @@ -16,8 +16,8 @@ class LPD8806Controller : public CLEDController { class LPD8806_ADJUST { public: // LPD8806 spec wants the high bit of every rgb data byte sent out to be set. - __attribute__((always_inline)) inline static uint8_t adjust(register uint8_t data) { return (data>>1) | 0x80; } - __attribute__((always_inline)) inline static uint8_t adjust(register uint8_t data, register uint8_t scale) { return (scale8(data, scale)>>1) | 0x80; } + __attribute__((always_inline)) inline static uint8_t adjust(register uint8_t data) { return (data>>1) | 0x80 | (data & 0x01); } + __attribute__((always_inline)) inline static uint8_t adjust(register uint8_t data, register uint8_t scale) { return (scale8(data, scale)>>1) | 0x80 | (data & 0x01); } __attribute__((always_inline)) inline static void postBlock(int len) { SPI::writeBytesValueRaw(0, ((len+63)>>6)); } @@ -54,9 +54,13 @@ public: virtual void showColor(const struct CRGB & data, int nLeds, uint8_t scale = 255) { mSPI.select(); - uint8_t a = 0x80 | (scale8(data[RGB_BYTE0(RGB_ORDER)], scale) >> 1); - uint8_t b = 0x80 | (scale8(data[RGB_BYTE1(RGB_ORDER)], scale) >> 1); - uint8_t c = 0x80 | (scale8(data[RGB_BYTE2(RGB_ORDER)], scale) >> 1); + uint8_t a = data[RGB_BYTE0(RGB_ORDER)]; + uint8_t b = data[RGB_BYTE1(RGB_ORDER)]; + uint8_t c = data[RGB_BYTE1(RGB_ORDER)]; + + a = 0x80 | (scale8(a, scale) >> 1) | (a & 0x01); + b = 0x80 | (scale8(b, scale) >> 1) | (b & 0x01); + c = 0x80 | (scale8(c, scale) >> 1) | (c & 0x01); int iLeds = 0; while(iLeds++ < nLeds) { @@ -290,7 +294,9 @@ public: // ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -#if defined(LIB8_ATTINY) && (F_CPU == 8000000) // 125ns/clock +// We want to force all avr's to use the Trinket controller when running at 8Mhz, because even the 328's at 8Mhz +// need the more tightly defined timeframes. +#if (defined(LIB8_ATTINY) || defined(FASTLED_AVR)) && (F_CPU == 8000000) // 125ns/clock // WS2811@8Mhz 2 clocks, 5 clocks, 3 clocks template class WS2811Controller800Khz : public ClocklessController_Trinket {}; diff --git a/fastspi_arm_k20.h b/fastspi_arm_k20.h index 8db42ac3..76f5b528 100644 --- a/fastspi_arm_k20.h +++ b/fastspi_arm_k20.h @@ -344,7 +344,6 @@ public: release(); } - template void writeBytes3(register uint8_t *data, int len, register uint8_t scale) { writeBytes3(data, len, scale); } diff --git a/lib8tion.h b/lib8tion.h index 2dfdcb1b..2ccd7601 100644 --- a/lib8tion.h +++ b/lib8tion.h @@ -1085,7 +1085,6 @@ LIB8STATIC int16_t cos16( uint16_t theta) return sin16( theta + 16384); } - /////////////////////////////////////////////////////////////////////// // // memmove8, memcpy8, and memset8: -- cgit v1.2.3 From a10b38d220b6c28ba8abaed6aff6ed9bc03e6f6b Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Mon, 10 Feb 2014 16:39:42 -0500 Subject: Preliminary test support for the GW6205 dropping 4 0 bits after the 8 bits of rgb data. Note: this is just writing out 8bit data to a 12bit chipset. Next step will be filling in the low 4 bits from scaling results (if applicable), then finally real CRGB16 support --- FastLED.h | 6 ++++++ chipsets.h | 14 +++++++++++++ clockless_avr.h | 36 ++++++++++++++++++++++++++++++---- examples/Blink/Blink.ino | 2 ++ examples/Cylon/Cylon.ino | 2 +- examples/FirstLight/FirstLight.ino | 2 ++ examples/RGBCalibrate/RGBCalibrate.ino | 2 ++ 7 files changed, 59 insertions(+), 5 deletions(-) diff --git a/FastLED.h b/FastLED.h index 89e94d92..55758951 100644 --- a/FastLED.h +++ b/FastLED.h @@ -29,6 +29,8 @@ enum EClocklessChipsets { UCS1903B, WS2811_400, NEOPIXEL, + GW6205, + GW6205_400, TM1829 }; @@ -113,6 +115,8 @@ public: case WS2811: { static WS2811Controller800Khz controller; return addLeds(&controller, data, nLedsOrOffset, nLedsIfOffset); } case NEOPIXEL: { static WS2811Controller800Khz controller; return addLeds(&controller, data, nLedsOrOffset, nLedsIfOffset); } case WS2811_400: { static WS2811Controller400Khz controller; return addLeds(&controller, data, nLedsOrOffset, nLedsIfOffset); } + case GW6205: { static GW6205Controller800Khz controller; return addLeds(&controller, data, nLedsOrOffset, nLedsIfOffset); } + case GW6205_400: { static GW6205Controller400Khz controller; return addLeds(&controller, data, nLedsOrOffset, nLedsIfOffset); } } return NULL; } @@ -134,6 +138,8 @@ public: case NEOPIXEL: case WS2811: { static WS2811Controller800Khz controller; return addLeds(&controller, data, nLedsOrOffset, nLedsIfOffset); } case WS2811_400: { static WS2811Controller400Khz controller; return addLeds(&controller, data, nLedsOrOffset, nLedsIfOffset); } + case GW6205: { static GW6205Controller800Khz controller; return addLeds(&controller, data, nLedsOrOffset, nLedsIfOffset); } + case GW6205_400: { static GW6205Controller400Khz controller; return addLeds(&controller, data, nLedsOrOffset, nLedsIfOffset); } } return NULL; } diff --git a/chipsets.h b/chipsets.h index 2864b5c7..ca76a818 100644 --- a/chipsets.h +++ b/chipsets.h @@ -338,6 +338,20 @@ template class TM1803Controller400Khz : public ClocklessController {}; #else +// GW6205@400khz - 800ns, 800ns, 800ns +template +class GW6205Controller400Khz : public ClocklessController {}; +#if NO_TIME(800, 800, 800) +#warning "Not enough clock cycles available for the GW6205@400khz" +#endif + +// GW6205@400khz - 400ns, 400ns, 400ns +template +class GW6205Controller800Khz : public ClocklessController {}; +#if NO_TIME(400, 400, 400) +#warning "Not enough clock cycles available for the GW6205@400khz" +#endif + // UCS1903 - 500ns, 1500ns, 500ns template class UCS1903Controller400Khz : public ClocklessController {}; diff --git a/clockless_avr.h b/clockless_avr.h index a822fb4e..887188b3 100644 --- a/clockless_avr.h +++ b/clockless_avr.h @@ -6,7 +6,7 @@ // Definition for a single channel clockless controller for the avr family of chips, like those used in // the arduino and teensy 2.x. Note that there is a special case for hardware-mul-less versions of the avr, // which are tracked in clockless_trinket.h -template +template class ClocklessController : public CLEDController { typedef typename FastPin::port_ptr_t data_ptr_t; typedef typename FastPin::port_t data_t; @@ -125,6 +125,14 @@ public: INLINE_SCALE(c, scale); bitSetLast<5, 1>(port, hi, lo, b); + if(XTRA0 > 0) { + for(register byte x=XTRA0; x; x--) { + bitSetLast<4,4>(port, hi, lo, b); + b <<=1; + } + delaycycles<1>(); + } + for(register byte x=5; x; x--) { bitSetLast<7, 4>(port, hi, lo, c); c <<= 1; @@ -145,9 +153,17 @@ public: INLINE_SCALE(d, scale); bitSetLast<5, 1>(port, hi, lo, c); + if(XTRA0 > 0) { + for(register byte x=XTRA0; x; x--) { + bitSetLast<4,4>(port, hi, lo, c); + c <<=1; + } + delaycycles<1>(); + } + for(register byte x=5; x; x--) { - bitSetLast<7, 4>(port, hi, lo, d); - d <<= 1; + bitSetLast<7, 4>(port, hi, lo, c); + c <<= 1; } delaycycles<1>(); // Leave an extra 2 clocks for the next byte load @@ -162,7 +178,19 @@ public: delaycycles<1>(); } INLINE_SCALE(b, scale); - bitSetLast<5, 6>(port, hi, lo, d); + + if(XTRA0 > 0) { + bitSetLast<5, 1>(port, hi, lo, d); + for(register byte x=XTRA0-1; x; x--) { + bitSetLast<4,4>(port, hi, lo, d); + d <<=1; + } + delaycycles<1>(); + bitSetLast<4,6>(port,hi,lo,d); + } else { + bitSetLast<5,6>(port, hi, lo, d); + } + } cleanup_R1(); } diff --git a/examples/Blink/Blink.ino b/examples/Blink/Blink.ino index 1d7f1fa7..fb0d90d8 100644 --- a/examples/Blink/Blink.ino +++ b/examples/Blink/Blink.ino @@ -23,6 +23,8 @@ void setup() { // FastLED.addLeds(leds, NUM_LEDS); // FastLED.addLeds(leds, NUM_LEDS); FastLED.addLeds(leds, NUM_LEDS); + // FastLED.addLeds(leds, NUM_LEDS); + // FastLED.addLeds(leds, NUM_LEDS); // FastLED.addLeds(leds, NUM_LEDS); // FastLED.addLeds(leds, NUM_LEDS); diff --git a/examples/Cylon/Cylon.ino b/examples/Cylon/Cylon.ino index bec878c5..8d133da2 100644 --- a/examples/Cylon/Cylon.ino +++ b/examples/Cylon/Cylon.ino @@ -40,4 +40,4 @@ void loop() { // Wait a little bit before we loop around and do it again delay(30); } -} \ No newline at end of file +} diff --git a/examples/FirstLight/FirstLight.ino b/examples/FirstLight/FirstLight.ino index 1572dad6..ebd58f13 100644 --- a/examples/FirstLight/FirstLight.ino +++ b/examples/FirstLight/FirstLight.ino @@ -37,6 +37,8 @@ void setup() { // FastLED.addLeds(leds, NUM_LEDS); // FastLED.addLeds(leds, NUM_LEDS); // FastLED.addLeds(leds, NUM_LEDS); + // FastLED.addLeds(leds, NUM_LEDS); + // FastLED.addLeds(leds, NUM_LEDS); // FastLED.addLeds(leds, NUM_LEDS); FastLED.addLeds(leds, NUM_LEDS); diff --git a/examples/RGBCalibrate/RGBCalibrate.ino b/examples/RGBCalibrate/RGBCalibrate.ino index 7be08c7c..59c1dd4f 100644 --- a/examples/RGBCalibrate/RGBCalibrate.ino +++ b/examples/RGBCalibrate/RGBCalibrate.ino @@ -43,6 +43,8 @@ void setup() { // FastLED.addLeds(leds, NUM_LEDS); // FastLED.addLeds(leds, NUM_LEDS); // FastLED.addLeds(leds, NUM_LEDS); + // FastLED.addLeds(leds, NUM_LEDS); + // FastLED.addLeds(leds, NUM_LEDS); // FastLED.addLeds(leds, NUM_LEDS); // FastLED.addLeds(leds, NUM_LEDS); -- cgit v1.2.3 From 4358f5b6df821b831993141e18ef20b33b16c54f Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Wed, 12 Feb 2014 15:47:41 -0500 Subject: Add dithering support for clockless chips on the due --- clockless_arm_sam.h | 67 ++++++++++++++++++++++++++-------- controller.h | 4 ++ examples/RGBCalibrate/RGBCalibrate.ino | 6 +-- 3 files changed, 59 insertions(+), 18 deletions(-) diff --git a/clockless_arm_sam.h b/clockless_arm_sam.h index f8b1e0bd..5d8fc47f 100644 --- a/clockless_arm_sam.h +++ b/clockless_arm_sam.h @@ -31,7 +31,7 @@ public: cli(); SysClockSaver savedClock(T1 + T2 + T3); - showRGBInternal<0, false>(nLeds, scale, (const byte*)&data); + showRGBInternal<0, false>(nLeds, CRGB(scale,scale,scale), (const byte*)&data); // Adjust the timer long microsTaken = CLKS_TO_MICROS((long)nLeds * 8 * (T1 + T2 + T3)); @@ -47,7 +47,7 @@ public: SysClockSaver savedClock(T1 + T2 + T3); // FastPinBB::hi(); delay(1); FastPinBB::lo(); - showRGBInternal<0, true>(nLeds, scale, (const byte*)rgbdata); + showRGBInternal<0, true>(nLeds, CRGB(scale,scale,scale), (const byte*)rgbdata); // Adjust the timer long microsTaken = CLKS_TO_MICROS((long)nLeds * 8 * (T1 + T2 + T3)); @@ -63,7 +63,7 @@ public: cli(); SysClockSaver savedClock(T1 + T2 + T3); - showRGBInternal<1, true>(nLeds, scale, (const byte*)rgbdata); + showRGBInternal<1, true>(nLeds, CRGB(scale,scale,scale), (const byte*)rgbdata); // Adjust the timer long microsTaken = CLKS_TO_MICROS((long)nLeds * 8 * (T1 + T2 + T3)); @@ -136,21 +136,37 @@ public: } #define FORCE_REFERENCE(var) asm volatile( "" : : "r" (var) ) - +#define DITHER 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. - template static void showRGBInternal(register int nLeds, register uint8_t scale, register const byte *rgbdata) { + template static void showRGBInternal(register int nLeds, register CRGB scale, register const byte *rgbdata) { register data_ptr_t port asm("r7") = FastPinBB::port(); FORCE_REFERENCE(port); register byte *data = (byte*)rgbdata; register uint8_t *end = data + (nLeds*3 + SKIP); - + uint8_t E[3] = {0xFF,0xFF,0xFF}; + uint8_t D[3] = {0,0,0}; + + static uint8_t Dstore[3] = {0,0,0}; + + // compute the E values and seed D from the stored values + for(register uint32_t i = 0; i < 3; i++) { + byte S = scale.raw[i]; + while(S>>=1) { E[i] >>=1; }; + D[i] = Dstore[i] & E[i]; + } + register volatile uint32_t *CTPTR asm("r6")= &SysTick->CTRL; FORCE_REFERENCE(CTPTR); *port = 0; register uint32_t b; - b = ADVANCE ? data[SKIP + RGB_BYTE0(RGB_ORDER)] :rgbdata[SKIP + RGB_BYTE0(RGB_ORDER)]; - b = scale8(b, scale); + b = ADVANCE ? data[SKIP + B0] :rgbdata[SKIP + B0]; + // dither + if(DITHER && b) b = qadd8(b, D[B0]); + // advance D constrained by E + D[B0] += 3; D[B0] &= E[B0]; + // now scale + b = scale8(b, scale.raw[B0]); // Setup and start the clock _LOAD = TOTAL; @@ -173,8 +189,11 @@ public: if(b& 0x80) {} else { AT_MARK(*port = 0); } AT_END(*port = 0); - b = ADVANCE ? data[SKIP + RGB_BYTE1(RGB_ORDER)] : rgbdata[SKIP + RGB_BYTE1(RGB_ORDER)]; - b = scale8(b, scale); + b = ADVANCE ? data[SKIP + B1] : rgbdata[SKIP + B1]; + // dither + if(DITHER && b) b = qadd8(b, D[B1]); + // now scale + b = scale8(b, scale.raw[B1]); for(register uint32_t i = 7; i > 0; i--) { AT_BIT_START(*port = 1); @@ -187,9 +206,11 @@ public: if(b& 0x80) {} else { AT_MARK(*port = 0); } AT_END(*port = 0); - b = ADVANCE ? data[SKIP + RGB_BYTE2(RGB_ORDER)] : rgbdata[SKIP + RGB_BYTE2(RGB_ORDER)]; - b = scale8(b, scale); - data += (3 + SKIP); + b = ADVANCE ? data[SKIP + B2] : rgbdata[SKIP + B2]; + // dither + if(DITHER && b) b = qadd8(b, D[B2]); + // now scale + b = scale8(b, scale.raw[B2]); for(register uint32_t i = 7; i > 0; i--) { AT_BIT_START(*port = 1); @@ -202,9 +223,25 @@ public: if(b& 0x80) {} else { AT_MARK(*port = 0); } AT_END(*port = 0); - b = ADVANCE ? data[SKIP + RGB_BYTE0(RGB_ORDER)] : rgbdata[SKIP + RGB_BYTE0(RGB_ORDER)]; - b = scale8(b, scale); + // We have some extra time between rgb pixels, prep + // the next byte and cycle the dither adjustments + data += (3 + SKIP); + b = ADVANCE ? data[SKIP + B0] : rgbdata[SKIP + B0]; + // dither + if(DITHER && b) b = qadd8(b, D[B0]); + // now scale + b = scale8(b, scale.raw[B0]); + + // advance D constrained by E + D[B0] += 3; D[B0] &= E[B0]; + D[B1] += 3; D[B1] &= E[B1]; + D[B2] += 3; D[B2] &= E[B2]; }; + + // Save the D values for cycling through next time + Dstore[0] = D[0]; + Dstore[1] = D[1]; + Dstore[2] = D[2]; } }; diff --git a/controller.h b/controller.h index e745459d..d1794cee 100644 --- a/controller.h +++ b/controller.h @@ -9,6 +9,10 @@ #define RGB_BYTE1(X) ((X>>3) & 0x3) #define RGB_BYTE2(X) ((X) & 0x3) +#define B0 RGB_BYTE0(RGB_ORDER) +#define B1 RGB_BYTE1(RGB_ORDER) +#define B2 RGB_BYTE2(RGB_ORDER) + // operator byte *(struct CRGB[] arr) { return (byte*)arr; } diff --git a/examples/RGBCalibrate/RGBCalibrate.ino b/examples/RGBCalibrate/RGBCalibrate.ino index 59c1dd4f..a8af8fc8 100644 --- a/examples/RGBCalibrate/RGBCalibrate.ino +++ b/examples/RGBCalibrate/RGBCalibrate.ino @@ -26,7 +26,7 @@ #define NUM_LEDS 6 // Data pin that led data will be written out over -#define DATA_PIN 7 +#define DATA_PIN 6 // Clock pin only needed for SPI based chipsets when not using hardware SPI //#define CLOCK_PIN 8 @@ -42,7 +42,7 @@ void setup() { // FastLED.addLeds(leds, NUM_LEDS); // FastLED.addLeds(leds, NUM_LEDS); // FastLED.addLeds(leds, NUM_LEDS); - // FastLED.addLeds(leds, NUM_LEDS); + FastLED.addLeds(leds, NUM_LEDS); // FastLED.addLeds(leds, NUM_LEDS); // FastLED.addLeds(leds, NUM_LEDS); // FastLED.addLeds(leds, NUM_LEDS); @@ -65,5 +65,5 @@ void loop() { leds[4] = CRGB::Blue; leds[5] = CRGB::Blue; FastLED.show(); - delay(1000); + // delay(1000); } -- cgit v1.2.3 From 5c027944a5f04fba509167cba558c2af3975c36b Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Wed, 12 Feb 2014 15:51:29 -0500 Subject: Adding a file to track adding dithering support --- dithertodo.txt | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 dithertodo.txt diff --git a/dithertodo.txt b/dithertodo.txt new file mode 100644 index 00000000..58240e96 --- /dev/null +++ b/dithertodo.txt @@ -0,0 +1,18 @@ +SPI: +o due +o bitbang +o k20 +o avr +o stm + +Clockless: +X due +o k20 +o avr +o stm + +Chipsets: +o LPD8806 +o WS2801 +o P9813 +o SM1676 -- cgit v1.2.3 From cb259bc471f9d5a2de54d2ebdd567e5b54c9b86a Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Wed, 12 Feb 2014 21:42:00 -0800 Subject: Switch brightness over to CRGB as well --- FastLED.cpp | 9 +++++--- FastLED.h | 17 +++++++++------ chipsets.h | 61 +++++++++++++++++++++++++++-------------------------- clockless_arm_sam.h | 39 ++++++++++++++++++++-------------- controller.h | 6 +++--- 5 files changed, 73 insertions(+), 59 deletions(-) diff --git a/FastLED.cpp b/FastLED.cpp index 7d78a8b4..b5a6a9d7 100644 --- a/FastLED.cpp +++ b/FastLED.cpp @@ -14,7 +14,7 @@ uint32_t CRGB::Squant = ((uint32_t)((__TIME__[4]-'0') * 28))<<16 | ((__TIME__[6] CFastLED::CFastLED() { // clear out the array of led controllers m_nControllers = NUM_CONTROLLERS; - m_nScale = 255; + m_Scale = CRGB::White; memset8(m_Controllers, 0, m_nControllers * sizeof(CControllerInfo)); } @@ -47,7 +47,7 @@ CLEDController *CFastLED::addLeds(CLEDController *pLed, return NULL; } -void CFastLED::show(uint8_t scale) { +void CFastLED::show(CRGB scale) { for(int i = 0; i < m_nControllers; i++) { if(m_Controllers[i].pLedController != NULL) { m_Controllers[i].pLedController->show(m_Controllers[i].pLedData + m_Controllers[i].nOffset, @@ -58,7 +58,7 @@ void CFastLED::show(uint8_t scale) { } } -void CFastLED::showColor(const struct CRGB & color, uint8_t scale) { +void CFastLED::showColor(const struct CRGB & color, CRGB scale) { for(int i = 0; i < m_nControllers; i++) { if(m_Controllers[i].pLedController != NULL) { m_Controllers[i].pLedController->showColor(color, m_Controllers[i].nLeds, scale); @@ -84,3 +84,6 @@ void CFastLED::clearData() { } } } + +void CFastLED::delay(unsigned long ms) { +} diff --git a/FastLED.h b/FastLED.h index 55758951..08f747b8 100644 --- a/FastLED.h +++ b/FastLED.h @@ -50,7 +50,7 @@ class CFastLED { CControllerInfo m_Controllers[NUM_CONTROLLERS]; int m_nControllers; - uint8_t m_nScale; + CRGB m_Scale; public: CFastLED(); @@ -154,22 +154,25 @@ public: return NULL; } - void setBrightness(uint8_t scale) { m_nScale = scale; } - uint8_t getBrightness() { return m_nScale; } + void setBrightness(CRGB scale) { m_Scale = scale; } + void setBrightness(uint8_t scale) { m_Scale = CRGB(scale,scale,scale); } + uint8_t getBrightness() { return m_Scale.raw[0]; } /// Update all our controllers with the current led colors, using the passed in brightness - void show(uint8_t scale); + void show(CRGB scale); /// Update all our controllers with the current led colors - void show() { show(m_nScale); } + void show() { show(m_Scale); } void clear(boolean writeData = false); void clearData(); - void showColor(const struct CRGB & color, uint8_t scale); + void showColor(const struct CRGB & color, CRGB scale); - void showColor(const struct CRGB & color) { showColor(color, m_nScale); } + void showColor(const struct CRGB & color) { showColor(color, m_Scale); } + + void delay(unsigned long ms); }; diff --git a/chipsets.h b/chipsets.h index ca76a818..93143967 100644 --- a/chipsets.h +++ b/chipsets.h @@ -52,15 +52,15 @@ public: mSPI.release(); } - virtual void showColor(const struct CRGB & data, int nLeds, uint8_t scale = 255) { + virtual void showColor(const struct CRGB & data, int nLeds, CRGB scale = CRGB::White) { mSPI.select(); uint8_t a = data[RGB_BYTE0(RGB_ORDER)]; uint8_t b = data[RGB_BYTE1(RGB_ORDER)]; uint8_t c = data[RGB_BYTE1(RGB_ORDER)]; - a = 0x80 | (scale8(a, scale) >> 1) | (a & 0x01); - b = 0x80 | (scale8(b, scale) >> 1) | (b & 0x01); - c = 0x80 | (scale8(c, scale) >> 1) | (c & 0x01); + a = 0x80 | (scale8(a, scale.raw[B0]) >> 1) | (a & 0x01); + b = 0x80 | (scale8(b, scale.raw[B1]) >> 1) | (b & 0x01); + c = 0x80 | (scale8(c, scale.raw[B2]) >> 1) | (c & 0x01); int iLeds = 0; while(iLeds++ < nLeds) { @@ -74,8 +74,9 @@ public: mSPI.release(); } - virtual void show(const struct CRGB *data, int nLeds, uint8_t scale = 255) { - mSPI.template writeBytes3((byte*)data, nLeds * 3, scale); + virtual void show(const struct CRGB *data, int nLeds, CRGB scale = CRGB::White) { + // TODO rgb-ize scale + mSPI.template writeBytes3((byte*)data, nLeds * 3, scale.raw[0]); } #ifdef SUPPORT_ARGB @@ -112,12 +113,12 @@ public: mWaitDelay.mark(); } - virtual void showColor(const struct CRGB & data, int nLeds, uint8_t scale = 255) { + virtual void showColor(const struct CRGB & data, int nLeds, CRGB scale = CRGB::White) { mWaitDelay.wait(); mSPI.select(); - uint8_t a = scale8(data[RGB_BYTE0(RGB_ORDER)], scale); - uint8_t b = scale8(data[RGB_BYTE1(RGB_ORDER)], scale); - uint8_t c = scale8(data[RGB_BYTE2(RGB_ORDER)], scale); + uint8_t a = scale8(data[RGB_BYTE0(RGB_ORDER)], scale.raw[B0]); + uint8_t b = scale8(data[RGB_BYTE1(RGB_ORDER)], scale.raw[B1]); + uint8_t c = scale8(data[RGB_BYTE2(RGB_ORDER)], scale.raw[B2]); while(nLeds--) { mSPI.writeByte(a); @@ -129,16 +130,16 @@ public: mWaitDelay.mark(); } - virtual void show(const struct CRGB *data, int nLeds, uint8_t scale) { + virtual void show(const struct CRGB *data, int nLeds, CRGB scale) { mWaitDelay.wait(); - mSPI.template writeBytes3<0, RGB_ORDER>((byte*)data, nLeds * 3, scale); + mSPI.template writeBytes3<0, RGB_ORDER>((byte*)data, nLeds * 3, scale.raw[0]); mWaitDelay.mark(); } #ifdef SUPPORT_ARGB - virtual void show(const struct CRGB *data, int nLeds, uint8_t scale) { + virtual void show(const struct CRGB *data, int nLeds, CRGB scale) { mWaitDelay.wait(); - mSPI.template writeBytes3<1, RGB_ORDER>((byte*)data, nLeds * 4, scale); + mSPI.template writeBytes3<1, RGB_ORDER>((byte*)data, nLeds * 4, scale.raw[0]); mWaitDelay.mark(); } #endif @@ -157,11 +158,11 @@ class P9813Controller : public CLEDController { void writeBoundary() { mSPI.writeWord(0); mSPI.writeWord(0); } - inline void writeLed(const struct CRGB & data, uint8_t scale) __attribute__((always_inline)) { + inline void writeLed(const struct CRGB & data, CRGB scale) __attribute__((always_inline)) { // prep the byte - register uint8_t r = scale8(data[RGB_BYTE0(RGB_ORDER)], scale); - register uint8_t g = scale8(data[RGB_BYTE1(RGB_ORDER)], scale); - register uint8_t b = scale8(data[RGB_BYTE2(RGB_ORDER)], scale); + register uint8_t r = scale8(data[RGB_BYTE0(RGB_ORDER)], scale.raw[B0]); + register uint8_t g = scale8(data[RGB_BYTE1(RGB_ORDER)], scale.raw[B1]); + register uint8_t b = scale8(data[RGB_BYTE2(RGB_ORDER)], scale.raw[B2]); register uint8_t top = 0xC0 | ((~b & 0xC0) >> 2) | ((~g & 0xC0) >> 4) | ((~r & 0xC0) >> 6); mSPI.writeByte(top); mSPI.writeByte(b); mSPI.writeByte(g); mSPI.writeByte(r); @@ -178,7 +179,7 @@ public: showColor(CRGB(0,0,0), nLeds); } - virtual void showColor(const struct CRGB & data, int nLeds, uint8_t scale = 255) { + virtual void showColor(const struct CRGB & data, int nLeds, CRGB scale = CRGB::White) { mSPI.select(); writeBoundary(); @@ -191,7 +192,7 @@ public: mSPI.release(); } - virtual void show(const struct CRGB *data, int nLeds, uint8_t scale) { + virtual void show(const struct CRGB *data, int nLeds, CRGB scale) { mSPI.select(); writeBoundary(); @@ -204,8 +205,8 @@ public: } #ifdef SUPPORT_ARGB - virtual void show(const struct CRGB *data, int nLeds, uint8_t scale) { - mSPI.template writeBytes3<1, RGB_ORDER>((byte*)data, nLeds * 4, scale); + virtual void show(const struct CRGB *data, int nLeds, CRGB scale) { + mSPI.template writeBytes3<1, RGB_ORDER>((byte*)data, nLeds * 4, scale.raw[0]); } #endif }; @@ -251,11 +252,11 @@ public: writeHeader(); } - virtual void showColor(const struct CRGB & data, int nLeds, uint8_t scale = 255) { + virtual void showColor(const struct CRGB & data, int nLeds, CRGB scale = CRGB::White) { mSPI.select(); - uint8_t a = scale8(data[RGB_BYTE0(RGB_ORDER)], scale); - uint8_t b = scale8(data[RGB_BYTE1(RGB_ORDER)], scale); - uint8_t c = scale8(data[RGB_BYTE2(RGB_ORDER)], scale); + uint8_t a = scale8(data[RGB_BYTE0(RGB_ORDER)], scale.raw[B0]); + uint8_t b = scale8(data[RGB_BYTE1(RGB_ORDER)], scale.raw[B1]); + uint8_t c = scale8(data[RGB_BYTE2(RGB_ORDER)], scale.raw[B2]); while(nLeds--) { mSPI.template writeBit<0>(1); @@ -267,23 +268,23 @@ public: mSPI.release(); } - virtual void show(const struct CRGB *data, int nLeds, uint8_t scale = 255) { + virtual void show(const struct CRGB *data, int nLeds, CRGB scale = CRGB::White) { // Make sure the FLAG_START_BIT flag is set to ensure that an extra 1 bit is sent at the start // of each triplet of bytes for rgb data // writeHeader(); - mSPI.template writeBytes3((byte*)data, nLeds * 3, scale); + mSPI.template writeBytes3((byte*)data, nLeds * 3, scale.raw[0]); writeHeader(); } #ifdef SUPPORT_ARGB - virtual void show(const struct CARGB *data, int nLeds, uint8_t scale = 255) { + virtual void show(const struct CARGB *data, int nLeds, CRGB scale = CRGB::White) { mSPI.writeBytesValue(0, 6); mSPI.template writeBit<0>(0); mSPI.template writeBit<0>(0); // Make sure the FLAG_START_BIT flag is set to ensure that an extra 1 bit is sent at the start // of each triplet of bytes for rgb data - mSPI.template writeBytes3<1 | FLAG_START_BIT, RGB_ORDER>((byte*)data, nLeds * 4, scale); + mSPI.template writeBytes3<1 | FLAG_START_BIT, RGB_ORDER>((byte*)data, nLeds * 4, scale.raw[0]); } #endif }; diff --git a/clockless_arm_sam.h b/clockless_arm_sam.h index 5d8fc47f..9601a908 100644 --- a/clockless_arm_sam.h +++ b/clockless_arm_sam.h @@ -26,48 +26,55 @@ public: } // set all the leds on the controller to a given color - virtual void showColor(const struct CRGB & data, int nLeds, uint8_t scale = 255) { + virtual void showColor(const struct CRGB & data, int nLeds, CRGB scale = CRGB::White) { mWait.wait(); cli(); SysClockSaver savedClock(T1 + T2 + T3); - showRGBInternal<0, false>(nLeds, CRGB(scale,scale,scale), (const byte*)&data); + showRGBInternal<0, false>(nLeds, scale, (const byte*)&data); // Adjust the timer long microsTaken = CLKS_TO_MICROS((long)nLeds * 8 * (T1 + T2 + T3)); - MS_COUNTER += (microsTaken / 1000); + long millisTaken = (microsTaken / 1000); + do { TimeTick_Increment(); } while(--millisTaken > 0); savedClock.restore(); sei(); mWait.mark(); } - virtual void show(const struct CRGB *rgbdata, int nLeds, uint8_t scale = 255) { + virtual void show(const struct CRGB *rgbdata, int nLeds, CRGB scale = CRGB::White) { mWait.wait(); cli(); SysClockSaver savedClock(T1 + T2 + T3); + Serial.print("Scale is "); + Serial.print(scale.raw[0]); Serial.print(" "); + Serial.print(scale.raw[1]); Serial.print(" "); + Serial.print(scale.raw[2]); Serial.println(" "); // FastPinBB::hi(); delay(1); FastPinBB::lo(); - showRGBInternal<0, true>(nLeds, CRGB(scale,scale,scale), (const byte*)rgbdata); + showRGBInternal<0, true>(nLeds, scale, (const byte*)rgbdata); // Adjust the timer long microsTaken = CLKS_TO_MICROS((long)nLeds * 8 * (T1 + T2 + T3)); - MS_COUNTER += (microsTaken / 1000); + long millisTaken = (microsTaken / 1000); + do { TimeTick_Increment(); } while(--millisTaken > 0); savedClock.restore(); sei(); mWait.mark(); } #ifdef SUPPORT_ARGB - virtual void show(const struct CARGB *rgbdata, int nLeds, uint8_t scale = 255) { + virtual void show(const struct CARGB *rgbdata, int nLeds, CRGB scale = CRGB::White) { mWait.wait(); cli(); SysClockSaver savedClock(T1 + T2 + T3); - showRGBInternal<1, true>(nLeds, CRGB(scale,scale,scale), (const byte*)rgbdata); + showRGBInternal<1, true>(nLeds, scale, (const byte*)rgbdata); // Adjust the timer long microsTaken = CLKS_TO_MICROS((long)nLeds * 8 * (T1 + T2 + T3)); - MS_COUNTER += (microsTaken / 1000); + long millisTaken = (microsTaken / 1000); + do { TimeTick_Increment(); } while(--millisTaken > 0); savedClock.restore(); sei(); mWait.mark(); @@ -137,6 +144,7 @@ public: #define FORCE_REFERENCE(var) asm volatile( "" : : "r" (var) ) #define DITHER 1 +#define DADVANCE 3 // 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. template static void showRGBInternal(register int nLeds, register CRGB scale, register const byte *rgbdata) { @@ -163,8 +171,6 @@ public: b = ADVANCE ? data[SKIP + B0] :rgbdata[SKIP + B0]; // dither if(DITHER && b) b = qadd8(b, D[B0]); - // advance D constrained by E - D[B0] += 3; D[B0] &= E[B0]; // now scale b = scale8(b, scale.raw[B0]); @@ -178,6 +184,12 @@ public: _CTRL; while(data < end) { + + // advance D constrained by E + D[B0] += DADVANCE; D[B0] &= E[B0]; + D[B1] += DADVANCE; D[B1] &= E[B1]; + D[B2] += DADVANCE; D[B2] &= E[B2]; + for(register uint32_t i = 7; i > 0; i--) { AT_BIT_START(*port = 1); if(b& 0x80) {} else { AT_MARK(*port = 0); } @@ -231,11 +243,6 @@ public: if(DITHER && b) b = qadd8(b, D[B0]); // now scale b = scale8(b, scale.raw[B0]); - - // advance D constrained by E - D[B0] += 3; D[B0] &= E[B0]; - D[B1] += 3; D[B1] &= E[B1]; - D[B2] += 3; D[B2] &= E[B2]; }; // Save the D values for cycling through next time diff --git a/controller.h b/controller.h index d1794cee..fa29408b 100644 --- a/controller.h +++ b/controller.h @@ -39,15 +39,15 @@ public: virtual void clearLeds(int nLeds) = 0; // set all the leds on the controller to a given color - virtual void showColor(const struct CRGB & data, int nLeds, uint8_t scale = 255) = 0; + virtual void showColor(const struct CRGB & data, int nLeds, CRGB scale = CRGB::White) = 0; // note that the uint8_ts will be in the order that you want them sent out to the device. // nLeds is the number of RGB leds being written to - virtual void show(const struct CRGB *data, int nLeds, uint8_t scale = 255) = 0; + virtual void show(const struct CRGB *data, int nLeds, CRGB scale = CRGB::White) = 0; #ifdef SUPPORT_ARGB // as above, but every 4th uint8_t is assumed to be alpha channel data, and will be skipped - virtual void show(const struct CARGB *data, int nLeds, uint8_t scale = 255) = 0; + virtual void show(const struct CARGB *data, int nLeds, CRGB scale = CRGB::White) = 0; #endif // is the controller ready to write data out -- cgit v1.2.3 From a55b3c3af12f8b2174482101d44026054862e36b Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Thu, 13 Feb 2014 09:52:34 -0800 Subject: Fix FastLED.delay --- FastLED.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/FastLED.cpp b/FastLED.cpp index b5a6a9d7..539bd5d6 100644 --- a/FastLED.cpp +++ b/FastLED.cpp @@ -86,4 +86,6 @@ void CFastLED::clearData() { } void CFastLED::delay(unsigned long ms) { + unsigned long start = millis(); + while((millis()-start) < ms) { LEDS.show(); } } -- cgit v1.2.3 From 0bfebe9752414ffa068e8f3421a073fa59e899eb Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Thu, 13 Feb 2014 11:22:59 -0800 Subject: fixing delay, again --- clockless_arm_sam.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/clockless_arm_sam.h b/clockless_arm_sam.h index 9601a908..7eb37698 100644 --- a/clockless_arm_sam.h +++ b/clockless_arm_sam.h @@ -36,8 +36,8 @@ public: // Adjust the timer long microsTaken = CLKS_TO_MICROS((long)nLeds * 8 * (T1 + T2 + T3)); long millisTaken = (microsTaken / 1000); - do { TimeTick_Increment(); } while(--millisTaken > 0); savedClock.restore(); + do { TimeTick_Increment(); } while(--millisTaken > 0); sei(); mWait.mark(); } @@ -57,8 +57,8 @@ public: // Adjust the timer long microsTaken = CLKS_TO_MICROS((long)nLeds * 8 * (T1 + T2 + T3)); long millisTaken = (microsTaken / 1000); - do { TimeTick_Increment(); } while(--millisTaken > 0); savedClock.restore(); + do { TimeTick_Increment(); } while(--millisTaken > 0); sei(); mWait.mark(); } @@ -74,8 +74,8 @@ public: // Adjust the timer long microsTaken = CLKS_TO_MICROS((long)nLeds * 8 * (T1 + T2 + T3)); long millisTaken = (microsTaken / 1000); - do { TimeTick_Increment(); } while(--millisTaken > 0); savedClock.restore(); + do { TimeTick_Increment(); } while(--millisTaken > 0); sei(); mWait.mark(); } -- cgit v1.2.3 From 902bf544a44ad0ec5bd35c6b462c0f4b2e7da5c9 Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Tue, 18 Feb 2014 12:00:36 -0800 Subject: Initial checkin of the dithering/white balance code for the trinket --- chipsets.h | 13 ++- clockless.h | 1 + clockless_trinket.h | 232 +++++++++++++++++++++++++++------------------------- 3 files changed, 133 insertions(+), 113 deletions(-) diff --git a/chipsets.h b/chipsets.h index 93143967..a7f61184 100644 --- a/chipsets.h +++ b/chipsets.h @@ -312,10 +312,19 @@ template class UCS1903BController800Khz : public ClocklessController_Trinket {}; template -class TM1809Controller800Khz : public ClocklessController {}; +class TM1809Controller800Khz : public ClocklessController_Trinket {}; template -class TM1803Controller400Khz : public ClocklessController {}; +class TM1803Controller400Khz : public ClocklessController_Trinket {}; + +template +class TM1829Controller800Khz : public ClocklessController_Trinket {}; + +template +class GW6205Controller400Khz : public ClocklessController_Trinket {}; + +template +class GW6205Controller800Khz : public ClocklessController_Trinket {}; #elif defined(LIB8_ATTINY) && (F_CPU == 16000000) // 62.5ns/clock diff --git a/clockless.h b/clockless.h index c7d3b49f..65fe18e4 100644 --- a/clockless.h +++ b/clockless.h @@ -19,6 +19,7 @@ #define SET_HI FLIP ? FastPin::fastset(port, lo) : FastPin::fastset(port, hi); #include "clockless_avr.h" +#include "clockless_trinket.h" #include "clockless_arm_k20.h" #include "clockless_arm_sam.h" #include "clockless2.h" diff --git a/clockless_trinket.h b/clockless_trinket.h index 7fb593dd..45eea2de 100644 --- a/clockless_trinket.h +++ b/clockless_trinket.h @@ -29,7 +29,7 @@ template<> __attribute__((always_inline)) inline void _dc<0>(register uint8_t & template<> __attribute__((always_inline)) inline void _dc<1>(register uint8_t & loopvar) {asm __volatile__("cp r0,r0":::);} template<> __attribute__((always_inline)) inline void _dc<2>(register uint8_t & loopvar) {asm __volatile__("rjmp .+0":::);} -#define D1(ADJ) _dc(loopvar); +#define D1(ADJ) _dc(loopvar); #define D2(ADJ) _dc(loopvar); #define D3(ADJ) _dc(loopvar); @@ -54,25 +54,25 @@ public: virtual void clearLeds(int nLeds) { static byte zeros[3] = {0,0,0}; - showRGBInternal_AdjTime(0, false, nLeds, 0, zeros); + showRGBInternal_AdjTime(0, false, nLeds, CRGB(0,0,0), zeros); } // set all the leds on the controller to a given color - virtual void showColor(const struct CRGB & data, int nLeds, uint8_t scale = 255) { + virtual void showColor(const struct CRGB & data, int nLeds, CRGB scale = CRGB::White) { showRGBInternal_AdjTime(0, false, nLeds, scale, (const byte*)&data); } - virtual void show(const struct CRGB *rgbdata, int nLeds, uint8_t scale = 255) { + virtual void show(const struct CRGB *rgbdata, int nLeds, CRGB scale = CRGB::White) { showRGBInternal_AdjTime(0, true, nLeds, scale, (const byte*)rgbdata); } #ifdef SUPPORT_ARGB - virtual void show(const struct CARGB *rgbdata, int nLeds, uint8_t scale = 255) { + virtual void show(const struct CARGB *rgbdata, int nLeds, CRGB scale = CRGB::White) { showRGBInternal_AdjTime(1, true, nLeds, scale, (const byte*)rgbdata); } #endif - void __attribute__ ((noinline)) showRGBInternal_AdjTime(int skip, bool advance, int nLeds, uint8_t scale, const byte *rgbdata) { + void __attribute__ ((noinline)) showRGBInternal_AdjTime(int skip, bool advance, int nLeds, CRGB scale, const byte *rgbdata) { mWait.wait(); cli(); @@ -87,32 +87,36 @@ public: } #define USE_ASM_MACROS - + #define ASM_VARS : /* write variables */ \ [b0] "+r" (b0), \ [b1] "+r" (b1), \ [b2] "+r" (b2), \ [count] "+x" (count), \ - [scale_base] "+r" (scale_base), \ + [scale_base] "+a" (scale_base), \ [data] "+z" (data), \ [loopvar] "+a" (loopvar) \ : /* use variables */ \ + [ADV] "r" (advanceBy), \ [hi] "r" (hi), \ [lo] "r" (lo), \ - [scale] "r" (scale), \ - [ADV] "r" (advanceBy), \ - [zero] "r" (zero), \ + [s0] "r" (s0), \ + [s1] "r" (s1), \ + [s2] "r" (s2), \ + [d0] "r" (d0), \ + [d1] "r" (d1), \ + [d2] "r" (d2), \ + [PORT] "M" (FastPin::port()-0x20), \ [O0] "M" (RGB_BYTE0(RGB_ORDER)), \ [O1] "M" (RGB_BYTE1(RGB_ORDER)), \ - [O2] "M" (RGB_BYTE2(RGB_ORDER)), \ - [PORT] "M" (FastPin::port()-0x20) \ + [O2] "M" (RGB_BYTE2(RGB_ORDER)) \ : /* clobber registers */ // 1 cycle, write hi to the port -#define HI1 asm __volatile__("out %[PORT], %[hi]" ASM_VARS ); +#define HI1 asm __volatile__("out 0x02, %[hi]" ASM_VARS ); // 1 cycle, write lo to the port -#define LO1 asm __volatile__("out %[PORT], %[lo]" ASM_VARS ); +#define LO1 asm __volatile__("out 0x02, %[lo]" ASM_VARS ); // 2 cycles, sbrs on flipping the lne 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 @@ -128,7 +132,9 @@ public: // 2 cycles - jump out of the loop #define BRLOOP1 asm __volatile__("breq 2f" ASM_VARS ); // 2 cycles - perform one step of the scaling (if a given bit is set in scale, add scale-base to the scratch space) -#define SCALE2(B, N) asm __volatile__("sbrc %[scale], " #N "\n\tadd %[" #B "], %[scale_base]" ASM_VARS ); +#define SCALE02(B, N) asm __volatile__("sbrc %[s0], " #N "\n\tadd %[" #B "], %[scale_base]" ASM_VARS ); +#define SCALE12(B, N) asm __volatile__("sbrc %[s1], " #N "\n\tadd %[" #B "], %[scale_base]" ASM_VARS ); +#define SCALE22(B, N) asm __volatile__("sbrc %[s2], " #N "\n\tadd %[" #B "], %[scale_base]" ASM_VARS ); // 1 cycle - rotate right, pulling in from carry #define ROR1(B) asm __volatile__("ror %[" #B "]" ASM_VARS ); // 1 cycle, clear the carry bit @@ -136,18 +142,29 @@ public: // 1 cycle, move one register to another #define MOV1(B1, B2) asm __volatile__("mov %[" #B1 "], %[" #B2 "]" ASM_VARS ); // 4 cycles, rotate, clear carry, scale next bit -#define RORSC4(B, N) ROR1(B) CLC1 SCALE2(B, N) +#define RORSC04(B, N) ROR1(B) CLC1 SCALE02(B, N) +#define RORSC14(B, N) ROR1(B) CLC1 SCALE12(B, N) +#define RORSC24(B, N) ROR1(B) CLC1 SCALE22(B, N) // 4 cycles, scale bit, rotate, clear carry -#define SCROR4(B, N) SCALE2(B,N) ROR1(B) CLC1 +#define SCROR04(B, N) SCALE02(B,N) ROR1(B) CLC1 +#define SCROR14(B, N) SCALE12(B,N) ROR1(B) CLC1 +#define SCROR24(B, N) SCALE22(B,N) ROR1(B) CLC1 // define the beginning of the loop -#define LOOP asm __volatile__("1:" ASM_VARS ); +#define LOOP asm __volatile__("1:" ASM_VARS ); d0 += DADVANCE; d1 += DADVANCE; d2 += DADVANCE; d0 &= e0; d1 &= e1; d2 &= d2; #define DONE asm __volatile__("2:" ASM_VARS ); // delay time - +#define DADVANCE 3 +#define DITHER 1 +#define PRESCALE0_4() if(DITHER) { asm __volatile__("cpse %[scale_base], r1\n\t add %[scale_base],%[d0]\n\tbrcc L_%=\n\tldi %[scale_base], 0xFF\n\tL_%=:\n\t" ASM_VARS); } \ + else { _dc<4>(loopvar); } +#define PRESCALE1_4() if(DITHER) { asm __volatile__("cpse %[scale_base], r1\n\t add %[scale_base],%[d1]\n\tbrcc L_%=\n\tldi %[scale_base], 0xFF\n\tL_%=:\n\t" ASM_VARS); } \ + else { _dc<4>(loopvar); } +#define PRESCALE2_4() if(DITHER) { asm __volatile__("cpse %[scale_base], r1\n\t add %[scale_base],%[d2]\n\tbrcc L_%=\n\tldi %[scale_base], 0xFF\n\tL_%=:\n\t" ASM_VARS); } \ + else { _dc<4>(loopvar); } // 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__ ((noinline)) showRGBInternal(int skip, bool advance, int nLeds, uint8_t scale, const byte *rgbdata) { + static void __attribute__ ((noinline)) showRGBInternal(int skip, bool advance, int nLeds, CRGB & scale, const byte *rgbdata) { byte *data = (byte*)rgbdata; data_t mask = FastPin::mask(); data_ptr_t port = FastPin::port(); @@ -156,118 +173,111 @@ public: data_t lo = *port & ~mask; *port = lo; + uint8_t d0, d1, d2; + uint8_t e0, e1, e2; + uint8_t s0, s1, s2; uint8_t b0, b1, b2; + static uint8_t d[3] = {0,0,0}; + uint16_t count = nLeds; uint8_t scale_base = 0; uint16_t advanceBy = advance ? (skip+3) : 0; - const uint8_t zero = 0; + + // initialize the scales + s0 = scale.raw[B0]; + s1 = scale.raw[B1]; + s2 = scale.raw[B2]; + + // initialize the e & d values + uint8_t S; + S = s0; e0 = 0xFF; while(s0 >>= 1) { e0 >>= 1; } + d0 = d[0] & e0; + S = s1; e1 = 0xFF; while(s1 >>= 1) { e1 >>= 1; } + d1 = d[1] & e1; + S = s2; e2 = 0xFF; while(s2 >>= 1) { e2 >>= 1; } + d2 = d[2] & e0; + b0 = data[RGB_BYTE0(RGB_ORDER)]; + if(DITHER && b0) { b0 = qadd8(b0, d0); } b0 = scale8(b0, scale); - b1 = data[RGB_BYTE1(RGB_ORDER)]; + b1 = 0; b2 = 0; - register uint8_t loopvar; + register uint8_t loopvar=0; - if(RGB_ORDER == RGB) { - // If the rgb order is RGB, we can cut back on program space usage by making a much more compact - // representation. - - // multiply count by 3, don't use * because there's no hardware multiply - count = count+(count<<1); - advanceBy = advance ? 1 : 0; - { - /* asm */ - LOOP - // Sum of the clock counts across each row should be 10 for 8Mhz, WS2811 -#if TRINKET_SCALE - // Inline scaling, RGB ordering matches byte ordering - HI1 D1(0) QLO2(b0, 7) LDSCL3(b1,O1) D2(3) LO1 SCALE2(b1,0) D3(2) - HI1 D1(0) QLO2(b0, 6) RORSC4(b1,1) D2(4) LO1 ROR1(b1) CLC1 D3(2) - HI1 D1(0) QLO2(b0, 5) SCROR4(b1,2) D2(4) LO1 SCALE2(b1,3) D3(2) - HI1 D1(0) QLO2(b0, 4) RORSC4(b1,4) D2(4) LO1 ROR1(b1) CLC1 D3(2) - HI1 D1(0) QLO2(b0, 3) SCROR4(b1,5) D2(4) LO1 SCALE2(b1,6) D3(2) - HI1 D1(0) QLO2(b0, 2) RORSC4(b1,7) D2(4) LO1 ROR1(b1) CLC1 D3(2) - HI1 D1(0) QLO2(b0, 1) IDATA2 D2(2) LO1 D3(0) - // In the last bit's first block, we decrement and branch to done if we decremented to 0 - HI1 D1(0) QLO2(b0, 0) DCOUNT2 BRLOOP1 MOV1(b0, b1) D2(4) LO1 D3(2) JMPLOOP2 -#else - // no inline scaling, RGB ordering matches byte ordering - HI1 D1(0) QLO2(b0, 7) LD2(b1,O1) D2(2) LO1 D3(0) - HI1 D1(0) QLO2(b0, 6) D2(0) LO1 D3(0) - HI1 D1(0) QLO2(b0, 5) D2(0) LO1 D3(0) - HI1 D1(0) QLO2(b0, 4) D2(0) LO1 D3(0) - HI1 D1(0) QLO2(b0, 3) D2(0) LO1 D3(0) - HI1 D1(0) QLO2(b0, 2) D2(0) LO1 D3(0) - HI1 D1(0) QLO2(b0, 1) IDATA2 D2(2) LO1 D3(0) - // In the last bit's first block, we decrement and branch to done if we decremented to 0 - HI1 D1(0) QLO2(b2, 0) DCOUNT2 BRLOOP1 MOV1(b0,b1) D2(4) LO1 D3(2) JMPLOOP2 -#endif - DONE - D2(4) LO1 D3(0) - } - } - else { { /* asm */ 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. #if TRINKET_SCALE // Inline scaling - RGB ordering - HI1 D1(0) QLO2(b0, 7) LDSCL3(b1,O1) D2(3) LO1 SCALE2(b1,0) D3(2) - HI1 D1(0) QLO2(b0, 6) RORSC4(b1,1) D2(4) LO1 ROR1(b1) CLC1 D3(2) - HI1 D1(0) QLO2(b0, 5) SCROR4(b1,2) D2(4) LO1 SCALE2(b1,3) D3(2) - HI1 D1(0) QLO2(b0, 4) RORSC4(b1,4) D2(4) LO1 ROR1(b1) CLC1 D3(2) - HI1 D1(0) QLO2(b0, 3) SCROR4(b1,5) D2(4) LO1 SCALE2(b1,6) D3(2) - HI1 D1(0) QLO2(b0, 2) RORSC4(b1,7) D2(4) LO1 ROR1(b1) CLC1 D3(2) - HI1 D1(0) QLO2(b0, 1) D2(0) LO1 D3(0) - HI1 D1(0) QLO2(b0, 0) D2(0) LO1 D3(0) - HI1 D1(0) QLO2(b1, 7) LDSCL3(b2,O2) D2(3) LO1 SCALE2(b2,0) D3(2) - HI1 D1(0) QLO2(b1, 6) RORSC4(b2,1) D2(4) LO1 ROR1(b2) CLC1 D3(2) - HI1 D1(0) QLO2(b1, 5) SCROR4(b2,2) D2(4) LO1 SCALE2(b2,3) D3(2) - HI1 D1(0) QLO2(b1, 4) RORSC4(b2,4) D2(4) LO1 ROR1(b2) CLC1 D3(2) - HI1 D1(0) QLO2(b1, 3) SCROR4(b2,5) D2(4) LO1 SCALE2(b2,6) D3(2) - HI1 D1(0) QLO2(b1, 2) RORSC4(b2,7) D2(4) LO1 ROR1(b2) CLC1 D3(2) - HI1 D1(0) QLO2(b1, 1) D2(0) LO1 D3(0) - HI1 D1(0) QLO2(b1, 0) IDATA2 D2(2) LO1 D3(0) - HI1 D1(0) QLO2(b2, 7) LDSCL3(b0,O0) D2(3) LO1 SCALE2(b0,0) D3(2) - HI1 D1(0) QLO2(b2, 6) RORSC4(b0,1) D2(4) LO1 ROR1(b0) CLC1 D3(2) - HI1 D1(0) QLO2(b2, 5) SCROR4(b0,2) D2(4) LO1 SCALE2(b0,3) D3(2) - HI1 D1(0) QLO2(b2, 4) RORSC4(b0,4) D2(4) LO1 ROR1(b0) CLC1 D3(2) - HI1 D1(0) QLO2(b2, 3) SCROR4(b0,5) D2(4) LO1 SCALE2(b0,6) D3(2) - HI1 D1(0) QLO2(b2, 2) RORSC4(b0,7) D2(4) LO1 ROR1(b0) CLC1 D3(2) - HI1 D1(0) QLO2(b2, 1) D2(0) LO1 D3(0) - HI1 D1(0) QLO2(b2, 0) DCOUNT2 BRLOOP1 D2(3) LO1 D3(2) JMPLOOP2 + HI1 D1(1) QLO2(b0, 7) LDSCL3(b1,O1) D2(3) LO1 D3(0) + HI1 D1(1) QLO2(b0, 6) PRESCALE1_4() D2(4) LO1 SCALE12(b1,0) D3(2) + HI1 D1(1) QLO2(b0, 5) RORSC14(b1,1) D2(4) LO1 ROR1(b1) CLC1 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 ROR1(b1) CLC1 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 ROR1(b1) CLC1 D3(2) + HI1 D1(1) QLO2(b0, 0) D2(0) LO1 D3(0) + HI1 D1(1) QLO2(b1, 7) LDSCL3(b2,O1) D2(3) LO1 D3(0) + HI1 D1(1) QLO2(b1, 6) PRESCALE2_4() D2(4) LO1 SCALE22(b2,0) D3(2) + HI1 D1(1) QLO2(b1, 5) RORSC24(b2,1) D2(4) LO1 ROR1(b2) CLC1 D3(2) + HI1 D1(1) QLO2(b1, 4) SCROR24(b2,2) D2(4) LO1 SCALE22(b2,3) D3(2) + HI1 D1(1) QLO2(b1, 3) RORSC24(b2,4) D2(4) LO1 ROR1(b2) CLC1 D3(2) + HI1 D1(1) QLO2(b1, 2) SCROR24(b2,5) D2(4) LO1 SCALE22(b2,6) D3(2) + HI1 D1(1) QLO2(b1, 1) RORSC24(b2,7) D2(4) LO1 ROR1(b2) CLC1 D3(2) + HI1 D1(1) QLO2(b1, 0) IDATA2 D2(2) LO1 D3(0) + HI1 D1(1) QLO2(b2, 7) LDSCL3(b2,O1) D2(3) LO1 D3(0) + HI1 D1(1) QLO2(b2, 6) PRESCALE0_4() D2(4) LO1 SCALE22(b0,0) D3(2) + HI1 D1(1) QLO2(b2, 5) RORSC04(b0,1) D2(4) LO1 ROR1(b0) CLC1 D3(2) + HI1 D1(1) QLO2(b2, 4) SCROR04(b0,2) D2(4) LO1 SCALE02(b0,3) D3(2) + HI1 D1(1) QLO2(b2, 3) RORSC04(b0,4) D2(4) LO1 ROR1(b0) CLC1 D3(2) + HI1 D1(1) QLO2(b2, 2) SCROR04(b0,5) D2(4) LO1 SCALE02(b0,6) D3(2) + HI1 D1(1) QLO2(b2, 1) RORSC04(b0,7) D2(4) LO1 ROR1(b0) CLC1 D3(2) + HI1 D1(1) QLO2(b2, 0) DCOUNT2 BRLOOP1 D2(3) LO1 D3(2) JMPLOOP2 #else // no inline scaling - non-straight RGB ordering - HI1 D1(0) QLO2(b0, 7) LD2(b1,O1) D2(2) LO1 D3(0) - HI1 D1(0) QLO2(b0, 6) D2(0) LO1 D3(0) - HI1 D1(0) QLO2(b0, 5) D2(0) LO1 D3(0) - HI1 D1(0) QLO2(b0, 4) D2(0) LO1 D3(0) - HI1 D1(0) QLO2(b0, 3) D2(0) LO1 D3(0) - HI1 D1(0) QLO2(b0, 2) D2(0) LO1 D3(0) - HI1 D1(0) QLO2(b0, 1) D2(0) LO1 D3(0) - HI1 D1(0) QLO2(b0, 0) D2(0) LO1 D3(0) - HI1 D1(0) QLO2(b1, 7) LD2(b2,O2) D2(2) LO1 D3(0) - HI1 D1(0) QLO2(b1, 6) D2(0) LO1 D3(0) - HI1 D1(0) QLO2(b1, 5) D2(0) LO1 D3(0) - HI1 D1(0) QLO2(b1, 4) D2(0) LO1 D3(0) - HI1 D1(0) QLO2(b1, 3) D2(0) LO1 D3(0) - HI1 D1(0) QLO2(b1, 2) D2(0) LO1 D3(0) - HI1 D1(0) QLO2(b1, 1) D2(0) LO1 D3(0) - HI1 D1(0) QLO2(b1, 0) IDATA2 D2(2) LO1 D3(0) - HI1 D1(0) QLO2(b2, 7) LD2(b0,O0) D2(2) LO1 D3(0) - HI1 D1(0) QLO2(b2, 6) D2(0) LO1 D3(0) - HI1 D1(0) QLO2(b2, 5) D2(0) LO1 D3(0) - HI1 D1(0) QLO2(b2, 4) D2(0) LO1 D3(0) - HI1 D1(0) QLO2(b2, 3) D2(0) LO1 D3(0) - HI1 D1(0) QLO2(b2, 2) D2(0) LO1 D3(0) - HI1 D1(0) QLO2(b2, 1) D2(0) LO1 D3(0) - HI1 D1(0) QLO2(b2, 0) DCOUNT2 BRLOOP1 D2(3) LO1 D3(2) JMPLOOP2 + HI1 D1(1) QLO2(b0, 7) LD2(b1,O1) D2(2) LO1 D3(0) + HI1 D1(1) QLO2(b0, 6) D2(0) LO1 D3(0) + HI1 D1(1) QLO2(b0, 5) D2(0) LO1 D3(0) + HI1 D1(1) QLO2(b0, 4) D2(0) LO1 D3(0) + HI1 D1(1) QLO2(b0, 3) D2(0) LO1 D3(0) + HI1 D1(1) QLO2(b0, 2) D2(0) LO1 D3(0) + HI1 D1(1) QLO2(b0, 1) D2(0) LO1 D3(0) + HI1 D1(1) QLO2(b0, 0) D2(0) LO1 D3(0) + HI1 D1(1) QLO2(b1, 7) LD2(b2,O2) D2(2) LO1 D3(0) + HI1 D1(1) QLO2(b1, 6) D2(0) LO1 D3(0) + HI1 D1(1) QLO2(b1, 5) D2(0) LO1 D3(0) + HI1 D1(1) QLO2(b1, 4) D2(0) LO1 D3(0) + HI1 D1(1) QLO2(b1, 3) D2(0) LO1 D3(0) + HI1 D1(1) QLO2(b1, 2) D2(0) LO1 D3(0) + HI1 D1(1) QLO2(b1, 1) D2(0) LO1 D3(0) + HI1 D1(1) QLO2(b1, 0) IDATA2 D2(2) LO1 D3(0) + HI1 D1(1) QLO2(b2, 7) LD2(b0,O0) D2(2) LO1 D3(0) + HI1 D1(1) QLO2(b2, 6) D2(0) LO1 D3(0) + HI1 D1(1) QLO2(b2, 5) D2(0) LO1 D3(0) + HI1 D1(1) QLO2(b2, 4) D2(0) LO1 D3(0) + HI1 D1(1) QLO2(b2, 3) D2(0) LO1 D3(0) + HI1 D1(1) QLO2(b2, 2) D2(0) LO1 D3(0) + HI1 D1(1) QLO2(b2, 1) D2(0) LO1 D3(0) + HI1 D1(1) QLO2(b2, 0) DCOUNT2 BRLOOP1 D2(3) LO1 D3(2) JMPLOOP2 #endif DONE D2(4) LO1 D3(0) } } + + // save the d values + d[0] = d0; + d[1] = d1; + d[2] = d2; } #ifdef SUPPORT_ARGB -- cgit v1.2.3 From 4ff103d94afcc33afc389dcd31537f15b98ae64a Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Tue, 18 Feb 2014 20:37:09 -0800 Subject: The moon. The mother fucking moon. Working dithering, RGB adjust, inline scale8_video on an 8Mhz, hardware-mul-less -trinket- --- FastLED.h | 4 ++ clockless_trinket.h | 111 +++++++++++++++++++++------------ examples/Cylon/Cylon.ino | 4 +- examples/RGBCalibrate/RGBCalibrate.ino | 15 ++--- lib8tion.h | 84 ++++++++++++++----------- 5 files changed, 134 insertions(+), 84 deletions(-) diff --git a/FastLED.h b/FastLED.h index 08f747b8..e735feca 100644 --- a/FastLED.h +++ b/FastLED.h @@ -38,7 +38,11 @@ enum EBlockChipsets { WS2811_PORTC }; +#if defined(LIB8_ATTINY) +#define NUM_CONTROLLERS 2 +#else #define NUM_CONTROLLERS 32 +#endif class CFastLED { struct CControllerInfo { diff --git a/clockless_trinket.h b/clockless_trinket.h index 45eea2de..52831296 100644 --- a/clockless_trinket.h +++ b/clockless_trinket.h @@ -11,6 +11,10 @@ // Scaling macro choice #ifndef TRINKET_SCALE #define TRINKET_SCALE 1 +// whether or not to use dithering +#define DITHER 1 +// whether or not to enable scale_video adjustments +#define SCALE_VIDEO 1 #endif // Variations on the functions in delay.h - w/a loop var passed in to preserve registers across calls by the optimizer/compiler @@ -87,11 +91,13 @@ public: } #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 */ \ - [b0] "+r" (b0), \ - [b1] "+r" (b1), \ - [b2] "+r" (b2), \ + [b0] "+a" (b0), \ + [b1] "+a" (b1), \ + [b2] "+a" (b2), \ [count] "+x" (count), \ [scale_base] "+a" (scale_base), \ [data] "+z" (data), \ @@ -106,7 +112,10 @@ public: [d0] "r" (d0), \ [d1] "r" (d1), \ [d2] "r" (d2), \ - [PORT] "M" (FastPin::port()-0x20), \ + [e0] "r" (e0), \ + [e1] "r" (e1), \ + [e2] "r" (e2), \ + [PORT] "M" (FastPin::port()-0x20), \ [O0] "M" (RGB_BYTE0(RGB_ORDER)), \ [O1] "M" (RGB_BYTE1(RGB_ORDER)), \ [O2] "M" (RGB_BYTE2(RGB_ORDER)) \ @@ -114,27 +123,31 @@ public: // 1 cycle, write hi to the port -#define HI1 asm __volatile__("out 0x02, %[hi]" ASM_VARS ); +#define HI1 asm __volatile__("out %[PORT], %[hi]" ASM_VARS ); // 1 cycle, write lo to the port -#define LO1 asm __volatile__("out 0x02, %[lo]" ASM_VARS ); +#define LO1 asm __volatile__("out %[PORT], %[lo]" ASM_VARS ); // 2 cycles, sbrs on flipping the lne 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 "]" ASM_VARS ); // 3 cycles - load a byte from ram into the scaling scratch space with the given offset, clear the target var #define LDSCL3(B,O) asm __volatile__("ldd %[scale_base], Z + %[" #O "]\n\tclr %[" #B "]" ASM_VARS ); -// 2 cycles - increment the data pointer -#define IDATA2 asm __volatile__("add %A[data], %A[ADV]\n\tadc %B[data], %B[ADV]" 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__("breq 2f" ASM_VARS ); // 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) asm __volatile__("sbrc %[s0], " #N "\n\tadd %[" #B "], %[scale_base]" ASM_VARS ); #define SCALE12(B, N) asm __volatile__("sbrc %[s1], " #N "\n\tadd %[" #B "], %[scale_base]" ASM_VARS ); #define SCALE22(B, N) asm __volatile__("sbrc %[s2], " #N "\n\tadd %[" #B "], %[scale_base]" ASM_VARS ); + +// apply dithering value before we do anything with scale_base +#define PRESCALE4(D) if(DITHER) { 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); } \ + else { _dc<4>(loopvar); } + +// Do a (rough) approximation of the nscale8_video jump +#if (SCALE_VIDEO == 1) +#define VIDADJ2(B) asm __volatile__("cpse %[scale_base], __zero_reg__\n\tsubi %[" #B "], 0xFF\n\t" ASM_VARS); +#else +#define VIDADJ2(B) asm __volatile__("rjmp .+0" ASM_VARS); +#endif + // 1 cycle - rotate right, pulling in from carry #define ROR1(B) asm __volatile__("ror %[" #B "]" ASM_VARS ); // 1 cycle, clear the carry bit @@ -149,18 +162,32 @@ public: #define SCROR04(B, N) SCALE02(B,N) ROR1(B) CLC1 #define SCROR14(B, N) SCALE12(B,N) ROR1(B) CLC1 #define SCROR24(B, N) SCALE22(B,N) ROR1(B) CLC1 + +///////////////////////////////////////////////////////////////////////////////////// +// Loop life cycle + +// #define ADJUST_DITHER d0 += DADVANCE; d1 += DADVANCE; d2 += DADVANCE; d0 &= e0; d1 &= e1; d2 &= d2; +#define ADJDITHER2(D, E) D += DADVANCE; D &= E; +// #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 ); d0 += DADVANCE; d1 += DADVANCE; d2 += DADVANCE; d0 &= e0; d1 &= e1; d2 &= d2; +#define LOOP asm __volatile__("1:" ASM_VARS ); +// define the end of the loop #define DONE asm __volatile__("2:" ASM_VARS ); -// delay time + +// 2 cycles - increment the data pointer +#define IDATA2 asm __volatile__("add %A[data], %A[ADV]\n\tadc %B[data], %B[ADV]" 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__("breq 2f" ASM_VARS ); + #define DADVANCE 3 -#define DITHER 1 -#define PRESCALE0_4() if(DITHER) { asm __volatile__("cpse %[scale_base], r1\n\t add %[scale_base],%[d0]\n\tbrcc L_%=\n\tldi %[scale_base], 0xFF\n\tL_%=:\n\t" ASM_VARS); } \ - else { _dc<4>(loopvar); } -#define PRESCALE1_4() if(DITHER) { asm __volatile__("cpse %[scale_base], r1\n\t add %[scale_base],%[d1]\n\tbrcc L_%=\n\tldi %[scale_base], 0xFF\n\tL_%=:\n\t" ASM_VARS); } \ - else { _dc<4>(loopvar); } -#define PRESCALE2_4() if(DITHER) { asm __volatile__("cpse %[scale_base], r1\n\t add %[scale_base],%[d2]\n\tbrcc L_%=\n\tldi %[scale_base], 0xFF\n\tL_%=:\n\t" ASM_VARS); } \ - else { _dc<4>(loopvar); } +#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. @@ -173,8 +200,8 @@ public: data_t lo = *port & ~mask; *port = lo; - uint8_t d0, d1, d2; - uint8_t e0, e1, e2; + register uint8_t d0, d1, d2; + register uint8_t e0, e1, e2; uint8_t s0, s1, s2; uint8_t b0, b1, b2; static uint8_t d[3] = {0,0,0}; @@ -182,6 +209,7 @@ public: uint16_t count = nLeds; uint8_t scale_base = 0; uint16_t advanceBy = advance ? (skip+3) : 0; + // uint8_t dadv = DADVANCE; // initialize the scales s0 = scale.raw[B0]; @@ -190,24 +218,29 @@ public: // initialize the e & d values uint8_t S; - S = s0; e0 = 0xFF; while(s0 >>= 1) { e0 >>= 1; } + S = s0; e0 = 0xFF; while(S >>= 1) { e0 >>= 1; } d0 = d[0] & e0; - S = s1; e1 = 0xFF; while(s1 >>= 1) { e1 >>= 1; } + S = s1; e1 = 0xFF; while(S >>= 1) { e1 >>= 1; } d1 = d[1] & e1; - S = s2; e2 = 0xFF; while(s2 >>= 1) { e2 >>= 1; } + S = s2; e2 = 0xFF; while(S >>= 1) { e2 >>= 1; } d2 = d[2] & e0; b0 = data[RGB_BYTE0(RGB_ORDER)]; if(DITHER && b0) { b0 = qadd8(b0, d0); } - b0 = scale8(b0, scale); + b0 = scale8_video(b0, s0); b1 = 0; b2 = 0; register uint8_t loopvar=0; { { - /* asm */ - LOOP + // Loop beginning, does some stuff that's outside of the pixel write cycle, namely incrementing d0-2 and masking off + // by the E values (see the definition ) + LOOP; + ADJDITHER2(d0,e0) + ADJDITHER2(d1,e1) + ADJDITHER2(d2,e2) + VIDADJ2(b0); // 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. @@ -219,23 +252,23 @@ public: #if TRINKET_SCALE // Inline scaling - RGB ordering HI1 D1(1) QLO2(b0, 7) LDSCL3(b1,O1) D2(3) LO1 D3(0) - HI1 D1(1) QLO2(b0, 6) PRESCALE1_4() D2(4) LO1 SCALE12(b1,0) D3(2) + HI1 D1(1) QLO2(b0, 6) PRESCALE4(d1) D2(4) LO1 SCALE12(b1,0) D3(2) HI1 D1(1) QLO2(b0, 5) RORSC14(b1,1) D2(4) LO1 ROR1(b1) CLC1 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 ROR1(b1) CLC1 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 ROR1(b1) CLC1 D3(2) - HI1 D1(1) QLO2(b0, 0) D2(0) LO1 D3(0) - HI1 D1(1) QLO2(b1, 7) LDSCL3(b2,O1) D2(3) LO1 D3(0) - HI1 D1(1) QLO2(b1, 6) PRESCALE2_4() D2(4) LO1 SCALE22(b2,0) D3(2) + HI1 D1(1) QLO2(b0, 0) D2(0) LO1 VIDADJ2(b1) D3(2) + HI1 D1(1) QLO2(b1, 7) LDSCL3(b2,O2) D2(3) LO1 D3(0) + HI1 D1(1) QLO2(b1, 6) PRESCALE4(d2) D2(4) LO1 SCALE22(b2,0) D3(2) HI1 D1(1) QLO2(b1, 5) RORSC24(b2,1) D2(4) LO1 ROR1(b2) CLC1 D3(2) HI1 D1(1) QLO2(b1, 4) SCROR24(b2,2) D2(4) LO1 SCALE22(b2,3) D3(2) HI1 D1(1) QLO2(b1, 3) RORSC24(b2,4) D2(4) LO1 ROR1(b2) CLC1 D3(2) HI1 D1(1) QLO2(b1, 2) SCROR24(b2,5) D2(4) LO1 SCALE22(b2,6) D3(2) HI1 D1(1) QLO2(b1, 1) RORSC24(b2,7) D2(4) LO1 ROR1(b2) CLC1 D3(2) - HI1 D1(1) QLO2(b1, 0) IDATA2 D2(2) LO1 D3(0) - HI1 D1(1) QLO2(b2, 7) LDSCL3(b2,O1) D2(3) LO1 D3(0) - HI1 D1(1) QLO2(b2, 6) PRESCALE0_4() D2(4) LO1 SCALE22(b0,0) D3(2) + HI1 D1(1) QLO2(b1, 0) IDATA2 D2(2) LO1 VIDADJ2(b2) D3(0) + HI1 D1(1) QLO2(b2, 7) LDSCL3(b0,O0) D2(3) LO1 D3(0) + HI1 D1(1) QLO2(b2, 6) PRESCALE4(d0) D2(4) LO1 SCALE22(b0,0) D3(2) HI1 D1(1) QLO2(b2, 5) RORSC04(b0,1) D2(4) LO1 ROR1(b0) CLC1 D3(2) HI1 D1(1) QLO2(b2, 4) SCROR04(b0,2) D2(4) LO1 SCALE02(b0,3) D3(2) HI1 D1(1) QLO2(b2, 3) RORSC04(b0,4) D2(4) LO1 ROR1(b0) CLC1 D3(2) diff --git a/examples/Cylon/Cylon.ino b/examples/Cylon/Cylon.ino index 8d133da2..57a3117e 100644 --- a/examples/Cylon/Cylon.ino +++ b/examples/Cylon/Cylon.ino @@ -1,12 +1,12 @@ #include "FastLED.h" // How many leds in your strip? -#define NUM_LEDS 6 +#define NUM_LEDS 32 // For led chips like Neopixels, which have a data line, ground, and power, you just // need to define DATA_PIN. For led chipsets that are SPI based (four wires - data, clock, // ground, and power), like the LPD8806, define both DATA_PIN and CLOCK_PIN -#define DATA_PIN 11 +#define DATA_PIN 3 #define CLOCK_PIN 13 // Define the array of leds diff --git a/examples/RGBCalibrate/RGBCalibrate.ino b/examples/RGBCalibrate/RGBCalibrate.ino index a8af8fc8..e37560c4 100644 --- a/examples/RGBCalibrate/RGBCalibrate.ino +++ b/examples/RGBCalibrate/RGBCalibrate.ino @@ -26,7 +26,7 @@ #define NUM_LEDS 6 // Data pin that led data will be written out over -#define DATA_PIN 6 +#define DATA_PIN 3 // Clock pin only needed for SPI based chipsets when not using hardware SPI //#define CLOCK_PIN 8 @@ -43,6 +43,7 @@ void setup() { // FastLED.addLeds(leds, NUM_LEDS); // FastLED.addLeds(leds, NUM_LEDS); FastLED.addLeds(leds, NUM_LEDS); + FastLED.setBrightness(CRGB(16,16,16)); // FastLED.addLeds(leds, NUM_LEDS); // FastLED.addLeds(leds, NUM_LEDS); // FastLED.addLeds(leds, NUM_LEDS); @@ -58,12 +59,12 @@ void setup() { } void loop() { - leds[0] = CRGB::Red; - leds[1] = CRGB::Green; - leds[2] = CRGB::Green; - leds[3] = CRGB::Blue; - leds[4] = CRGB::Blue; - leds[5] = CRGB::Blue; + leds[0] = CRGB(255,0,0); + leds[1] = CRGB(0,255,0); + leds[2] = CRGB(0,255,0); + leds[3] = CRGB(0,0,255); + leds[4] = CRGB(0,0,255); + leds[5] = CRGB(0,0,255); FastLED.show(); // delay(1000); } diff --git a/lib8tion.h b/lib8tion.h index 2ccd7601..f94ec9f0 100644 --- a/lib8tion.h +++ b/lib8tion.h @@ -464,23 +464,34 @@ LIB8STATIC uint8_t scale8_video( uint8_t i, fract8 scale) uint8_t j = (i == 0) ? 0 : (((int)i * (int)(scale) ) >> 8) + nonzeroscale; return j; #elif SCALE8_AVRASM == 1 - - uint8_t nonzeroscale = (scale != 0) ? 1 : 0; + uint8_t j; asm volatile( - " tst %0 \n" - " breq L_%= \n" - " mul %0, %1 \n" - " mov %0, r1 \n" - " add %0, %2 \n" - " clr __zero_reg__ \n" - "L_%=: \n" + "mul %[i], %[scale]\n\t" + "mov %[j], r1\n\t" + "clr __zero_reg__\n\t" + "cpse %[i], r1\n\t" + "addi %[j], 1\n\t" + : "+a" (j) + : "a" (i), "a" (scale) + : "r0", "r1"); + + return j; + // uint8_t nonzeroscale = (scale != 0) ? 1 : 0; + // asm volatile( + // " tst %0 \n" + // " breq L_%= \n" + // " mul %0, %1 \n" + // " mov %0, r1 \n" + // " add %0, %2 \n" + // " clr __zero_reg__ \n" + // "L_%=: \n" - : "+a" (i) - : "a" (scale), "a" (nonzeroscale) - : "r0", "r1"); + // : "+a" (i) + // : "a" (scale), "a" (nonzeroscale) + // : "r0", "r1"); - // Return the result - return i; + // // Return the result + // return i; #else #error "No implementation for scale8_video available." #endif @@ -541,31 +552,32 @@ LIB8STATIC void nscale8_LEAVING_R1_DIRTY( uint8_t& i, fract8 scale) LIB8STATIC uint8_t scale8_video_LEAVING_R1_DIRTY( uint8_t i, fract8 scale) { -#if SCALE8_C == 1 - uint8_t nonzeroscale = (scale != 0) ? 1 : 0; - uint8_t j = (i == 0) ? 0 : (((int)i * (int)(scale) ) >> 8) + nonzeroscale; - return j; -#elif SCALE8_AVRASM == 1 + return scale8_video(i,scale); +// #if SCALE8_C == 1 +// uint8_t nonzeroscale = (scale != 0) ? 1 : 0; +// uint8_t j = (i == 0) ? 0 : (((int)i * (int)(scale) ) >> 8) + nonzeroscale; +// return j; +// #elif SCALE8_AVRASM == 1 - uint8_t nonzeroscale = (scale != 0) ? 1 : 0; - asm volatile( - " tst %0 \n" - " breq L_%= \n" - " mul %0, %1 \n" - " mov %0, r1 \n" - " add %0, %2 \n" - /* R1 IS LEFT DIRTY, YOU MUST ZERO IT OUT YOURSELF */ - "L_%=: \n" +// uint8_t nonzeroscale = (scale != 0) ? 1 : 0; +// asm volatile( +// " tst %0 \n" +// " breq L_%= \n" +// " mul %0, %1 \n" +// " mov %0, r1 \n" +// " add %0, %2 \n" +// /* R1 IS LEFT DIRTY, YOU MUST ZERO IT OUT YOURSELF */ +// "L_%=: \n" - : "+a" (i) - : "a" (scale), "a" (nonzeroscale) - : "r0", "r1"); +// : "+a" (i) +// : "a" (scale), "a" (nonzeroscale) +// : "r0", "r1"); - // Return the result - return i; -#else -#error "No implementation for scale8_video available." -#endif +// // Return the result +// return i; +// #else +// #error "No implementation for scale8_video available." +// #endif } -- cgit v1.2.3 From e393d6996476a5032cc2cc1e4a27da9843c7f602 Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Tue, 18 Feb 2014 22:00:56 -0800 Subject: Fixing regular AVR build, flipping all AVR code over to using the clockless_trinket code. Dithering and RGB brightness control for everyone --- chipsets.h | 39 ++++++++++++++++++++++++--------------- clockless.h | 2 +- clockless_arm_sam.h | 48 +++++++++++++++++++++++++----------------------- clockless_trinket.h | 10 ++++++++-- lib8tion.h | 6 +++--- 5 files changed, 61 insertions(+), 44 deletions(-) diff --git a/chipsets.h b/chipsets.h index a7f61184..65c6b144 100644 --- a/chipsets.h +++ b/chipsets.h @@ -297,49 +297,49 @@ public: // We want to force all avr's to use the Trinket controller when running at 8Mhz, because even the 328's at 8Mhz // need the more tightly defined timeframes. -#if (defined(LIB8_ATTINY) || defined(FASTLED_AVR)) && (F_CPU == 8000000) // 125ns/clock +#if defined(FASTLED_AVR) && (F_CPU == 8000000) // 125ns/clock // WS2811@8Mhz 2 clocks, 5 clocks, 3 clocks template -class WS2811Controller800Khz : public ClocklessController_Trinket {}; +class WS2811Controller800Khz : public ClocklessController {}; template -class WS2811Controller400Khz : public ClocklessController_Trinket {}; +class WS2811Controller400Khz : public ClocklessController {}; template -class UCS1903Controller400Khz : public ClocklessController_Trinket {}; +class UCS1903Controller400Khz : public ClocklessController {}; template -class UCS1903BController800Khz : public ClocklessController_Trinket {}; +class UCS1903BController800Khz : public ClocklessController {}; template -class TM1809Controller800Khz : public ClocklessController_Trinket {}; +class TM1809Controller800Khz : public ClocklessController {}; template -class TM1803Controller400Khz : public ClocklessController_Trinket {}; +class TM1803Controller400Khz : public ClocklessController {}; template -class TM1829Controller800Khz : public ClocklessController_Trinket {}; +class TM1829Controller800Khz : public ClocklessController {}; template -class GW6205Controller400Khz : public ClocklessController_Trinket {}; +class GW6205Controller400Khz : public ClocklessController {}; template -class GW6205Controller800Khz : public ClocklessController_Trinket {}; +class GW6205Controller800Khz : public ClocklessController {}; -#elif defined(LIB8_ATTINY) && (F_CPU == 16000000) // 62.5ns/clock +#elif defined(FASTLED_AVR) && (F_CPU == 16000000) // 62.5ns/clock // WS2811@16Mhz 4 clocks, 10 clocks, 6 clocks template -class WS2811Controller800Khz : public ClocklessController_Trinket {}; +class WS2811Controller800Khz : public ClocklessController {}; template -class WS2811Controller400Khz : public ClocklessController_Trinket {}; +class WS2811Controller400Khz : public ClocklessController {}; template -class UCS1903Controller400Khz : public ClocklessController_Trinket {}; +class UCS1903Controller400Khz : public ClocklessController {}; template -class UCS1903BController800Khz : public ClocklessController_Trinket {}; +class UCS1903BController800Khz : public ClocklessController {}; template class TM1809Controller800Khz : public ClocklessController {}; @@ -347,6 +347,15 @@ class TM1809Controller800Khz : public ClocklessController class TM1803Controller400Khz : public ClocklessController {}; +template +class TM1829Controller800Khz : public ClocklessController {}; + +template +class GW6205Controller400Khz : public ClocklessController {}; + +template +class GW6205Controller800Khz : public ClocklessController {}; + #else // GW6205@400khz - 800ns, 800ns, 800ns template diff --git a/clockless.h b/clockless.h index 65fe18e4..b3fabbc5 100644 --- a/clockless.h +++ b/clockless.h @@ -18,7 +18,7 @@ #define SET_LO FLIP ? FastPin::fastset(port, hi) : FastPin::fastset(port, lo); #define SET_HI FLIP ? FastPin::fastset(port, lo) : FastPin::fastset(port, hi); -#include "clockless_avr.h" +// #include "clockless_avr.h" #include "clockless_trinket.h" #include "clockless_arm_k20.h" #include "clockless_arm_sam.h" diff --git a/clockless_arm_sam.h b/clockless_arm_sam.h index 7eb37698..3ce29bcb 100644 --- a/clockless_arm_sam.h +++ b/clockless_arm_sam.h @@ -6,6 +6,13 @@ #if defined(__SAM3X8E__) +#define TOTAL ( (T1+2) + (T2+2) + (T3+2) ) +#define T1_MARK (TOTAL - (T1+2)) +#define T2_MARK (T1_MARK - (T2+2)) + +#define SCALE(S,V) scale8_video(S,V) +// #define SCALE(S,V) scale8(S,V) + template class ClocklessController : public CLEDController { typedef typename FastPinBB::port_ptr_t data_ptr_t; @@ -29,12 +36,12 @@ public: virtual void showColor(const struct CRGB & data, int nLeds, CRGB scale = CRGB::White) { mWait.wait(); cli(); - SysClockSaver savedClock(T1 + T2 + T3); + SysClockSaver savedClock(TOTAL); showRGBInternal<0, false>(nLeds, scale, (const byte*)&data); // Adjust the timer - long microsTaken = CLKS_TO_MICROS((long)nLeds * 8 * (T1 + T2 + T3)); + long microsTaken = CLKS_TO_MICROS((long)nLeds * 8 * (TOTAL)); long millisTaken = (microsTaken / 1000); savedClock.restore(); do { TimeTick_Increment(); } while(--millisTaken > 0); @@ -45,17 +52,17 @@ public: virtual void show(const struct CRGB *rgbdata, int nLeds, CRGB scale = CRGB::White) { mWait.wait(); cli(); - SysClockSaver savedClock(T1 + T2 + T3); + SysClockSaver savedClock(TOTAL); - Serial.print("Scale is "); - Serial.print(scale.raw[0]); Serial.print(" "); - Serial.print(scale.raw[1]); Serial.print(" "); - Serial.print(scale.raw[2]); Serial.println(" "); + // Serial.print("Scale is "); + // Serial.print(scale.raw[0]); Serial.print(" "); + // Serial.print(scale.raw[1]); Serial.print(" "); + // Serial.print(scale.raw[2]); Serial.println(" "); // FastPinBB::hi(); delay(1); FastPinBB::lo(); showRGBInternal<0, true>(nLeds, scale, (const byte*)rgbdata); // Adjust the timer - long microsTaken = CLKS_TO_MICROS((long)nLeds * 8 * (T1 + T2 + T3)); + long microsTaken = CLKS_TO_MICROS((long)nLeds * 8 * (TOTAL)); long millisTaken = (microsTaken / 1000); savedClock.restore(); do { TimeTick_Increment(); } while(--millisTaken > 0); @@ -67,12 +74,12 @@ public: virtual void show(const struct CARGB *rgbdata, int nLeds, CRGB scale = CRGB::White) { mWait.wait(); cli(); - SysClockSaver savedClock(T1 + T2 + T3); + SysClockSaver savedClock(TOTAL); showRGBInternal<1, true>(nLeds, scale, (const byte*)rgbdata); // Adjust the timer - long microsTaken = CLKS_TO_MICROS((long)nLeds * 8 * (T1 + T2 + T3)); + long microsTaken = CLKS_TO_MICROS((long)nLeds * 8 * (TOTAL)); long millisTaken = (microsTaken / 1000); savedClock.restore(); do { TimeTick_Increment(); } while(--millisTaken > 0); @@ -126,10 +133,7 @@ public: //#define AT_MARK(X) delayclocks_until(_VAL); X; //#define AT_END(X) delayclocks_until(_VAL); X; -#define TOTAL (T1 + T2 + T3) -#define T1_MARK (TOTAL - T1) -#define T2_MARK (T1_MARK - T2) template __attribute__((always_inline)) static inline void delayclocks_until(register byte b) { __asm__ __volatile__ ( " sub %0, %0, %1\n" @@ -172,7 +176,7 @@ public: // dither if(DITHER && b) b = qadd8(b, D[B0]); // now scale - b = scale8(b, scale.raw[B0]); + b = SCALE(b, scale.raw[B0]); // Setup and start the clock _LOAD = TOTAL; @@ -199,13 +203,13 @@ public: AT_BIT_START(*port = 1); if(b& 0x80) {} else { AT_MARK(*port = 0); } + b = ADVANCE ? data[SKIP + B1] : rgbdata[SKIP + B1]; AT_END(*port = 0); - b = ADVANCE ? data[SKIP + B1] : rgbdata[SKIP + B1]; // dither if(DITHER && b) b = qadd8(b, D[B1]); // now scale - b = scale8(b, scale.raw[B1]); + b = SCALE(b, scale.raw[B1]); for(register uint32_t i = 7; i > 0; i--) { AT_BIT_START(*port = 1); @@ -216,13 +220,13 @@ public: AT_BIT_START(*port = 1); if(b& 0x80) {} else { AT_MARK(*port = 0); } + b = ADVANCE ? data[SKIP + B2] : rgbdata[SKIP + B2]; AT_END(*port = 0); - b = ADVANCE ? data[SKIP + B2] : rgbdata[SKIP + B2]; // dither if(DITHER && b) b = qadd8(b, D[B2]); // now scale - b = scale8(b, scale.raw[B2]); + b = SCALE(b, scale.raw[B2]); for(register uint32_t i = 7; i > 0; i--) { AT_BIT_START(*port = 1); @@ -233,16 +237,14 @@ public: AT_BIT_START(*port = 1); if(b& 0x80) {} else { AT_MARK(*port = 0); } - AT_END(*port = 0); - - // We have some extra time between rgb pixels, prep - // the next byte and cycle the dither adjustments data += (3 + SKIP); b = ADVANCE ? data[SKIP + B0] : rgbdata[SKIP + B0]; + AT_END(*port = 0); + // dither if(DITHER && b) b = qadd8(b, D[B0]); // now scale - b = scale8(b, scale.raw[B0]); + b = SCALE(b, scale.raw[B0]); }; // Save the D values for cycling through next time diff --git a/clockless_trinket.h b/clockless_trinket.h index 52831296..fe628aa6 100644 --- a/clockless_trinket.h +++ b/clockless_trinket.h @@ -6,7 +6,7 @@ #include "delay.h" #include // for cli/se definitions -#if defined(LIB8_ATTINY) +#if defined(FASTLED_AVR) // Scaling macro choice #ifndef TRINKET_SCALE @@ -32,6 +32,12 @@ template __attribute__((always_inline)) inline void _dc(register uin template<> __attribute__((always_inline)) inline void _dc<0>(register uint8_t & loopvar) {} template<> __attribute__((always_inline)) inline void _dc<1>(register uint8_t & loopvar) {asm __volatile__("cp r0,r0":::);} template<> __attribute__((always_inline)) inline void _dc<2>(register uint8_t & loopvar) {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); } #define D1(ADJ) _dc(loopvar); #define D2(ADJ) _dc(loopvar); @@ -46,7 +52,7 @@ template<> __attribute__((always_inline)) inline void _dc<2>(register uint8_t & ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// template -class ClocklessController_Trinket : public CLEDController { +class ClocklessController : public CLEDController { typedef typename FastPin::port_ptr_t data_ptr_t; typedef typename FastPin::port_t data_t; diff --git a/lib8tion.h b/lib8tion.h index f94ec9f0..d873948a 100644 --- a/lib8tion.h +++ b/lib8tion.h @@ -470,9 +470,9 @@ LIB8STATIC uint8_t scale8_video( uint8_t i, fract8 scale) "mov %[j], r1\n\t" "clr __zero_reg__\n\t" "cpse %[i], r1\n\t" - "addi %[j], 1\n\t" - : "+a" (j) - : "a" (i), "a" (scale) + "subi %[j], 0xFF\n\t" + : [j] "+a" (j) + : [i] "a" (i), [scale] "a" (scale) : "r0", "r1"); return j; -- cgit v1.2.3 From c7c6210fd43a742c96fcf515568469e89bac4c02 Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Wed, 19 Feb 2014 03:48:00 -0800 Subject: Dithering, rgb balance, video scaling code put into k20 code --- FastLED.h | 2 +- clockless_arm_k20.h | 87 +++++++++++++++++++++------------- delay.h | 2 +- examples/RGBCalibrate/RGBCalibrate.ino | 4 +- led_sysdefs.h | 2 +- 5 files changed, 58 insertions(+), 39 deletions(-) diff --git a/FastLED.h b/FastLED.h index e735feca..78bb77c7 100644 --- a/FastLED.h +++ b/FastLED.h @@ -41,7 +41,7 @@ enum EBlockChipsets { #if defined(LIB8_ATTINY) #define NUM_CONTROLLERS 2 #else -#define NUM_CONTROLLERS 32 +#define NUM_CONTROLLERS 8 #endif class CFastLED { diff --git a/clockless_arm_k20.h b/clockless_arm_k20.h index a0cf0998..7cd333da 100644 --- a/clockless_arm_k20.h +++ b/clockless_arm_k20.h @@ -4,7 +4,7 @@ // 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) -template +template class ClocklessController : public CLEDController { typedef typename FastPin::port_ptr_t data_ptr_t; typedef typename FastPin::port_t data_t; @@ -24,7 +24,7 @@ public: } // set all the leds on the controller to a given color - virtual void showColor(const struct CRGB & data, int nLeds, uint8_t scale = 255) { + virtual void showColor(const struct CRGB & data, int nLeds, CRGB scale = CRGB::White) { mWait.wait(); cli(); @@ -37,7 +37,7 @@ public: mWait.mark(); } - virtual void show(const struct CRGB *rgbdata, int nLeds, uint8_t scale = 255) { + virtual void show(const struct CRGB *rgbdata, int nLeds, CRGB scale = CRGB::White) { mWait.wait(); cli(); @@ -51,7 +51,7 @@ public: } #ifdef SUPPORT_ARGB - virtual void show(const struct CARGB *rgbdata, int nLeds, uint8_t scale = 255) { + virtual void show(const struct CARGB *rgbdata, int nLeds, CRGB scale = CRGB::White) { mWait.wait(); cli(); @@ -65,31 +65,26 @@ public: } #endif - inline static void write8Bits(register data_ptr_t port, register data_t hi, register data_t lo, register uint32_t & b) __attribute__ ((always_inline)) { + inline static void write8Bits(register uint32_t & next_mark, register data_ptr_t port, register data_t hi, register data_t lo, register uint32_t & b) __attribute__ ((always_inline)) { // TODO: hand rig asm version of this method. The timings are based on adjusting/studying GCC compiler ouptut. This // will bite me in the ass at some point, I know it. - for(register uint32_t i = 7; i > 0; i--) { + for(register uint32_t i = 8; i > 0; i--) { + while(ARM_DWT_CYCCNT < next_mark); + next_mark = ARM_DWT_CYCCNT + (T1+T2+T3); FastPin::fastset(port, hi); - delaycycles(); // 5 cycles - 2 store, 1 and, 1 test, 1 if - if(b & 0x80) { FastPin::fastset(port, hi); } else { FastPin::fastset(port, lo); } + uint32_t flip_mark = next_mark - ((b&0x80) ? (T3) : (T2+T3)); b <<= 1; - delaycycles(); // 2 cycles, 1 store/skip, 1 shift + while(ARM_DWT_CYCCNT < flip_mark); FastPin::fastset(port, lo); - delaycycles(); // 3 cycles, 2 store, 1 sub, 1 branch backwards } - // delay an extra cycle because falling out of the loop takes on less cycle than looping around - delaycycles<1>(); - - FastPin::fastset(port, hi); - delaycycles(); - if(b & 0x80) { FastPin::fastset(port, hi); } else { FastPin::fastset(port, lo); } - delaycycles(); // 4 cycles, 2 store, store/skip - FastPin::fastset(port, lo); } +#define DITHER 1 +#define DADVANCE 3 + // 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. - template static void showRGBInternal(register int nLeds, register uint8_t scale, register const byte *rgbdata) { + template static void showRGBInternal(register int nLeds, register CRGB scale, register const byte *rgbdata) { register byte *data = (byte*)rgbdata; register data_t mask = FastPin::mask(); register data_ptr_t port = FastPin::port(); @@ -99,38 +94,62 @@ public: register data_t lo = *port & ~mask; *port = lo; + uint8_t E[3] = {0xFF,0xFF,0xFF}; + uint8_t D[3] = {0,0,0}; + + static uint8_t Dstore[3] = {0,0,0}; + + // compute the E values and seed D from the stored values + for(register uint32_t i = 0; i < 3; i++) { + byte S = scale.raw[i]; + while(S>>=1) { E[i] >>=1; }; + D[i] = Dstore[i] & E[i]; + } + + // Get access to the clock + ARM_DEMCR |= ARM_DEMCR_TRCENA; + ARM_DWT_CTRL |= ARM_DWT_CTRL_CYCCNTENA; + ARM_DWT_CYCCNT = 0; + register uint32_t b; b = ((ADVANCE)?data:rgbdata)[SKIP + RGB_BYTE0(RGB_ORDER)]; - b = scale8(b, scale); + if(DITHER && b) b = qadd8(b, D[B0]); + b = scale8(b, scale.raw[B0]); + + uint32_t next_mark = ARM_DWT_CYCCNT + (T1+T2+T3); while(data < end) { + // Write first byte, read next byte - write8Bits(port, hi, lo, b); + write8Bits(next_mark, port, hi, lo, b); + D[B0] += DADVANCE; D[B0] &= E[B0]; b = ((ADVANCE)?data:rgbdata)[SKIP + RGB_BYTE1(RGB_ORDER)]; - INLINE_SCALE(b, scale); - delaycycles(); // 1 store, 2 load, 1 mul, 1 shift, + if(DITHER && b) b = qadd8(b, D[B1]); + INLINE_SCALE(b, scale.raw[B1]); // Write second byte - write8Bits(port, hi, lo, b); + write8Bits(next_mark, port, hi, lo, b); + D[B1] += DADVANCE; D[B1] &= E[B1]; b = ((ADVANCE)?data:rgbdata)[SKIP + RGB_BYTE2(RGB_ORDER)]; - INLINE_SCALE(b, scale); + if(DITHER && b) b = qadd8(b, D[B2]); + INLINE_SCALE(b, scale.raw[B2]); data += 3 + SKIP; - if((RGB_ORDER & 0070) == 0) { - delaycycles(); // 1 store, 2 load, 1 mul, 1 shift, 1 adds if BRG or GRB - } else { - delaycycles(); // 1 store, 2 load, 1 mul, 1 shift, - } // Write third byte - write8Bits(port, hi, lo, b); + write8Bits(next_mark, port, hi, lo, b); + D[B2] += DADVANCE; D[B2] &= E[B2]; b = ((ADVANCE)?data:rgbdata)[SKIP + RGB_BYTE0(RGB_ORDER)]; - INLINE_SCALE(b, scale); - - delaycycles(); // 1 store, 2 load (with increment), 1 mul, 1 shift, 1 cmp, 1 branch backwards, 1 movim + if(DITHER && b) b = qadd8(b, D[B0]); + INLINE_SCALE(b, scale.raw[B0]); }; + + // Save the D values for cycling through next time + Dstore[0] = D[0]; + Dstore[1] = D[1]; + Dstore[2] = D[2]; } }; #endif diff --git a/delay.h b/delay.h index 7c7a50ea..923d96bd 100644 --- a/delay.h +++ b/delay.h @@ -83,7 +83,7 @@ template<> __attribute__((always_inline)) inline void delaycycles<5>() {NOP2;NOP // Macro to convert from nano-seconds to clocks and clocks to nano-seconds // #define NS(_NS) (_NS / (1000 / (F_CPU / 1000000L))) -#if F_CPU < 96000000 +#if 1 || (F_CPU < 96000000) #define NS(_NS) ( (_NS * (F_CPU / 1000000L))) / 1000 #define CLKS_TO_MICROS(_CLKS) ((long)(_CLKS)) / (F_CPU / 1000000L) #else diff --git a/examples/RGBCalibrate/RGBCalibrate.ino b/examples/RGBCalibrate/RGBCalibrate.ino index e37560c4..4adf7fbe 100644 --- a/examples/RGBCalibrate/RGBCalibrate.ino +++ b/examples/RGBCalibrate/RGBCalibrate.ino @@ -26,7 +26,7 @@ #define NUM_LEDS 6 // Data pin that led data will be written out over -#define DATA_PIN 3 +#define DATA_PIN 6 // Clock pin only needed for SPI based chipsets when not using hardware SPI //#define CLOCK_PIN 8 @@ -43,7 +43,7 @@ void setup() { // FastLED.addLeds(leds, NUM_LEDS); // FastLED.addLeds(leds, NUM_LEDS); FastLED.addLeds(leds, NUM_LEDS); - FastLED.setBrightness(CRGB(16,16,16)); + FastLED.setBrightness(CRGB(255,255,255)); // FastLED.addLeds(leds, NUM_LEDS); // FastLED.addLeds(leds, NUM_LEDS); // FastLED.addLeds(leds, NUM_LEDS); diff --git a/led_sysdefs.h b/led_sysdefs.h index adbd10b6..afcf6e1b 100644 --- a/led_sysdefs.h +++ b/led_sysdefs.h @@ -35,7 +35,7 @@ typedef volatile uint8_t RwReg; /**< Read-Write 8-bit register (volatile u # define INLINE_SCALE(B, SCALE) delaycycles<3>() # warning "No hardware multiply, inline brightness scaling disabled" #else -# define INLINE_SCALE(B, SCALE) B = scale8_LEAVING_R1_DIRTY(B, SCALE) +# define INLINE_SCALE(B, SCALE) B = scale8_video(B, SCALE) #endif #endif \ No newline at end of file -- cgit v1.2.3 From 6b0be7a772dbc49b22d82471bad7d1ff6f332cf3 Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Wed, 19 Feb 2014 04:07:14 -0800 Subject: small tweak --- clockless_arm_k20.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/clockless_arm_k20.h b/clockless_arm_k20.h index 7cd333da..610244b5 100644 --- a/clockless_arm_k20.h +++ b/clockless_arm_k20.h @@ -118,11 +118,13 @@ public: uint32_t next_mark = ARM_DWT_CYCCNT + (T1+T2+T3); while(data < end) { + D[B0] += DADVANCE; D[B0] &= E[B0]; + D[B1] += DADVANCE; D[B1] &= E[B1]; + D[B2] += DADVANCE; D[B2] &= E[B2]; // Write first byte, read next byte write8Bits(next_mark, port, hi, lo, b); - D[B0] += DADVANCE; D[B0] &= E[B0]; b = ((ADVANCE)?data:rgbdata)[SKIP + RGB_BYTE1(RGB_ORDER)]; if(DITHER && b) b = qadd8(b, D[B1]); INLINE_SCALE(b, scale.raw[B1]); @@ -130,7 +132,6 @@ public: // Write second byte write8Bits(next_mark, port, hi, lo, b); - D[B1] += DADVANCE; D[B1] &= E[B1]; b = ((ADVANCE)?data:rgbdata)[SKIP + RGB_BYTE2(RGB_ORDER)]; if(DITHER && b) b = qadd8(b, D[B2]); INLINE_SCALE(b, scale.raw[B2]); @@ -140,7 +141,6 @@ public: // Write third byte write8Bits(next_mark, port, hi, lo, b); - D[B2] += DADVANCE; D[B2] &= E[B2]; b = ((ADVANCE)?data:rgbdata)[SKIP + RGB_BYTE0(RGB_ORDER)]; if(DITHER && b) b = qadd8(b, D[B0]); INLINE_SCALE(b, scale.raw[B0]); -- cgit v1.2.3 From 9f33fb12b57d97f83801ae32ce4d7a3076868ea5 Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Wed, 19 Feb 2014 13:59:02 -0800 Subject: Some more teensy 3/3.1 work --- clockless_arm_k20.h | 2 +- lib8tion.h | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/clockless_arm_k20.h b/clockless_arm_k20.h index 610244b5..59dd3f51 100644 --- a/clockless_arm_k20.h +++ b/clockless_arm_k20.h @@ -110,13 +110,13 @@ public: ARM_DEMCR |= ARM_DEMCR_TRCENA; ARM_DWT_CTRL |= ARM_DWT_CTRL_CYCCNTENA; ARM_DWT_CYCCNT = 0; + uint32_t next_mark = ARM_DWT_CYCCNT + (T1+T2+T3); register uint32_t b; b = ((ADVANCE)?data:rgbdata)[SKIP + RGB_BYTE0(RGB_ORDER)]; if(DITHER && b) b = qadd8(b, D[B0]); b = scale8(b, scale.raw[B0]); - uint32_t next_mark = ARM_DWT_CYCCNT + (T1+T2+T3); while(data < end) { D[B0] += DADVANCE; D[B0] &= E[B0]; D[B1] += DADVANCE; D[B1] &= E[B1]; diff --git a/lib8tion.h b/lib8tion.h index d873948a..c8b84fda 100644 --- a/lib8tion.h +++ b/lib8tion.h @@ -460,8 +460,9 @@ LIB8STATIC uint8_t scale8( uint8_t i, fract8 scale) LIB8STATIC uint8_t scale8_video( uint8_t i, fract8 scale) { #if SCALE8_C == 1 - uint8_t nonzeroscale = (scale != 0) ? 1 : 0; - uint8_t j = (i == 0) ? 0 : (((int)i * (int)(scale) ) >> 8) + nonzeroscale; + uint8_t j = (((int)i * (int)scale) >> 8) + (i?1:0); + // uint8_t nonzeroscale = (scale != 0) ? 1 : 0; + // uint8_t j = (i == 0) ? 0 : (((int)i * (int)(scale) ) >> 8) + nonzeroscale; return j; #elif SCALE8_AVRASM == 1 uint8_t j; -- cgit v1.2.3 From e3c72c99ef84a7571f2f2b4b2e68384dab2d1b16 Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Wed, 19 Feb 2014 14:33:45 -0800 Subject: Courtesy of Paul's NeoPixel code, discovered the teensy's DWT_CYCCNT - switch the clockless code over to using that, should fix clockless code on the teensy 3.1 and complete teensy 3.1 code for us. --- clockless_arm_k20.h | 45 +++++++++++++++++---------------------------- delay.h | 2 +- 2 files changed, 18 insertions(+), 29 deletions(-) diff --git a/clockless_arm_k20.h b/clockless_arm_k20.h index a0cf0998..78569b3f 100644 --- a/clockless_arm_k20.h +++ b/clockless_arm_k20.h @@ -65,26 +65,16 @@ public: } #endif - inline static void write8Bits(register data_ptr_t port, register data_t hi, register data_t lo, register uint32_t & b) __attribute__ ((always_inline)) { - // TODO: hand rig asm version of this method. The timings are based on adjusting/studying GCC compiler ouptut. This - // will bite me in the ass at some point, I know it. - for(register uint32_t i = 7; i > 0; i--) { + inline static void write8Bits(register uint32_t & next_mark, register data_ptr_t port, register data_t hi, register data_t lo, register uint32_t & b) __attribute__ ((always_inline)) { + for(register uint32_t i = 8; i > 0; i--) { + while(ARM_DWT_CYCCNT < next_mark); + next_mark = ARM_DWT_CYCCNT + (T1+T2+T3); FastPin::fastset(port, hi); - delaycycles(); // 5 cycles - 2 store, 1 and, 1 test, 1 if - if(b & 0x80) { FastPin::fastset(port, hi); } else { FastPin::fastset(port, lo); } + uint32_t flip_mark = next_mark - ((b&0x80) ? (T3) : (T2+T3)); b <<= 1; - delaycycles(); // 2 cycles, 1 store/skip, 1 shift + while(ARM_DWT_CYCCNT < flip_mark); FastPin::fastset(port, lo); - delaycycles(); // 3 cycles, 2 store, 1 sub, 1 branch backwards } - // delay an extra cycle because falling out of the loop takes on less cycle than looping around - delaycycles<1>(); - - FastPin::fastset(port, hi); - delaycycles(); - if(b & 0x80) { FastPin::fastset(port, hi); } else { FastPin::fastset(port, lo); } - delaycycles(); // 4 cycles, 2 store, store/skip - FastPin::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 @@ -99,37 +89,36 @@ public: register data_t lo = *port & ~mask; *port = lo; + // Get access to the clock + ARM_DEMCR |= ARM_DEMCR_TRCENA; + ARM_DWT_CTRL |= ARM_DWT_CTRL_CYCCNTENA; + ARM_DWT_CYCCNT = 0; + uint32_t next_mark = ARM_DWT_CYCCNT + (T1+T2+T3); + register uint32_t b; b = ((ADVANCE)?data:rgbdata)[SKIP + RGB_BYTE0(RGB_ORDER)]; - b = scale8(b, scale); + INLINE_SCALE(b, scale); + while(data < end) { // Write first byte, read next byte - write8Bits(port, hi, lo, b); + write8Bits(next_mark, port, hi, lo, b); b = ((ADVANCE)?data:rgbdata)[SKIP + RGB_BYTE1(RGB_ORDER)]; INLINE_SCALE(b, scale); - delaycycles(); // 1 store, 2 load, 1 mul, 1 shift, // Write second byte - write8Bits(port, hi, lo, b); + write8Bits(next_mark, port, hi, lo, b); b = ((ADVANCE)?data:rgbdata)[SKIP + RGB_BYTE2(RGB_ORDER)]; INLINE_SCALE(b, scale); data += 3 + SKIP; - if((RGB_ORDER & 0070) == 0) { - delaycycles(); // 1 store, 2 load, 1 mul, 1 shift, 1 adds if BRG or GRB - } else { - delaycycles(); // 1 store, 2 load, 1 mul, 1 shift, - } // Write third byte - write8Bits(port, hi, lo, b); + write8Bits(next_mark, port, hi, lo, b); b = ((ADVANCE)?data:rgbdata)[SKIP + RGB_BYTE0(RGB_ORDER)]; INLINE_SCALE(b, scale); - - delaycycles(); // 1 store, 2 load (with increment), 1 mul, 1 shift, 1 cmp, 1 branch backwards, 1 movim }; } }; diff --git a/delay.h b/delay.h index 7c7a50ea..d92da697 100644 --- a/delay.h +++ b/delay.h @@ -83,7 +83,7 @@ template<> __attribute__((always_inline)) inline void delaycycles<5>() {NOP2;NOP // Macro to convert from nano-seconds to clocks and clocks to nano-seconds // #define NS(_NS) (_NS / (1000 / (F_CPU / 1000000L))) -#if F_CPU < 96000000 +#if 1 || F_CPU < 96000000 #define NS(_NS) ( (_NS * (F_CPU / 1000000L))) / 1000 #define CLKS_TO_MICROS(_CLKS) ((long)(_CLKS)) / (F_CPU / 1000000L) #else -- cgit v1.2.3 From 0e1afbcda4336ff8967e419504459a22ffa56952 Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Wed, 19 Feb 2014 16:05:56 -0800 Subject: turning k20 dithering into a playground with different values/styles of dithering --- clockless_arm_k20.h | 44 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 42 insertions(+), 2 deletions(-) diff --git a/clockless_arm_k20.h b/clockless_arm_k20.h index 59dd3f51..2b993fb3 100644 --- a/clockless_arm_k20.h +++ b/clockless_arm_k20.h @@ -79,6 +79,11 @@ public: } } +// Dither values: +// 0 - no dithering +// 1 - approximated E values, high +// 2 - approximated E values, lo +// 3 - exact E values #define DITHER 1 #define DADVANCE 3 @@ -94,16 +99,37 @@ public: register data_t lo = *port & ~mask; *port = lo; - uint8_t E[3] = {0xFF,0xFF,0xFF}; + uint8_t D[3] = {0,0,0}; +#if DITHER > 0 +# if DITHER == 2 + uint8_t E[3] = {0x7F,0x7F,0x7F}; +# else + uint8_t E[3] = {0xFF,0xFF,0xFF}; +# endif + static uint8_t Dstore[3] = {0,0,0}; // compute the E values and seed D from the stored values for(register uint32_t i = 0; i < 3; i++) { byte S = scale.raw[i]; +# if DITHER == 3 + E[i] = 255 / S; + D[i] = Dstore[i]; + while(D[i] && D[i] >= E[i]) D[i] -= E[i]; +# else while(S>>=1) { E[i] >>=1; }; D[i] = Dstore[i] & E[i]; +# endif + } +#endif + + data[0] = data[1] = data[2] = 0; + switch(DITHER) { + case 1: data[0] = 255; break; + case 2: data[1] = 255; break; + case 3: data[2] = 255; break; } // Get access to the clock @@ -112,15 +138,25 @@ public: ARM_DWT_CYCCNT = 0; uint32_t next_mark = ARM_DWT_CYCCNT + (T1+T2+T3); + register uint32_t b; b = ((ADVANCE)?data:rgbdata)[SKIP + RGB_BYTE0(RGB_ORDER)]; if(DITHER && b) b = qadd8(b, D[B0]); b = scale8(b, scale.raw[B0]); - while(data < end) { + while(data < end) { + +#if DITHER > 0 +# if DITHER == 3 + D[B0] += DADVANCE; if(D[B0] >= E[B0]) D[B0] -= E[B0]; // D[B0] &= E[B0]; + D[B1] += DADVANCE; if(D[B1] >= E[B1]) D[B1] -= E[B1]; // D[B1] &= E[B1]; + D[B2] += DADVANCE; if(D[B2] >= E[B2]) D[B2] -= E[B2]; // D[B2] &= E[B2]; +# else D[B0] += DADVANCE; D[B0] &= E[B0]; D[B1] += DADVANCE; D[B1] &= E[B1]; D[B2] += DADVANCE; D[B2] &= E[B2]; +# endif +#endif // Write first byte, read next byte write8Bits(next_mark, port, hi, lo, b); @@ -146,10 +182,14 @@ public: INLINE_SCALE(b, scale.raw[B0]); }; + + +#if DITHER > 0 // Save the D values for cycling through next time Dstore[0] = D[0]; Dstore[1] = D[1]; Dstore[2] = D[2]; +#endif } }; #endif -- cgit v1.2.3 From adc14f87b3ad94d1787de3a93517d173147de957 Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Wed, 19 Feb 2014 16:27:12 -0800 Subject: turn off the selected dither indicator in pixel 0 --- clockless_arm_k20.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/clockless_arm_k20.h b/clockless_arm_k20.h index 2b993fb3..27793ff6 100644 --- a/clockless_arm_k20.h +++ b/clockless_arm_k20.h @@ -125,12 +125,12 @@ public: } #endif - data[0] = data[1] = data[2] = 0; - switch(DITHER) { - case 1: data[0] = 255; break; - case 2: data[1] = 255; break; - case 3: data[2] = 255; break; - } + // data[0] = data[1] = data[2] = 0; + // switch(DITHER) { + // case 1: data[0] = 255; break; + // case 2: data[1] = 255; break; + // case 3: data[2] = 255; break; + // } // Get access to the clock ARM_DEMCR |= ARM_DEMCR_TRCENA; -- cgit v1.2.3 From 68f7a7f2fc37d299706830ad374990738f18d6ff Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Mon, 3 Mar 2014 22:49:03 -0800 Subject: Apply mark's adjustments for the dithering and add to the sam3x as well --- clockless_arm_k20.h | 25 ++++++++++++++++++------- clockless_arm_sam.h | 39 +++++++++++++++++++++++++++++++++++---- 2 files changed, 53 insertions(+), 11 deletions(-) diff --git a/clockless_arm_k20.h b/clockless_arm_k20.h index 27793ff6..421011b0 100644 --- a/clockless_arm_k20.h +++ b/clockless_arm_k20.h @@ -111,13 +111,23 @@ public: static uint8_t Dstore[3] = {0,0,0}; +# if DITHER == 3 + static byte oddeven = 0; + oddeven = 1 - oddeven; + + static byte Q; + Q += 157; +# endif // compute the E values and seed D from the stored values for(register uint32_t i = 0; i < 3; i++) { byte S = scale.raw[i]; + # if DITHER == 3 - E[i] = 255 / S; - D[i] = Dstore[i]; - while(D[i] && D[i] >= E[i]) D[i] -= E[i]; + // Example: assume that S is 32 + E[i] = S ? 256 / S : 0; // E = 256 / 32 = 8 + D[i] = scale8( Q, E[i] /* E[i]+1 ? */ ); // D is now Q scaled 0..7 + if( E[i] ) E[i]--; // E is now 31 + if( oddeven ) D[i] = E[i] - D[i]; /* ? */ // Flip (invert) initial D on alternating updates # else while(S>>=1) { E[i] >>=1; }; D[i] = Dstore[i] & E[i]; @@ -148,16 +158,17 @@ public: #if DITHER > 0 # if DITHER == 3 - D[B0] += DADVANCE; if(D[B0] >= E[B0]) D[B0] -= E[B0]; // D[B0] &= E[B0]; - D[B1] += DADVANCE; if(D[B1] >= E[B1]) D[B1] -= E[B1]; // D[B1] &= E[B1]; - D[B2] += DADVANCE; if(D[B2] >= E[B2]) D[B2] -= E[B2]; // D[B2] &= E[B2]; + // Flip (invert) D on alternating pixles, to get even lighting + D[B0] = E[B0] - D[B0]; + D[B1] = E[B1] - D[B1]; + D[B2] = E[B2] - D[B2]; # else D[B0] += DADVANCE; D[B0] &= E[B0]; D[B1] += DADVANCE; D[B1] &= E[B1]; D[B2] += DADVANCE; D[B2] &= E[B2]; # endif #endif - + // Write first byte, read next byte write8Bits(next_mark, port, hi, lo, b); diff --git a/clockless_arm_sam.h b/clockless_arm_sam.h index 3ce29bcb..9899f6af 100644 --- a/clockless_arm_sam.h +++ b/clockless_arm_sam.h @@ -147,7 +147,7 @@ public: } #define FORCE_REFERENCE(var) asm volatile( "" : : "r" (var) ) -#define DITHER 1 +#define DITHER 3 #define DADVANCE 3 // 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. @@ -155,17 +155,41 @@ public: register data_ptr_t port asm("r7") = FastPinBB::port(); FORCE_REFERENCE(port); register byte *data = (byte*)rgbdata; register uint8_t *end = data + (nLeds*3 + SKIP); - uint8_t E[3] = {0xFF,0xFF,0xFF}; + uint8_t D[3] = {0,0,0}; +#if DITHER > 0 +# if DITHER == 2 + uint8_t E[3] = {0x7F,0x7F,0x7F}; +# else + uint8_t E[3] = {0xFF,0xFF,0xFF}; +# endif + static uint8_t Dstore[3] = {0,0,0}; +# if DITHER == 3 + static byte oddeven = 0; + oddeven = 1 - oddeven; + + static byte Q; + Q += 157; +# endif // compute the E values and seed D from the stored values for(register uint32_t i = 0; i < 3; i++) { byte S = scale.raw[i]; + +# if DITHER == 3 + // Example: assume that S is 32 + E[i] = S ? 256 / S : 0; // E = 256 / 32 = 8 + D[i] = scale8( Q, E[i] /* E[i]+1 ? */ ); // D is now Q scaled 0..7 + if( E[i] ) E[i]--; // E is now 31 + if( oddeven ) D[i] = E[i] - D[i]; /* ? */ // Flip (invert) initial D on alternating updates +# else while(S>>=1) { E[i] >>=1; }; D[i] = Dstore[i] & E[i]; +# endif } +#endif register volatile uint32_t *CTPTR asm("r6")= &SysTick->CTRL; FORCE_REFERENCE(CTPTR); @@ -188,11 +212,18 @@ public: _CTRL; while(data < end) { - - // advance D constrained by E +#if DITHER > 0 +# if DITHER == 3 + // Flip (invert) D on alternating pixles, to get even lighting + D[B0] = E[B0] - D[B0]; + D[B1] = E[B1] - D[B1]; + D[B2] = E[B2] - D[B2]; +# else D[B0] += DADVANCE; D[B0] &= E[B0]; D[B1] += DADVANCE; D[B1] &= E[B1]; D[B2] += DADVANCE; D[B2] &= E[B2]; +# endif +#endif for(register uint32_t i = 7; i > 0; i--) { AT_BIT_START(*port = 1); -- cgit v1.2.3 From 621782cd0955d824ece1ed528a77347afca07a9c Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Tue, 4 Mar 2014 00:06:20 -0800 Subject: Pull mark's changes back into trinket code --- clockless_arm_k20.h | 4 ++-- clockless_arm_sam.h | 6 +++++- clockless_trinket.h | 53 +++++++++++++++++++++++++++++++++++------------------ 3 files changed, 42 insertions(+), 21 deletions(-) diff --git a/clockless_arm_k20.h b/clockless_arm_k20.h index 421011b0..62e4e5e7 100644 --- a/clockless_arm_k20.h +++ b/clockless_arm_k20.h @@ -168,7 +168,7 @@ public: D[B2] += DADVANCE; D[B2] &= E[B2]; # endif #endif - + // Write first byte, read next byte write8Bits(next_mark, port, hi, lo, b); @@ -195,7 +195,7 @@ public: -#if DITHER > 0 +#if DITHER > 0 && DITHER != 3 // Save the D values for cycling through next time Dstore[0] = D[0]; Dstore[1] = D[1]; diff --git a/clockless_arm_sam.h b/clockless_arm_sam.h index 9899f6af..b5b1a50f 100644 --- a/clockless_arm_sam.h +++ b/clockless_arm_sam.h @@ -165,7 +165,6 @@ public: uint8_t E[3] = {0xFF,0xFF,0xFF}; # endif - static uint8_t Dstore[3] = {0,0,0}; # if DITHER == 3 static byte oddeven = 0; @@ -173,7 +172,10 @@ public: static byte Q; Q += 157; +# else + static uint8_t Dstore[3] = {0,0,0}; # endif + // compute the E values and seed D from the stored values for(register uint32_t i = 0; i < 3; i++) { byte S = scale.raw[i]; @@ -278,10 +280,12 @@ public: b = SCALE(b, scale.raw[B0]); }; +#if DITHER > 0 && DITHER != 3 // Save the D values for cycling through next time Dstore[0] = D[0]; Dstore[1] = D[1]; Dstore[2] = D[2]; +#endif } }; diff --git a/clockless_trinket.h b/clockless_trinket.h index fe628aa6..820aef17 100644 --- a/clockless_trinket.h +++ b/clockless_trinket.h @@ -14,7 +14,7 @@ // whether or not to use dithering #define DITHER 1 // whether or not to enable scale_video adjustments -#define SCALE_VIDEO 1 +#define SCALE_VIDEO 0 #endif // Variations on the functions in delay.h - w/a loop var passed in to preserve registers across calls by the optimizer/compiler @@ -173,7 +173,8 @@ public: // Loop life cycle // #define ADJUST_DITHER d0 += DADVANCE; d1 += DADVANCE; d2 += DADVANCE; d0 &= e0; d1 &= e1; d2 &= d2; -#define ADJDITHER2(D, E) D += DADVANCE; D &= E; +#define ADJDITHER2(D, E) D = E - D; + // #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); @@ -206,17 +207,24 @@ public: data_t lo = *port & ~mask; *port = lo; - register uint8_t d0, d1, d2; - register uint8_t e0, e1, e2; - uint8_t s0, s1, s2; - uint8_t b0, b1, b2; - static uint8_t d[3] = {0,0,0}; - uint16_t count = nLeds; uint8_t scale_base = 0; uint16_t advanceBy = advance ? (skip+3) : 0; // uint8_t dadv = DADVANCE; + + static byte oddeven = 0; + oddeven = 1 - oddeven; + + static byte Q; + Q += 157; + + register uint8_t d0, d1, d2; + register uint8_t e0, e1, e2; + uint8_t s0, s1, s2; + uint8_t b0, b1, b2; + // static uint8_t d[3] = {0,0,0}; + // initialize the scales s0 = scale.raw[B0]; s1 = scale.raw[B1]; @@ -224,13 +232,22 @@ public: // initialize the e & d values uint8_t S; - S = s0; e0 = 0xFF; while(S >>= 1) { e0 >>= 1; } - d0 = d[0] & e0; - S = s1; e1 = 0xFF; while(S >>= 1) { e1 >>= 1; } - d1 = d[1] & e1; - S = s2; e2 = 0xFF; while(S >>= 1) { e2 >>= 1; } - d2 = d[2] & e0; - + S = s0; e0 = S ? 256/S : 0; d0 = scale8(Q, e0); + if(e0) e0--; + if(oddeven) d0 = e0 - d0; + //e0 = 0xFF; while(S >>= 1) { e0 >>= 1; } + // d0 = d[0] & e0; + S = s1; e1 = S ? 256/S : 0; d1 = scale8(Q, e1); + if(e1) e1--; + if(oddeven) d1 = e1 - d1; + // e1 = 0xFF; while(S >>= 1) { e1 >>= 1; } + // d1 = d[1] & e1; + S = s2; e0 = S ? 256/S : 0; d2 = scale8(Q, e2); + // e2 = 0xFF; while(S >>= 1) { e2 >>= 1; } + // d2 = d[2] & e0; + if(e1) e2--; + if(oddeven) d1 = e1 - d1; + b0 = data[RGB_BYTE0(RGB_ORDER)]; if(DITHER && b0) { b0 = qadd8(b0, d0); } b0 = scale8_video(b0, s0); @@ -314,9 +331,9 @@ public: } // save the d values - d[0] = d0; - d[1] = d1; - d[2] = d2; + // d[0] = d0; + // d[1] = d1; + // d[2] = d2; } #ifdef SUPPORT_ARGB -- cgit v1.2.3 From 9324c3286ab955cffefc7a29dd58f8f7f5babd09 Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Thu, 6 Mar 2014 10:14:19 -0800 Subject: Fix compile errors for avr --- chipsets.h | 22 ++++++++++++++++++++++ clockless.h | 1 + clockless_trinket.h | 2 +- fastpin_avr.h | 4 ++-- 4 files changed, 26 insertions(+), 3 deletions(-) diff --git a/chipsets.h b/chipsets.h index ca76a818..ff146cba 100644 --- a/chipsets.h +++ b/chipsets.h @@ -2,6 +2,7 @@ #define __INC_CHIPSETS_H #include "pixeltypes.h" +#include "clockless.h" ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // @@ -316,6 +317,16 @@ class TM1809Controller800Khz : public ClocklessController class TM1803Controller400Khz : public ClocklessController {}; +// TODO: Merge in better defs +template +class GW6205Controller400Khz : public ClocklessController_Trinket {}; + +template +class GW6205Controller800Khz : public ClocklessController_Trinket {}; + +template +class TM1829Controller800Khz : public ClocklessController_Trinket {}; + #elif defined(LIB8_ATTINY) && (F_CPU == 16000000) // 62.5ns/clock // WS2811@16Mhz 4 clocks, 10 clocks, 6 clocks @@ -337,6 +348,17 @@ class TM1809Controller800Khz : public ClocklessController class TM1803Controller400Khz : public ClocklessController {}; +// TODO: Merge in better defs +template +class GW6205Controller400Khz : public ClocklessController_Trinket {}; + +template +class GW6205Controller800Khz : public ClocklessController_Trinket {}; + +template +class TM1829Controller800Khz : public ClocklessController_Trinket {}; + + #else // GW6205@400khz - 800ns, 800ns, 800ns template diff --git a/clockless.h b/clockless.h index c7d3b49f..c2c94b87 100644 --- a/clockless.h +++ b/clockless.h @@ -18,6 +18,7 @@ #define SET_LO FLIP ? FastPin::fastset(port, hi) : FastPin::fastset(port, lo); #define SET_HI FLIP ? FastPin::fastset(port, lo) : FastPin::fastset(port, hi); +#include "clockless_trinket.h" #include "clockless_avr.h" #include "clockless_arm_k20.h" #include "clockless_arm_sam.h" diff --git a/clockless_trinket.h b/clockless_trinket.h index 7fb593dd..2315e42e 100644 --- a/clockless_trinket.h +++ b/clockless_trinket.h @@ -6,7 +6,7 @@ #include "delay.h" #include // for cli/se definitions -#if defined(LIB8_ATTINY) +#if defined(FASTLED_AVR) // Scaling macro choice #ifndef TRINKET_SCALE diff --git a/fastpin_avr.h b/fastpin_avr.h index cb1e04ee..64fa822d 100644 --- a/fastpin_avr.h +++ b/fastpin_avr.h @@ -45,7 +45,7 @@ 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 : public _AVRPIN {}; +#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__) _IO(B); @@ -177,4 +177,4 @@ _DEFPIN_AVR(20, 32, F); _DEFPIN_AVR(21, 16, F); _DEFPIN_AVR(22, 2, F); _DEFPIN_A #endif -#endif \ No newline at end of file +#endif -- cgit v1.2.3 From 58f2cbfa0c12aafb76db41efe65d9ca7c5b2ca0b Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Sat, 8 Mar 2014 18:34:03 -0800 Subject: Centralized the rgb data load, advancing, scaling, and dithering code. This will work for all platforms/chipsets except for the trinket clockless (because of hand rolled asm) --- clockless_arm_k20.h | 103 +++------------------------------ clockless_arm_sam.h | 146 +++++++++-------------------------------------- controller.h | 85 ++++++++++++++++++++++++++- examples/Cylon/Cylon.ino | 4 +- 4 files changed, 119 insertions(+), 219 deletions(-) diff --git a/clockless_arm_k20.h b/clockless_arm_k20.h index 62e4e5e7..4477ffc7 100644 --- a/clockless_arm_k20.h +++ b/clockless_arm_k20.h @@ -79,14 +79,6 @@ public: } } -// Dither values: -// 0 - no dithering -// 1 - approximated E values, high -// 2 - approximated E values, lo -// 3 - exact E values -#define DITHER 1 -#define DADVANCE 3 - // 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. template static void showRGBInternal(register int nLeds, register CRGB scale, register const byte *rgbdata) { @@ -99,48 +91,9 @@ public: register data_t lo = *port & ~mask; *port = lo; - - uint8_t D[3] = {0,0,0}; - -#if DITHER > 0 -# if DITHER == 2 - uint8_t E[3] = {0x7F,0x7F,0x7F}; -# else - uint8_t E[3] = {0xFF,0xFF,0xFF}; -# endif - - static uint8_t Dstore[3] = {0,0,0}; - -# if DITHER == 3 - static byte oddeven = 0; - oddeven = 1 - oddeven; - - static byte Q; - Q += 157; -# endif - // compute the E values and seed D from the stored values - for(register uint32_t i = 0; i < 3; i++) { - byte S = scale.raw[i]; - -# if DITHER == 3 - // Example: assume that S is 32 - E[i] = S ? 256 / S : 0; // E = 256 / 32 = 8 - D[i] = scale8( Q, E[i] /* E[i]+1 ? */ ); // D is now Q scaled 0..7 - if( E[i] ) E[i]--; // E is now 31 - if( oddeven ) D[i] = E[i] - D[i]; /* ? */ // Flip (invert) initial D on alternating updates -# else - while(S>>=1) { E[i] >>=1; }; - D[i] = Dstore[i] & E[i]; -# endif - } -#endif - - // data[0] = data[1] = data[2] = 0; - // switch(DITHER) { - // case 1: data[0] = 255; break; - // case 2: data[1] = 255; break; - // case 3: data[2] = 255; break; - // } + // Setup the pixel controller and load/scale the first byte + PixelController pixels(data, scale, true, ADVANCE, SKIP); + register uint8_t b = pixels.loadAndScale0(); // Get access to the clock ARM_DEMCR |= ARM_DEMCR_TRCENA; @@ -148,59 +101,21 @@ public: ARM_DWT_CYCCNT = 0; uint32_t next_mark = ARM_DWT_CYCCNT + (T1+T2+T3); - - register uint32_t b; - b = ((ADVANCE)?data:rgbdata)[SKIP + RGB_BYTE0(RGB_ORDER)]; - if(DITHER && b) b = qadd8(b, D[B0]); - b = scale8(b, scale.raw[B0]); - - while(data < end) { - -#if DITHER > 0 -# if DITHER == 3 - // Flip (invert) D on alternating pixles, to get even lighting - D[B0] = E[B0] - D[B0]; - D[B1] = E[B1] - D[B1]; - D[B2] = E[B2] - D[B2]; -# else - D[B0] += DADVANCE; D[B0] &= E[B0]; - D[B1] += DADVANCE; D[B1] &= E[B1]; - D[B2] += DADVANCE; D[B2] &= E[B2]; -# endif -#endif + while(nLeds-- > 0) { + pixels.stepDithering(); // Write first byte, read next byte write8Bits(next_mark, port, hi, lo, b); + b = pixels.loadAndScale1(); - b = ((ADVANCE)?data:rgbdata)[SKIP + RGB_BYTE1(RGB_ORDER)]; - if(DITHER && b) b = qadd8(b, D[B1]); - INLINE_SCALE(b, scale.raw[B1]); - - // Write second byte + // Write second byte, read 3rd byte write8Bits(next_mark, port, hi, lo, b); - - b = ((ADVANCE)?data:rgbdata)[SKIP + RGB_BYTE2(RGB_ORDER)]; - if(DITHER && b) b = qadd8(b, D[B2]); - INLINE_SCALE(b, scale.raw[B2]); - - data += 3 + SKIP; + b = pixels.loadAndScale2(); // Write third byte write8Bits(next_mark, port, hi, lo, b); - - b = ((ADVANCE)?data:rgbdata)[SKIP + RGB_BYTE0(RGB_ORDER)]; - if(DITHER && b) b = qadd8(b, D[B0]); - INLINE_SCALE(b, scale.raw[B0]); + b = pixels.advanceAndLoadAndScale0(); }; - - - -#if DITHER > 0 && DITHER != 3 - // Save the D values for cycling through next time - Dstore[0] = D[0]; - Dstore[1] = D[1]; - Dstore[2] = D[2]; -#endif } }; #endif diff --git a/clockless_arm_sam.h b/clockless_arm_sam.h index b5b1a50f..8bd6d123 100644 --- a/clockless_arm_sam.h +++ b/clockless_arm_sam.h @@ -13,7 +13,7 @@ #define SCALE(S,V) scale8_video(S,V) // #define SCALE(S,V) scale8(S,V) -template +template class ClocklessController : public CLEDController { typedef typename FastPinBB::port_ptr_t data_ptr_t; typedef typename FastPinBB::port_t data_t; @@ -146,65 +146,32 @@ public: } + inline static void write8Bits(register volatile uint32_t *CTPTR, register data_ptr_t port, register uint8_t & b) __attribute__ ((always_inline)) { + // TODO: hand rig asm version of this method. The timings are based on adjusting/studying GCC compiler ouptut. This + // will bite me in the ass at some point, I know it. + for(register uint32_t i = 8; i > 0; i--) { + AT_BIT_START(*port=1); + if(b&0x80) {} else { AT_MARK(*port=0); } + b <<= 1; + AT_END(*port=0); + } + } + #define FORCE_REFERENCE(var) asm volatile( "" : : "r" (var) ) -#define DITHER 3 -#define DADVANCE 3 // 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. template static void showRGBInternal(register int nLeds, register CRGB scale, register const byte *rgbdata) { register data_ptr_t port asm("r7") = FastPinBB::port(); FORCE_REFERENCE(port); register byte *data = (byte*)rgbdata; register uint8_t *end = data + (nLeds*3 + SKIP); - - uint8_t D[3] = {0,0,0}; - -#if DITHER > 0 -# if DITHER == 2 - uint8_t E[3] = {0x7F,0x7F,0x7F}; -# else - uint8_t E[3] = {0xFF,0xFF,0xFF}; -# endif - - -# if DITHER == 3 - static byte oddeven = 0; - oddeven = 1 - oddeven; - - static byte Q; - Q += 157; -# else - static uint8_t Dstore[3] = {0,0,0}; -# endif - - // compute the E values and seed D from the stored values - for(register uint32_t i = 0; i < 3; i++) { - byte S = scale.raw[i]; - -# if DITHER == 3 - // Example: assume that S is 32 - E[i] = S ? 256 / S : 0; // E = 256 / 32 = 8 - D[i] = scale8( Q, E[i] /* E[i]+1 ? */ ); // D is now Q scaled 0..7 - if( E[i] ) E[i]--; // E is now 31 - if( oddeven ) D[i] = E[i] - D[i]; /* ? */ // Flip (invert) initial D on alternating updates -# else - while(S>>=1) { E[i] >>=1; }; - D[i] = Dstore[i] & E[i]; -# endif - } -#endif - - register volatile uint32_t *CTPTR asm("r6")= &SysTick->CTRL; FORCE_REFERENCE(CTPTR); - *port = 0; - register uint32_t b; - b = ADVANCE ? data[SKIP + B0] :rgbdata[SKIP + B0]; - // dither - if(DITHER && b) b = qadd8(b, D[B0]); - // now scale - b = SCALE(b, scale.raw[B0]); + // Setup the pixel controller and load/scale the first byte + PixelController pixels(data, scale, true, ADVANCE, SKIP); + register uint8_t b = pixels.loadAndScale0(); // Setup and start the clock + register volatile uint32_t *CTPTR asm("r6")= &SysTick->CTRL; FORCE_REFERENCE(CTPTR); _LOAD = TOTAL; _VAL = 0; _CTRL |= SysTick_CTRL_CLKSOURCE_Msk; @@ -212,80 +179,19 @@ public: // read to clear the loop flag _CTRL; + while(nLeds-- > 0) { + pixels.stepDithering(); - while(data < end) { -#if DITHER > 0 -# if DITHER == 3 - // Flip (invert) D on alternating pixles, to get even lighting - D[B0] = E[B0] - D[B0]; - D[B1] = E[B1] - D[B1]; - D[B2] = E[B2] - D[B2]; -# else - D[B0] += DADVANCE; D[B0] &= E[B0]; - D[B1] += DADVANCE; D[B1] &= E[B1]; - D[B2] += DADVANCE; D[B2] &= E[B2]; -# endif -#endif + write8Bits(CTPTR, port, b); - for(register uint32_t i = 7; i > 0; i--) { - AT_BIT_START(*port = 1); - if(b& 0x80) {} else { AT_MARK(*port = 0); } - AT_END(*port = 0); - b <<= 1; - } - - AT_BIT_START(*port = 1); - if(b& 0x80) {} else { AT_MARK(*port = 0); } - b = ADVANCE ? data[SKIP + B1] : rgbdata[SKIP + B1]; - AT_END(*port = 0); - - // dither - if(DITHER && b) b = qadd8(b, D[B1]); - // now scale - b = SCALE(b, scale.raw[B1]); - - for(register uint32_t i = 7; i > 0; i--) { - AT_BIT_START(*port = 1); - if(b& 0x80) {} else { AT_MARK(*port = 0); } - AT_END(*port = 0); - b <<= 1; - } - - AT_BIT_START(*port = 1); - if(b& 0x80) {} else { AT_MARK(*port = 0); } - b = ADVANCE ? data[SKIP + B2] : rgbdata[SKIP + B2]; - AT_END(*port = 0); - - // dither - if(DITHER && b) b = qadd8(b, D[B2]); - // now scale - b = SCALE(b, scale.raw[B2]); - - for(register uint32_t i = 7; i > 0; i--) { - AT_BIT_START(*port = 1); - if(b& 0x80) {} else { AT_MARK(*port = 0); } - AT_END(*port = 0); - b <<= 1; - } - - AT_BIT_START(*port = 1); - if(b& 0x80) {} else { AT_MARK(*port = 0); } - data += (3 + SKIP); - b = ADVANCE ? data[SKIP + B0] : rgbdata[SKIP + B0]; - AT_END(*port = 0); - - // dither - if(DITHER && b) b = qadd8(b, D[B0]); - // now scale - b = SCALE(b, scale.raw[B0]); - }; + b = pixels.loadAndScale1(); + write8Bits(CTPTR, port,b); -#if DITHER > 0 && DITHER != 3 - // Save the D values for cycling through next time - Dstore[0] = D[0]; - Dstore[1] = D[1]; - Dstore[2] = D[2]; -#endif + b = pixels.loadAndScale2(); + write8Bits(CTPTR, port,b); + + b = pixels.advanceAndLoadAndScale0(); + }; } }; diff --git a/controller.h b/controller.h index fa29408b..c2cc4164 100644 --- a/controller.h +++ b/controller.h @@ -4,10 +4,12 @@ #include "led_sysdefs.h" #include "pixeltypes.h" +#define RO(X) RGB_BYTE(RGB_ORDER, X) +#define RGB_BYTE(RO,X) (((RO)>>(3*(2-(X)))) & 0x3) -#define RGB_BYTE0(X) ((X>>6) & 0x3) -#define RGB_BYTE1(X) ((X>>3) & 0x3) -#define RGB_BYTE2(X) ((X) & 0x3) +#define RGB_BYTE0(RO) ((RO>>6) & 0x3) +#define RGB_BYTE1(RO) ((RO>>3) & 0x3) +#define RGB_BYTE2(RO) ((RO) & 0x3) #define B0 RGB_BYTE0(RGB_ORDER) #define B1 RGB_BYTE1(RGB_ORDER) @@ -58,4 +60,81 @@ public: }; +// Pixel controller class. This is the class that we use to centralize pixel access in a block of data, including +// support for things like RGB reordering, scaling, dithering, skipping (for ARGB data), and eventually, we will +// centralize 8/12/16 conversions here as well. +template +struct PixelController { + uint8_t d[3]; + uint8_t e[3]; + CRGB & mScale; + uint8_t *mData; + uint8_t mAdvance; + + PixelController(uint8_t *d, CRGB & s, bool dodithering, bool doadvance=0, uint8_t skip=0) : mData(d), mScale(s) { + enable_dithering(dodithering); + + mData += skip; + + mAdvance = 0; + if(doadvance) { mAdvance = 3 + skip; } + } + + void init_dithering() { + static byte R = 0; + R++; + + // fast reverse bits in a byte + byte Q = 0; + if(R & 0x01) { Q |= 0x80; } + if(R & 0x02) { Q |= 0x40; } + if(R & 0x04) { Q |= 0x20; } + if(R & 0x08) { Q |= 0x10; } + if(R & 0x10) { Q |= 0x08; } + if(R & 0x20) { Q |= 0x04; } + if(R & 0x40) { Q |= 0x02; } + if(R & 0x80) { Q |= 0x01; } + + // setup the seed d and e values + for(int i = 0; i < 3; i++) { byte s = mScale.raw[i]; + e[i] = s ? (256/s) + 1 : 0; + d[i] = scale8(Q, e[i]); + if(e[i]) e[i]--; + } + + d[0] = e[0] - d[0]; + } + + // toggle dithering enable + void enable_dithering(bool enable) { + if(enable) { init_dithering(); } + else { d[0]=d[1]=d[2]=e[0]=e[1]=e[2]=0; } + } + + // advance the data pointer forward + __attribute__((always_inline)) inline void advanceData() { mData += mAdvance; } + + // step the dithering forward + __attribute__((always_inline)) inline void stepDithering() { + d[0] = e[0] - d[0]; + d[1] = e[1] - d[1]; + d[2] = e[2] - d[2]; + } + + template __attribute__((always_inline)) inline static uint8_t loadByte(PixelController & pc) { return pc.mData[RO(SLOT)]; } + template __attribute__((always_inline)) inline static uint8_t dither(PixelController & pc, uint8_t b) { return qadd8(b, pc.d[RO(SLOT)]); } + template __attribute__((always_inline)) inline static uint8_t scale(PixelController & pc, uint8_t b) { return scale8(b, pc.mScale.raw[RO(SLOT)]); } + + // composite shortcut functions for loading, dithering, and scaling + template __attribute__((always_inline)) inline static uint8_t loadAndScale(PixelController & pc) { return scale(pc, pc.dither(pc, pc.loadByte(pc))); } + template __attribute__((always_inline)) inline static uint8_t advanceAndLoadAndScale(PixelController & pc) { pc.advanceData(); return pc.loadAndScale(pc); } + + // Helper functions to get around gcc stupidities + __attribute__((always_inline)) inline uint8_t loadAndScale0() { return loadAndScale<0>(*this); } + __attribute__((always_inline)) inline uint8_t loadAndScale1() { return loadAndScale<1>(*this); } + __attribute__((always_inline)) inline uint8_t loadAndScale2() { return loadAndScale<2>(*this); } + __attribute__((always_inline)) inline uint8_t advanceAndLoadAndScale0() { return advanceAndLoadAndScale<0>(*this); } + +}; + #endif \ No newline at end of file diff --git a/examples/Cylon/Cylon.ino b/examples/Cylon/Cylon.ino index 57a3117e..3bafb8d7 100644 --- a/examples/Cylon/Cylon.ino +++ b/examples/Cylon/Cylon.ino @@ -1,12 +1,12 @@ #include "FastLED.h" // How many leds in your strip? -#define NUM_LEDS 32 +#define NUM_LEDS 40 // For led chips like Neopixels, which have a data line, ground, and power, you just // need to define DATA_PIN. For led chipsets that are SPI based (four wires - data, clock, // ground, and power), like the LPD8806, define both DATA_PIN and CLOCK_PIN -#define DATA_PIN 3 +#define DATA_PIN 6 #define CLOCK_PIN 13 // Define the array of leds -- cgit v1.2.3 From 99d7e8ddb6519d32d8d17bc2dbde796cad8fdfdd Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Sat, 8 Mar 2014 19:22:13 -0800 Subject: doc updates --- controller.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/controller.h b/controller.h index c2cc4164..28dd1cb9 100644 --- a/controller.h +++ b/controller.h @@ -114,8 +114,10 @@ struct PixelController { // advance the data pointer forward __attribute__((always_inline)) inline void advanceData() { mData += mAdvance; } - // step the dithering forward + // step the dithering forward __attribute__((always_inline)) inline void stepDithering() { + // IF UPDATING HERE, BE SURE TO UPDATE THE ASM VERSION IN + // clockless_trinket.h! d[0] = e[0] - d[0]; d[1] = e[1] - d[1]; d[2] = e[2] - d[2]; -- cgit v1.2.3 From 5afdef7bd46d6e02abf33c377ee3d38b0d9b717a Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Sat, 8 Mar 2014 19:22:25 -0800 Subject: poking examples --- examples/Cylon/Cylon.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/Cylon/Cylon.ino b/examples/Cylon/Cylon.ino index 3bafb8d7..3f066425 100644 --- a/examples/Cylon/Cylon.ino +++ b/examples/Cylon/Cylon.ino @@ -6,7 +6,7 @@ // For led chips like Neopixels, which have a data line, ground, and power, you just // need to define DATA_PIN. For led chipsets that are SPI based (four wires - data, clock, // ground, and power), like the LPD8806, define both DATA_PIN and CLOCK_PIN -#define DATA_PIN 6 +#define DATA_PIN 4 #define CLOCK_PIN 13 // Define the array of leds -- cgit v1.2.3 From 47fec8524446bcb982a7ea20d726fac27bd1d3df Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Sat, 8 Mar 2014 19:32:18 -0800 Subject: Converting the clockless code to use the new pixels object for setting up dithering values --- clockless_trinket.h | 57 ++++++++++++++++------------------------------------- fastpin_avr.h | 2 +- 2 files changed, 18 insertions(+), 41 deletions(-) diff --git a/clockless_trinket.h b/clockless_trinket.h index 820aef17..aff80d8f 100644 --- a/clockless_trinket.h +++ b/clockless_trinket.h @@ -172,7 +172,7 @@ public: ///////////////////////////////////////////////////////////////////////////////////// // Loop life cycle -// #define ADJUST_DITHER d0 += DADVANCE; d1 += DADVANCE; d2 += DADVANCE; d0 &= e0; d1 &= e1; d2 &= d2; +// dither adjustment macro - should be kept in sync w/what's in stepDithering #define ADJDITHER2(D, E) D = E - D; // #define xstr(a) str(a) @@ -212,47 +212,24 @@ public: uint16_t advanceBy = advance ? (skip+3) : 0; // uint8_t dadv = DADVANCE; + uint8_t b0 = 0; + uint8_t b1 = 0; + uint8_t b2 = 0; - static byte oddeven = 0; - oddeven = 1 - oddeven; - - static byte Q; - Q += 157; - - register uint8_t d0, d1, d2; - register uint8_t e0, e1, e2; - uint8_t s0, s1, s2; - uint8_t b0, b1, b2; - // static uint8_t d[3] = {0,0,0}; - - // initialize the scales - s0 = scale.raw[B0]; - s1 = scale.raw[B1]; - s2 = scale.raw[B2]; - - // initialize the e & d values - uint8_t S; - S = s0; e0 = S ? 256/S : 0; d0 = scale8(Q, e0); - if(e0) e0--; - if(oddeven) d0 = e0 - d0; - //e0 = 0xFF; while(S >>= 1) { e0 >>= 1; } - // d0 = d[0] & e0; - S = s1; e1 = S ? 256/S : 0; d1 = scale8(Q, e1); - if(e1) e1--; - if(oddeven) d1 = e1 - d1; - // e1 = 0xFF; while(S >>= 1) { e1 >>= 1; } - // d1 = d[1] & e1; - S = s2; e0 = S ? 256/S : 0; d2 = scale8(Q, e2); - // e2 = 0xFF; while(S >>= 1) { e2 >>= 1; } - // d2 = d[2] & e0; - if(e1) e2--; - if(oddeven) d1 = e1 - d1; + // Setup the pixel controller and load/scale the first byte + PixelController pixels(data, scale, true, advance, skip); + b0 = pixels.loadAndScale0(); - b0 = data[RGB_BYTE0(RGB_ORDER)]; - if(DITHER && b0) { b0 = qadd8(b0, d0); } - b0 = scale8_video(b0, s0); - b1 = 0; - b2 = 0; + // pull the dithering/adjustment values out of the pixels object for direct asm access + uint8_t s0 = scale.raw[RO(0)]; + uint8_t s1 = scale.raw[RO(1)]; + uint8_t s2 = scale.raw[RO(2)]; + 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)]; register uint8_t loopvar=0; { diff --git a/fastpin_avr.h b/fastpin_avr.h index cb1e04ee..6fb6f0be 100644 --- a/fastpin_avr.h +++ b/fastpin_avr.h @@ -45,7 +45,7 @@ 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 : public _AVRPIN {}; +#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__) _IO(B); -- cgit v1.2.3 From cb7f6b15ebf5e8f7dc131c82222b0c4333d9acd0 Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Sat, 8 Mar 2014 19:45:35 -0800 Subject: Cleanup some spurious code from the asm --- clockless_trinket.h | 21 ++++++--------------- controller.h | 2 +- 2 files changed, 7 insertions(+), 16 deletions(-) diff --git a/clockless_trinket.h b/clockless_trinket.h index aff80d8f..2d5621e2 100644 --- a/clockless_trinket.h +++ b/clockless_trinket.h @@ -115,12 +115,9 @@ public: [s0] "r" (s0), \ [s1] "r" (s1), \ [s2] "r" (s2), \ - [d0] "r" (d0), \ - [d1] "r" (d1), \ - [d2] "r" (d2), \ - [e0] "r" (e0), \ - [e1] "r" (e1), \ - [e2] "r" (e2), \ + [d0] "r" (pixels.d[RO(0)]), \ + [d1] "r" (pixels.d[RO(1)]), \ + [d2] "r" (pixels.d[RO(2)]), \ [PORT] "M" (FastPin::port()-0x20), \ [O0] "M" (RGB_BYTE0(RGB_ORDER)), \ [O1] "M" (RGB_BYTE1(RGB_ORDER)), \ @@ -224,12 +221,6 @@ public: uint8_t s0 = scale.raw[RO(0)]; uint8_t s1 = scale.raw[RO(1)]; uint8_t s2 = scale.raw[RO(2)]; - 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)]; register uint8_t loopvar=0; { @@ -237,9 +228,9 @@ public: // Loop beginning, does some stuff that's outside of the pixel write cycle, namely incrementing d0-2 and masking off // by the E values (see the definition ) LOOP; - ADJDITHER2(d0,e0) - ADJDITHER2(d1,e1) - ADJDITHER2(d2,e2) + ADJDITHER2(pixels.d[RO(0)],pixels.e[RO(0)]) + ADJDITHER2(pixels.d[RO(1)],pixels.e[RO(1)]) + ADJDITHER2(pixels.d[RO(2)],pixels.e[RO(2)]) VIDADJ2(b0); // 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 diff --git a/controller.h b/controller.h index c2cc4164..16e1043a 100644 --- a/controller.h +++ b/controller.h @@ -67,8 +67,8 @@ template struct PixelController { uint8_t d[3]; uint8_t e[3]; - CRGB & mScale; uint8_t *mData; + CRGB & mScale; uint8_t mAdvance; PixelController(uint8_t *d, CRGB & s, bool dodithering, bool doadvance=0, uint8_t skip=0) : mData(d), mScale(s) { -- cgit v1.2.3 From 2dd3a81ce2f8c0e94660976cdd0401b5aebf8e63 Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Sun, 9 Mar 2014 11:23:36 -0700 Subject: Fix some k20 related bugs --- clockless_arm_k20.h | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/clockless_arm_k20.h b/clockless_arm_k20.h index 4477ffc7..65888f11 100644 --- a/clockless_arm_k20.h +++ b/clockless_arm_k20.h @@ -65,7 +65,7 @@ public: } #endif - inline static void write8Bits(register uint32_t & next_mark, register data_ptr_t port, register data_t hi, register data_t lo, register uint32_t & b) __attribute__ ((always_inline)) { + inline static void write8Bits(register uint32_t & next_mark, register data_ptr_t port, register data_t hi, register data_t lo, register uint8_t & b) __attribute__ ((always_inline)) { // TODO: hand rig asm version of this method. The timings are based on adjusting/studying GCC compiler ouptut. This // will bite me in the ass at some point, I know it. for(register uint32_t i = 8; i > 0; i--) { @@ -83,12 +83,9 @@ public: // gcc will use register Y for the this pointer. template static void showRGBInternal(register int nLeds, register CRGB scale, register const byte *rgbdata) { register byte *data = (byte*)rgbdata; - register data_t mask = FastPin::mask(); register data_ptr_t port = FastPin::port(); - nLeds *= (3 + SKIP); - register uint8_t *end = data + nLeds; - register data_t hi = *port | mask; - register data_t lo = *port & ~mask; + register data_t hi = *port | FastPin::mask();; + register data_t lo = *port & ~FastPin::mask();; *port = lo; // Setup the pixel controller and load/scale the first byte -- cgit v1.2.3 From d1535918f9a0023d1c3a6c1c89615bc3c8d0c3e0 Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Sun, 9 Mar 2014 13:02:27 -0700 Subject: Fix the trinket avr code for the mega and it's higher i/o port pin layouts --- clockless_trinket.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/clockless_trinket.h b/clockless_trinket.h index 2d5621e2..de6e8f01 100644 --- a/clockless_trinket.h +++ b/clockless_trinket.h @@ -39,9 +39,9 @@ template<> __attribute__((always_inline)) inline void _dc<6>(register uint8_t & 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); } -#define D1(ADJ) _dc(loopvar); -#define D2(ADJ) _dc(loopvar); -#define D3(ADJ) _dc(loopvar); +#define D1(ADJ) _dc(loopvar); +#define D2(ADJ) _dc(loopvar); +#define D3(ADJ) _dc(loopvar); ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // @@ -101,12 +101,12 @@ public: // 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), \ [b0] "+a" (b0), \ [b1] "+a" (b1), \ [b2] "+a" (b2), \ - [count] "+x" (count), \ [scale_base] "+a" (scale_base), \ - [data] "+z" (data), \ [loopvar] "+a" (loopvar) \ : /* use variables */ \ [ADV] "r" (advanceBy), \ @@ -118,7 +118,7 @@ public: [d0] "r" (pixels.d[RO(0)]), \ [d1] "r" (pixels.d[RO(1)]), \ [d2] "r" (pixels.d[RO(2)]), \ - [PORT] "M" (FastPin::port()-0x20), \ + [PORT] "M" (FastPin::port()-0x20), \ [O0] "M" (RGB_BYTE0(RGB_ORDER)), \ [O1] "M" (RGB_BYTE1(RGB_ORDER)), \ [O2] "M" (RGB_BYTE2(RGB_ORDER)) \ @@ -126,9 +126,9 @@ public: // 1 cycle, write hi to the port -#define HI1 asm __volatile__("out %[PORT], %[hi]" ASM_VARS ); +#define HI1 if((int)(FastPin::port()) < 64) { asm __volatile__("out %[PORT], %[hi]" ASM_VARS ); } else { *FastPin::port()=hi; } // 1 cycle, write lo to the port -#define LO1 asm __volatile__("out %[PORT], %[lo]" ASM_VARS ); +#define LO1 if((int)(FastPin::port()) < 64) { asm __volatile__("out %[PORT], %[lo]" ASM_VARS ); } else { *FastPin::port()=lo; } // 2 cycles, sbrs on flipping the lne 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 -- cgit v1.2.3 From 4ba3f8ef44bb2b0be4fdc9231b6cc76e2dbc48d0 Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Sun, 9 Mar 2014 13:26:15 -0700 Subject: * Add rgb scaling and dithering support to all the SPI based chipsets * Fix some compiler warnings, and do other code cleanup * All LED chipsets are now using the PixelController object for loading, scaling, re-ordering rgb data --- chipsets.h | 91 +++++++++++++++++++------------------------------------ controller.h | 10 ++---- fastspi_arm_k20.h | 70 +++++++++++++++++++++++------------------- fastspi_arm_sam.h | 18 +++++------ fastspi_avr.h | 79 +++++++++++++++++++++++++---------------------- fastspi_bitbang.h | 66 +++++++++++++++++++++++----------------- lib8tion.h | 2 +- 7 files changed, 164 insertions(+), 172 deletions(-) diff --git a/chipsets.h b/chipsets.h index 65c6b144..6f642a38 100644 --- a/chipsets.h +++ b/chipsets.h @@ -17,7 +17,6 @@ class LPD8806Controller : public CLEDController { public: // LPD8806 spec wants the high bit of every rgb data byte sent out to be set. __attribute__((always_inline)) inline static uint8_t adjust(register uint8_t data) { return (data>>1) | 0x80 | (data & 0x01); } - __attribute__((always_inline)) inline static uint8_t adjust(register uint8_t data, register uint8_t scale) { return (scale8(data, scale)>>1) | 0x80 | (data & 0x01); } __attribute__((always_inline)) inline static void postBlock(int len) { SPI::writeBytesValueRaw(0, ((len+63)>>6)); } @@ -53,36 +52,18 @@ public: } virtual void showColor(const struct CRGB & data, int nLeds, CRGB scale = CRGB::White) { - mSPI.select(); - uint8_t a = data[RGB_BYTE0(RGB_ORDER)]; - uint8_t b = data[RGB_BYTE1(RGB_ORDER)]; - uint8_t c = data[RGB_BYTE1(RGB_ORDER)]; - - a = 0x80 | (scale8(a, scale.raw[B0]) >> 1) | (a & 0x01); - b = 0x80 | (scale8(b, scale.raw[B1]) >> 1) | (b & 0x01); - c = 0x80 | (scale8(c, scale.raw[B2]) >> 1) | (c & 0x01); - int iLeds = 0; - - while(iLeds++ < nLeds) { - mSPI.writeByte(a); - mSPI.writeByte(b); - mSPI.writeByte(c); - } - - // latch in the world - mSPI.writeBytesValueRaw(0, ((nLeds*3+63)>>6)); - mSPI.release(); + mSPI.template writeBytes3((byte*)data.raw, nLeds * 3, scale, false); } virtual void show(const struct CRGB *data, int nLeds, CRGB scale = CRGB::White) { // TODO rgb-ize scale - mSPI.template writeBytes3((byte*)data, nLeds * 3, scale.raw[0]); + mSPI.template writeBytes3((byte*)data, nLeds * 3, scale); } #ifdef SUPPORT_ARGB virtual void show(const struct CARGB *data, int nLeds, uint8_t scale) { checkClear(nLeds); - mSPI.template writeBytes3<1, LPD8806_ADJUST, RGB_ORDER>((byte*)data, nLeds * 4, scale); + mSPI.template writeBytes3((byte*)data, nLeds * 4, scale, true, 1); } #endif }; @@ -115,31 +96,20 @@ public: virtual void showColor(const struct CRGB & data, int nLeds, CRGB scale = CRGB::White) { mWaitDelay.wait(); - mSPI.select(); - uint8_t a = scale8(data[RGB_BYTE0(RGB_ORDER)], scale.raw[B0]); - uint8_t b = scale8(data[RGB_BYTE1(RGB_ORDER)], scale.raw[B1]); - uint8_t c = scale8(data[RGB_BYTE2(RGB_ORDER)], scale.raw[B2]); - - while(nLeds--) { - mSPI.writeByte(a); - mSPI.writeByte(b); - mSPI.writeByte(c); - } - mSPI.waitFully(); - mSPI.release(); + mSPI.template writeBytes3((byte*)data.raw, nLeds * 3, scale, false); mWaitDelay.mark(); } virtual void show(const struct CRGB *data, int nLeds, CRGB scale) { mWaitDelay.wait(); - mSPI.template writeBytes3<0, RGB_ORDER>((byte*)data, nLeds * 3, scale.raw[0]); + mSPI.template writeBytes3((byte*)data, nLeds * 3, scale); mWaitDelay.mark(); } #ifdef SUPPORT_ARGB virtual void show(const struct CRGB *data, int nLeds, CRGB scale) { mWaitDelay.wait(); - mSPI.template writeBytes3<1, RGB_ORDER>((byte*)data, nLeds * 4, scale.raw[0]); + mSPI.template writeBytes3((byte*)data, nLeds * 4, scale, true, 1); mWaitDelay.mark(); } #endif @@ -158,12 +128,7 @@ class P9813Controller : public CLEDController { void writeBoundary() { mSPI.writeWord(0); mSPI.writeWord(0); } - inline void writeLed(const struct CRGB & data, CRGB scale) __attribute__((always_inline)) { - // prep the byte - register uint8_t r = scale8(data[RGB_BYTE0(RGB_ORDER)], scale.raw[B0]); - register uint8_t g = scale8(data[RGB_BYTE1(RGB_ORDER)], scale.raw[B1]); - register uint8_t b = scale8(data[RGB_BYTE2(RGB_ORDER)], scale.raw[B2]); - + inline void writeLed(uint8_t r, uint8_t g, uint8_t b) __attribute__((always_inline)) { register uint8_t top = 0xC0 | ((~b & 0xC0) >> 2) | ((~g & 0xC0) >> 4) | ((~r & 0xC0) >> 6); mSPI.writeByte(top); mSPI.writeByte(b); mSPI.writeByte(g); mSPI.writeByte(r); } @@ -180,11 +145,14 @@ public: } virtual void showColor(const struct CRGB & data, int nLeds, CRGB scale = CRGB::White) { + PixelController pixels(data.raw, scale, true, false, 0); + mSPI.select(); writeBoundary(); while(nLeds--) { - writeLed(data, scale); + writeLed(pixels.loadAndScale0(), pixels.loadAndScale1(), pixels.loadAndScale2()); + pixels.stepDithering(); } writeBoundary(); @@ -193,11 +161,15 @@ public: } virtual void show(const struct CRGB *data, int nLeds, CRGB scale) { + PixelController pixels((byte*)data, scale, true, true, 0); + mSPI.select(); writeBoundary(); for(int i = 0; i < nLeds; i++) { - writeLed(data[i], scale); + writeLed(pixels.loadAndScale0(), pixels.loadAndScale1(), pixels.loadAndScale2()); + pixels.advanceData(); + pixels.stepDithering(); } writeBoundary(); @@ -206,7 +178,19 @@ public: #ifdef SUPPORT_ARGB virtual void show(const struct CRGB *data, int nLeds, CRGB scale) { - mSPI.template writeBytes3<1, RGB_ORDER>((byte*)data, nLeds * 4, scale.raw[0]); + PixelController pixels(data, scale, true, true, 1); + + mSPI.select(); + + writeBoundary(); + for(int i = 0; i < nLeds; i++) { + writeLed(pixels.loadAndScale0(), pixels.loadAndScale1(), pixels.loadAndScale2()); + pixels.advanceData(); + pixels.stepDithering(); + } + writeBoundary(); + + mSPI.release(); } #endif }; @@ -253,26 +237,15 @@ public: } virtual void showColor(const struct CRGB & data, int nLeds, CRGB scale = CRGB::White) { - mSPI.select(); - uint8_t a = scale8(data[RGB_BYTE0(RGB_ORDER)], scale.raw[B0]); - uint8_t b = scale8(data[RGB_BYTE1(RGB_ORDER)], scale.raw[B1]); - uint8_t c = scale8(data[RGB_BYTE2(RGB_ORDER)], scale.raw[B2]); - - while(nLeds--) { - mSPI.template writeBit<0>(1); - mSPI.writeByte(a); - mSPI.writeByte(b); - mSPI.writeByte(c); - } + mSPI.template writeBytes3((byte*)data.raw, nLeds * 3, scale, false); writeHeader(); - mSPI.release(); } virtual void show(const struct CRGB *data, int nLeds, CRGB scale = CRGB::White) { // Make sure the FLAG_START_BIT flag is set to ensure that an extra 1 bit is sent at the start // of each triplet of bytes for rgb data // writeHeader(); - mSPI.template writeBytes3((byte*)data, nLeds * 3, scale.raw[0]); + mSPI.template writeBytes3((byte*)data, nLeds * 3, scale); writeHeader(); } @@ -284,7 +257,7 @@ public: // Make sure the FLAG_START_BIT flag is set to ensure that an extra 1 bit is sent at the start // of each triplet of bytes for rgb data - mSPI.template writeBytes3<1 | FLAG_START_BIT, RGB_ORDER>((byte*)data, nLeds * 4, scale.raw[0]); + mSPI.template writeBytes3((byte*)data, nLeds * 4, scale, true, 1); } #endif }; diff --git a/controller.h b/controller.h index 16e1043a..0e481ba9 100644 --- a/controller.h +++ b/controller.h @@ -11,10 +11,6 @@ #define RGB_BYTE1(RO) ((RO>>3) & 0x3) #define RGB_BYTE2(RO) ((RO) & 0x3) -#define B0 RGB_BYTE0(RGB_ORDER) -#define B1 RGB_BYTE1(RGB_ORDER) -#define B2 RGB_BYTE2(RGB_ORDER) - // operator byte *(struct CRGB[] arr) { return (byte*)arr; } @@ -67,11 +63,11 @@ template struct PixelController { uint8_t d[3]; uint8_t e[3]; - uint8_t *mData; + const uint8_t *mData; CRGB & mScale; uint8_t mAdvance; - PixelController(uint8_t *d, CRGB & s, bool dodithering, bool doadvance=0, uint8_t skip=0) : mData(d), mScale(s) { + PixelController(const uint8_t *d, CRGB & s, bool dodithering, bool doadvance=0, uint8_t skip=0) : mData(d), mScale(s) { enable_dithering(dodithering); mData += skip; @@ -134,7 +130,7 @@ struct PixelController { __attribute__((always_inline)) inline uint8_t loadAndScale1() { return loadAndScale<1>(*this); } __attribute__((always_inline)) inline uint8_t loadAndScale2() { return loadAndScale<2>(*this); } __attribute__((always_inline)) inline uint8_t advanceAndLoadAndScale0() { return advanceAndLoadAndScale<0>(*this); } - + __attribute__((always_inline)) inline uint8_t stepAdvanceAndLoadAndScale0() { stepDithering(); return advanceAndLoadAndScale<0>(*this); } }; #endif \ No newline at end of file diff --git a/fastspi_arm_k20.h b/fastspi_arm_k20.h index 76f5b528..706755d2 100644 --- a/fastspi_arm_k20.h +++ b/fastspi_arm_k20.h @@ -290,32 +290,44 @@ public: // 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 void writeBytes3(register uint8_t *data, int len, register uint8_t scale) { + template void writeBytes3(register uint8_t *data, int len, register CRGB scale, bool advance=true, uint8_t skip=0) { // setSPIRate(); - uint8_t *end = data + len; select(); - if((SKIP & FLAG_START_BIT) == 0) { + uint8_t *end = data + len; + + // Setup the pixel controller + PixelController pixels(data, scale, true, advance, skip); + + if((FLAGS & FLAG_START_BIT) == 0) { //If no start bit stupiditiy, write out as many 16-bit blocks as we can - uint8_t *first_end = end - (len % (SPI_ADVANCE * 2)); - + uint8_t *first_end = end - (len % ((3+skip)*2)); while(data != first_end) { + // Load and write out the first two bytes if(WM == NONE) { wait1(); } - Write::writeWord(D::adjust(data[SPI_B0], scale) << 8 | D::adjust(data[SPI_B1], scale)); - Write::writeWord(D::adjust(data[SPI_B2], scale) << 8 | D::adjust(data[SPI_ADVANCE + SPI_B0], scale)); - Write::writeWord(D::adjust(data[SPI_ADVANCE + SPI_B1], scale) << 8 | D::adjust(data[SPI_ADVANCE + SPI_B2], scale)); - data += (SPI_ADVANCE + SPI_ADVANCE); + Write::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::writeWord(D::adjust(pixels.loadAndScale2()) << 8 | D::adjust(pixels.stepAdvanceAndLoadAndScale0())); + + // Load and write out the next two bytes + Write::writeWord(D::adjust(pixels.loadAndScale1()) << 8 | D::adjust(pixels.loadAndScale2())); + pixels.stepDithering(); + pixels.advanceData(); + + data += ((3+skip)*2); } if(data != end) { if(WM == NONE) { wait1(); } // write out the rest as alternating 16/8-bit blocks (likely to be just one) - Write::writeWord(D::adjust(data[SPI_B0], scale) << 8 | D::adjust(data[SPI_B1], scale)); - Write::writeByte(D::adjust(data[SPI_B2], scale)); + Write::writeWord(D::adjust(pixels.loadAndScale0()) << 8 | D::adjust(pixels.loadAndScale1())); + Write::writeByte(D::adjust(pixels.loadAndScale2())); } D::postBlock(len); waitFully(); - } else if(SKIP & FLAG_START_BIT) { + } else if(FLAGS & FLAG_START_BIT) { uint32_t ctar1_save = SPI0_CTAR1; // Clear out the FMSZ bits, reset them for 9 bits transferd for the start bit @@ -323,38 +335,34 @@ public: update_ctar1(ctar1); while(data != end) { - writeWord( 0x100 | D::adjust(data[SPI_B0], scale)); - writeByte(D::adjust(data[SPI_B1], scale)); - writeByte(D::adjust(data[SPI_B2], scale)); - data += SPI_ADVANCE; + writeWord( 0x100 | D::adjust(pixels.loadAndScale0())); + writeByte(D::adjust(pixels.loadAndScale1())); + writeByte(D::adjust(pixels.loadAndScale2())); + pixels.advanceData(); + pixels.stepDithering(); + data += (3+skip); } D::postBlock(len); waitFully(); // restore ctar1 update_ctar1(ctar1_save); - // } else { - // while(data != end) { - // writeByte(D::adjust(data[SPI_B0], scale); - // writeWord(D::adjust(data[SPI_B1], scale) << 8 | D::adjust(data[SPI_B2], scale)); - // data += SPI_ADVANCE; - // } - // waitFully(); } release(); } - template void writeBytes3(register uint8_t *data, int len, register uint8_t scale) { - writeBytes3(data, len, scale); + // template instantiations for writeBytes 3 + template void writeBytes3(register uint8_t *data, int len, register CRGB scale, bool advance=true, uint8_t skip=0) { + writeBytes3(data, len, scale, advance, skip); } - template void writeBytes3(register uint8_t *data, int len, register uint8_t scale) { - writeBytes3<0, D, RGB_ORDER>(data, len, scale); + template void writeBytes3(register uint8_t *data, int len, register CRGB scale, bool advance=true, uint8_t skip=0) { + writeBytes3<0, D, RGB_ORDER>(data, len, scale, advance, skip); } - template void writeBytes3(register uint8_t *data, int len, register uint8_t scale) { - writeBytes3<0, DATA_NOP, RGB_ORDER>(data, len, scale); + template void writeBytes3(register uint8_t *data, int len, register CRGB scale, bool advance=true, uint8_t skip=0) { + writeBytes3<0, DATA_NOP, RGB_ORDER>(data, len, scale, advance, skip); } - void writeBytes3(register uint8_t *data, int len, register uint8_t scale) { - writeBytes3<0, DATA_NOP, RGB>(data, len, scale); + void writeBytes3(register uint8_t *data, int len, register CRGB scale, bool advance=true, uint8_t skip=0) { + writeBytes3<0, DATA_NOP, RGB>(data, len, scale, advance, skip); } }; #endif diff --git a/fastspi_arm_sam.h b/fastspi_arm_sam.h index 2e17634d..9b58049d 100644 --- a/fastspi_arm_sam.h +++ b/fastspi_arm_sam.h @@ -40,20 +40,20 @@ public: // write a single bit out, which bit from the passed in byte is determined by template parameter template inline static void writeBit(uint8_t b) { /* TODO */ } - template void writeBytes3(register uint8_t *data, int len, register uint8_t scale) { /* TODO*/ } + template void writeBytes3(register uint8_t *data, int len, register uint8_t scale, bool advance=true, uint8_t skip=0) { /* TODO*/ } // template instantiations for writeBytes 3 - template void writeBytes3(register uint8_t *data, int len, register uint8_t scale) { - writeBytes3(data, len, scale); + template void writeBytes3(register uint8_t *data, int len, register uint8_t scale, bool advance=true, uint8_t skip=0) { + writeBytes3(data, len, scale, advance, skip); } - template void writeBytes3(register uint8_t *data, int len, register uint8_t scale) { - writeBytes3<0, D, RGB_ORDER>(data, len, scale); + template void writeBytes3(register uint8_t *data, int len, register uint8_t scale, bool advance=true, uint8_t skip=0) { + writeBytes3<0, D, RGB_ORDER>(data, len, scale, advance, skip); } - template void writeBytes3(register uint8_t *data, int len, register uint8_t scale) { - writeBytes3<0, DATA_NOP, RGB_ORDER>(data, len, scale); + template void writeBytes3(register uint8_t *data, int len, register uint8_t scale, bool advance=true, uint8_t skip=0) { + writeBytes3<0, DATA_NOP, RGB_ORDER>(data, len, scale, advance, skip); } - void writeBytes3(register uint8_t *data, int len, register uint8_t scale) { - writeBytes3<0, DATA_NOP, RGB>(data, len, scale); + void writeBytes3(register uint8_t *data, int len, register uint8_t scale, bool advance=true, uint8_t skip=0) { + writeBytes3<0, DATA_NOP, RGB>(data, len, scale, advance, skip); }; diff --git a/fastspi_avr.h b/fastspi_avr.h index 95e1c977..3099672a 100644 --- a/fastspi_avr.h +++ b/fastspi_avr.h @@ -94,30 +94,37 @@ public: // 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 void writeBytes3(register uint8_t *data, int len, register uint8_t scale) { + template void writeBytes3(register uint8_t *data, int len, register uint8_t scale, bool advance=true, uint8_t skip=0) { uint8_t *end = data + len; + PixelController pixels(data, scale, true, advance, skip); select(); while(data != end) { - writeByte(D::adjust(data[SPI_B0], scale)); - writeByte(D::adjust(data[SPI_B1], scale)); - writeByte(D::adjust(data[SPI_B2], scale)); - data += SPI_ADVANCE; + 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(); + data += (3+skip); } D::postBlock(len); release(); } - template void writeBytes3(register uint8_t *data, int len, register uint8_t scale) { - writeBytes3(data, len, scale); + // template instantiations for writeBytes 3 + template void writeBytes3(register uint8_t *data, int len, register uint8_t scale, bool advance=true, uint8_t skip=0) { + writeBytes3(data, len, scale, advance, skip); } - template void writeBytes3(register uint8_t *data, int len, register uint8_t scale) { - writeBytes3<0, D, RGB_ORDER>(data, len, scale); + template void writeBytes3(register uint8_t *data, int len, register uint8_t scale, bool advance=true, uint8_t skip=0) { + writeBytes3<0, D, RGB_ORDER>(data, len, scale, advance, skip); } - template void writeBytes3(register uint8_t *data, int len, register uint8_t scale) { - writeBytes3<0, DATA_NOP, RGB_ORDER>(data, len, scale); + template void writeBytes3(register uint8_t *data, int len, register uint8_t scale, bool advance=true, uint8_t skip=0) { + writeBytes3<0, DATA_NOP, RGB_ORDER>(data, len, scale, advance, skip); } - void writeBytes3(register uint8_t *data, int len, register uint8_t scale) { - writeBytes3<0, DATA_NOP, RGB>(data, len, scale); + void writeBytes3(register uint8_t *data, int len, register uint8_t scale, bool advance=true, uint8_t skip=0) { + writeBytes3<0, DATA_NOP, RGB>(data, len, scale, advance, skip); } }; @@ -260,46 +267,44 @@ public: // 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 void writeBytes3(register uint8_t *data, int len, register uint8_t scale) { + template void writeBytes3(register uint8_t *data, int len, register CRGB scale, bool advance=true, uint8_t skip=0) { //setSPIRate(); uint8_t *end = data + len; + PixelController pixels(data, scale, true, advance, skip); + select(); while(data != end) { - if(SKIP & FLAG_START_BIT) { + if(FLAGS & FLAG_START_BIT) { writeBit<0>(1); - } - // a slight touch of delay here helps optimize the timing of the status register check loop (not used on ARM) - if(false && _SPI_CLOCK_DIVIDER == 0) { - writeByteNoWait(D::adjust(data[SPI_B0], scale)); delaycycles<13>(); - writeByteNoWait(D::adjust(data[SPI_B1], scale)); delaycycles<13>(); - writeByteNoWait(D::adjust(data[SPI_B2], scale)); delaycycles<9>(); - } else if(SKIP & FLAG_START_BIT) { - writeBytePostWait(D::adjust(data[SPI_B0], scale)); - writeBytePostWait(D::adjust(data[SPI_B1], scale)); - writeBytePostWait(D::adjust(data[SPI_B2], scale)); + writeBytePostWait(D::adjust(pixels.loadAndScale0())); + writeBytePostWait(D::adjust(pixels.loadAndScale1())); + writeBytePostWait(D::adjust(pixels.loadAndScale2())); } else { - writeByte(D::adjust(data[SPI_B0], scale)); - writeByte(D::adjust(data[SPI_B1], scale)); - writeByte(D::adjust(data[SPI_B2], scale)); + writeByte(D::adjust(pixels.loadAndScale0())); + writeByte(D::adjust(pixels.loadAndScale1())); + writeByte(D::adjust(pixels.loadAndScale2())); } - data += SPI_ADVANCE; + pixels.advanceData(); + pixels.stepDithering(); + data += (3+skip); } D::postBlock(len); release(); } - template void writeBytes3(register uint8_t *data, int len, register uint8_t scale) { - writeBytes3(data, len, scale); + // template instantiations for writeBytes 3 + template void writeBytes3(register uint8_t *data, int len, register CRGB scale, bool advance=true, uint8_t skip=0) { + writeBytes3(data, len, scale, advance, skip); } - template void writeBytes3(register uint8_t *data, int len, register uint8_t scale) { - writeBytes3<0, D, RGB_ORDER>(data, len, scale); + template void writeBytes3(register uint8_t *data, int len, register CRGB scale, bool advance=true, uint8_t skip=0) { + writeBytes3<0, D, RGB_ORDER>(data, len, scale, advance, skip); } - template void writeBytes3(register uint8_t *data, int len, register uint8_t scale) { - writeBytes3<0, DATA_NOP, RGB_ORDER>(data, len, scale); + template void writeBytes3(register uint8_t *data, int len, register CRGB scale, bool advance=true, uint8_t skip=0) { + writeBytes3<0, DATA_NOP, RGB_ORDER>(data, len, scale, advance, skip); } - void writeBytes3(register uint8_t *data, int len, register uint8_t scale) { - writeBytes3<0, DATA_NOP, RGB>(data, len, scale); + void writeBytes3(register uint8_t *data, int len, register CRGB scale, bool advance=true, uint8_t skip=0) { + writeBytes3<0, DATA_NOP, RGB>(data, len, scale, advance, skip); } }; diff --git a/fastspi_bitbang.h b/fastspi_bitbang.h index f9c1a218..8c3650c6 100644 --- a/fastspi_bitbang.h +++ b/fastspi_bitbang.h @@ -48,7 +48,7 @@ public: static void writeWord(uint16_t w) __attribute__((always_inline)) { writeByte(w>>8); writeByte(w&0xFF); } // naive writeByte implelentation, simply calls writeBit on the 8 bits in the byte. - static void writeByte(uint8_t b) __attribute__((always_inline)) { + static void writeByte(uint8_t b) { writeBit<7>(b); writeBit<6>(b); writeBit<5>(b); @@ -61,7 +61,7 @@ public: private: // writeByte implementation with data/clock registers passed in. - static void writeByte(uint8_t b, clock_ptr_t clockpin, data_ptr_t datapin) __attribute__((always_inline)) { + static void writeByte(uint8_t b, clock_ptr_t clockpin, data_ptr_t datapin) { writeBit<7>(b, clockpin, datapin); writeBit<6>(b, clockpin, datapin); writeBit<5>(b, clockpin, datapin); @@ -77,7 +77,7 @@ private: // can get close to getting a bit out the door in 2 clock cycles! static void writeByte(uint8_t b, data_ptr_t datapin, data_t hival, data_t loval, - clock_t hiclock, clock_t loclock) __attribute__((always_inline, hot)) { + clock_t hiclock, clock_t loclock) { writeBit<7>(b, datapin, hival, loval, hiclock, loclock); writeBit<6>(b, datapin, hival, loval, hiclock, loclock); writeBit<5>(b, datapin, hival, loval, hiclock, loclock); @@ -93,7 +93,7 @@ private: // the data and clock pins are on the same port! Don't do that! static void writeByte(uint8_t b, clock_ptr_t clockpin, data_ptr_t datapin, data_t hival, data_t loval, - clock_t hiclock, clock_t loclock) __attribute__((always_inline)) { + clock_t hiclock, clock_t loclock) { writeBit<7>(b, clockpin, datapin, hival, loval, hiclock, loclock); writeBit<6>(b, clockpin, datapin, hival, loval, hiclock, loclock); writeBit<5>(b, clockpin, datapin, hival, loval, hiclock, loclock); @@ -286,7 +286,10 @@ public: // 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 of each grouping, as well as a class specifying a per // byte of data modification to be made. (See DATA_NOP above) - template void writeBytes3(register uint8_t *data, int len, register uint8_t scale) { + template void writeBytes3(register uint8_t *data, int len, register CRGB scale, bool advance=true, uint8_t skip=0) { + // Setup the pixel controller + PixelController pixels(data, scale, true, advance, skip); + select(); #ifdef FAST_SPI_INTERRUPTS_WRITE_PINS @@ -294,13 +297,15 @@ public: // to use this block uint8_t *end = data + len; while(data != end) { - if(SKIP & FLAG_START_BIT) { + if(FLAGS & FLAG_START_BIT) { writeBit<0>(1); } - writeByte(D::adjust(data[SPI_B0], scale)); - writeByte(D::adjust(data[SPI_B1], scale)); - writeByte(D::adjust(data[SPI_B2], scale)); - data += SPI_ADVANCE; + writeByte(D::adjust(pixels.loadAndScale0())); + writeByte(D::adjust(pixels.loadAndScale1())); + writeByte(D::adjust(pixels.loadAndScale2())); + pixels.advanceData(); + pixels.stepDithering(); + data += (skip+3); } #else // If we can guaruntee that no one else will be writing data while we are running (namely, changing the values of the PORT/PDOR pins) @@ -318,13 +323,15 @@ public: uint8_t *end = data + len; while(data != end) { - if(SKIP & FLAG_START_BIT) { + if(FLAGS & FLAG_START_BIT) { writeBit<0>(1, clockpin, datapin, datahi, datalo, clockhi, clocklo); } - writeByte(D::adjust(data[SPI_B0], scale), clockpin, datapin, datahi, datalo, clockhi, clocklo); - writeByte(D::adjust(data[SPI_B1], scale), clockpin, datapin, datahi, datalo, clockhi, clocklo); - writeByte(D::adjust(data[SPI_B2], scale), clockpin, datapin, datahi, datalo, clockhi, clocklo); - data += SPI_ADVANCE; + writeByte(D::adjust(pixels.loadAndScale0()), clockpin, datapin, datahi, datalo, clockhi, clocklo); + writeByte(D::adjust(pixels.loadAndScale1()), clockpin, datapin, datahi, datalo, clockhi, clocklo); + writeByte(D::adjust(pixels.loadAndScale2()), clockpin, datapin, datahi, datalo, clockhi, clocklo); + pixels.advanceData(); + pixels.stepDithering(); + data += (skip+3); } } else { @@ -337,13 +344,15 @@ public: uint8_t *end = data + len; while(data != end) { - if(SKIP & FLAG_START_BIT) { + if(FLAGS & FLAG_START_BIT) { writeBit<0>(1, datapin, datahi_clockhi, datalo_clockhi, datahi_clocklo, datalo_clocklo); } - writeByte(D::adjust(data[SPI_B0], scale), datapin, datahi_clockhi, datalo_clockhi, datahi_clocklo, datalo_clocklo); - writeByte(D::adjust(data[SPI_B1], scale), datapin, datahi_clockhi, datalo_clockhi, datahi_clocklo, datalo_clocklo); - writeByte(D::adjust(data[SPI_B2], scale), datapin, datahi_clockhi, datalo_clockhi, datahi_clocklo, datalo_clocklo); - data += SPI_ADVANCE; + writeByte(D::adjust(pixels.loadAndScale0()), datapin, datahi_clockhi, datalo_clockhi, datahi_clocklo, datalo_clocklo); + writeByte(D::adjust(pixels.loadAndScale1()), datapin, datahi_clockhi, datalo_clockhi, datahi_clocklo, datalo_clocklo); + writeByte(D::adjust(pixels.loadAndScale2()), datapin, datahi_clockhi, datalo_clockhi, datahi_clocklo, datalo_clocklo); + pixels.advanceData(); + pixels.stepDithering(); + data += (skip+3); } } #endif @@ -351,17 +360,18 @@ public: release(); } - template void writeBytes3(register uint8_t *data, int len, register uint8_t scale) { - writeBytes3(data, len, scale); + // template instantiations for writeBytes 3 + template void writeBytes3(register uint8_t *data, int len, register CRGB scale, bool advance=true, uint8_t skip=0) { + writeBytes3(data, len, scale, advance, skip); } - template void writeBytes3(register uint8_t *data, int len, register uint8_t scale) { - writeBytes3<0, D, RGB_ORDER>(data, len, scale); + template void writeBytes3(register uint8_t *data, int len, register CRGB scale, bool advance=true, uint8_t skip=0) { + writeBytes3<0, D, RGB_ORDER>(data, len, scale, advance, skip); } - template void writeBytes3(register uint8_t *data, int len, register uint8_t scale) { - writeBytes3<0, DATA_NOP, RGB_ORDER>(data, len, scale); + template void writeBytes3(register uint8_t *data, int len, register CRGB scale, bool advance=true, uint8_t skip=0) { + writeBytes3<0, DATA_NOP, RGB_ORDER>(data, len, scale, advance, skip); } - void writeBytes3(register uint8_t *data, int len, register uint8_t scale) { - writeBytes3<0, DATA_NOP, RGB>(data, len, scale); + void writeBytes3(register uint8_t *data, int len, register CRGB scale, bool advance=true, uint8_t skip=0) { + writeBytes3<0, DATA_NOP, RGB>(data, len, scale, advance, skip); } }; diff --git a/lib8tion.h b/lib8tion.h index c8b84fda..d197b5a1 100644 --- a/lib8tion.h +++ b/lib8tion.h @@ -465,7 +465,7 @@ LIB8STATIC uint8_t scale8_video( uint8_t i, fract8 scale) // uint8_t j = (i == 0) ? 0 : (((int)i * (int)(scale) ) >> 8) + nonzeroscale; return j; #elif SCALE8_AVRASM == 1 - uint8_t j; + uint8_t j=0; asm volatile( "mul %[i], %[scale]\n\t" "mov %[j], r1\n\t" -- cgit v1.2.3 From d758a83509b971479c646084e937081fa3daaa8b Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Sun, 9 Mar 2014 14:01:03 -0700 Subject: Extend GW6205 support to the other clockless platforms --- chipsets.h | 12 ++++++------ clockless_arm_k20.h | 12 ++++++------ clockless_arm_sam.h | 12 ++++++------ clockless_trinket.h | 22 ++++++++++++++++++++-- 4 files changed, 38 insertions(+), 20 deletions(-) diff --git a/chipsets.h b/chipsets.h index 6f642a38..c68e9d81 100644 --- a/chipsets.h +++ b/chipsets.h @@ -294,10 +294,10 @@ template class TM1829Controller800Khz : public ClocklessController {}; template -class GW6205Controller400Khz : public ClocklessController {}; +class GW6205Controller400Khz : public ClocklessController {}; template -class GW6205Controller800Khz : public ClocklessController {}; +class GW6205Controller800Khz : public ClocklessController {}; #elif defined(FASTLED_AVR) && (F_CPU == 16000000) // 62.5ns/clock @@ -324,10 +324,10 @@ template class TM1829Controller800Khz : public ClocklessController {}; template -class GW6205Controller400Khz : public ClocklessController {}; +class GW6205Controller400Khz : public ClocklessController {}; template -class GW6205Controller800Khz : public ClocklessController {}; +class GW6205Controller800Khz : public ClocklessController {}; #else // GW6205@400khz - 800ns, 800ns, 800ns @@ -387,10 +387,10 @@ class TM1803Controller400Khz : public ClocklessController -class TM1829Controller800Khz : public ClocklessController {}; +class TM1829Controller800Khz : public ClocklessController {}; template -class TM1829Controller1600Khz : public ClocklessController {}; +class TM1829Controller1600Khz : public ClocklessController {}; #if NO_TIME(100, 300, 200) #warning "Not enough clock cycles available for TM1829@1.6Mhz" #endif diff --git a/clockless_arm_k20.h b/clockless_arm_k20.h index 65888f11..961789a2 100644 --- a/clockless_arm_k20.h +++ b/clockless_arm_k20.h @@ -4,7 +4,7 @@ // 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) -template +template class ClocklessController : public CLEDController { typedef typename FastPin::port_ptr_t data_ptr_t; typedef typename FastPin::port_t data_t; @@ -65,10 +65,10 @@ public: } #endif - inline static void write8Bits(register uint32_t & next_mark, register data_ptr_t port, register data_t hi, register data_t lo, register uint8_t & b) __attribute__ ((always_inline)) { + template __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) { // TODO: hand rig asm version of this method. The timings are based on adjusting/studying GCC compiler ouptut. This // will bite me in the ass at some point, I know it. - for(register uint32_t i = 8; i > 0; i--) { + for(register uint32_t i = BITS; i > 0; i--) { while(ARM_DWT_CYCCNT < next_mark); next_mark = ARM_DWT_CYCCNT + (T1+T2+T3); FastPin::fastset(port, hi); @@ -102,15 +102,15 @@ public: pixels.stepDithering(); // Write first byte, read next byte - write8Bits(next_mark, port, hi, lo, b); + writeBits<8+XTRA0>(next_mark, port, hi, lo, b); b = pixels.loadAndScale1(); // Write second byte, read 3rd byte - write8Bits(next_mark, port, hi, lo, b); + writeBits<8+XTRA0>(next_mark, port, hi, lo, b); b = pixels.loadAndScale2(); // Write third byte - write8Bits(next_mark, port, hi, lo, b); + writeBits<8+XTRA0>(next_mark, port, hi, lo, b); b = pixels.advanceAndLoadAndScale0(); }; } diff --git a/clockless_arm_sam.h b/clockless_arm_sam.h index 8bd6d123..5c418509 100644 --- a/clockless_arm_sam.h +++ b/clockless_arm_sam.h @@ -13,7 +13,7 @@ #define SCALE(S,V) scale8_video(S,V) // #define SCALE(S,V) scale8(S,V) -template +template class ClocklessController : public CLEDController { typedef typename FastPinBB::port_ptr_t data_ptr_t; typedef typename FastPinBB::port_t data_t; @@ -146,10 +146,10 @@ public: } - inline static void write8Bits(register volatile uint32_t *CTPTR, register data_ptr_t port, register uint8_t & b) __attribute__ ((always_inline)) { + template __attribute__ ((always_inline)) inline static void writeBits(register volatile uint32_t *CTPTR, register data_ptr_t port, register uint8_t & b) { // TODO: hand rig asm version of this method. The timings are based on adjusting/studying GCC compiler ouptut. This // will bite me in the ass at some point, I know it. - for(register uint32_t i = 8; i > 0; i--) { + for(register uint32_t i = BITS; i > 0; i--) { AT_BIT_START(*port=1); if(b&0x80) {} else { AT_MARK(*port=0); } b <<= 1; @@ -182,13 +182,13 @@ public: while(nLeds-- > 0) { pixels.stepDithering(); - write8Bits(CTPTR, port, b); + writeBits<8+XTRA0>(CTPTR, port, b); b = pixels.loadAndScale1(); - write8Bits(CTPTR, port,b); + writeBits<8+XTRA0>(CTPTR, port,b); b = pixels.loadAndScale2(); - write8Bits(CTPTR, port,b); + writeBits<8+XTRA0>(CTPTR, port,b); b = pixels.advanceAndLoadAndScale0(); }; diff --git a/clockless_trinket.h b/clockless_trinket.h index de6e8f01..1222106f 100644 --- a/clockless_trinket.h +++ b/clockless_trinket.h @@ -51,7 +51,7 @@ template<> __attribute__((always_inline)) inline void _dc<8>(register uint8_t & // ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -template +template class ClocklessController : public CLEDController { typedef typename FastPin::port_ptr_t data_ptr_t; typedef typename FastPin::port_t data_t; @@ -249,7 +249,13 @@ public: HI1 D1(1) QLO2(b0, 3) RORSC14(b1,4) D2(4) LO1 ROR1(b1) CLC1 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 ROR1(b1) CLC1 D3(2) - HI1 D1(1) QLO2(b0, 0) D2(0) LO1 VIDADJ2(b1) D3(2) + HI1 D1(1) QLO2(b0, 0) D2(0) LO1 VIDADJ2(b1) D3(2) + switch(XTRA0) { + case 4: HI1 D1(1) QLO2(b0,0) D2(0) LO1 D3(0); + case 3: HI1 D1(1) QLO2(b0,0) D2(0) LO1 D3(0); + case 2: HI1 D1(1) QLO2(b0,0) D2(0) LO1 D3(0); + case 1: HI1 D1(1) QLO2(b0,0) D2(0) LO1 D3(0); + } HI1 D1(1) QLO2(b1, 7) LDSCL3(b2,O2) D2(3) LO1 D3(0) HI1 D1(1) QLO2(b1, 6) PRESCALE4(d2) D2(4) LO1 SCALE22(b2,0) D3(2) HI1 D1(1) QLO2(b1, 5) RORSC24(b2,1) D2(4) LO1 ROR1(b2) CLC1 D3(2) @@ -258,6 +264,12 @@ public: HI1 D1(1) QLO2(b1, 2) SCROR24(b2,5) D2(4) LO1 SCALE22(b2,6) D3(2) HI1 D1(1) QLO2(b1, 1) RORSC24(b2,7) D2(4) LO1 ROR1(b2) CLC1 D3(2) HI1 D1(1) QLO2(b1, 0) IDATA2 D2(2) LO1 VIDADJ2(b2) D3(0) + switch(XTRA0) { + case 4: HI1 D1(1) QLO2(b1,0) D2(0) LO1 D3(0); + case 3: HI1 D1(1) QLO2(b1,0) D2(0) LO1 D3(0); + case 2: HI1 D1(1) QLO2(b1,0) D2(0) LO1 D3(0); + case 1: HI1 D1(1) QLO2(b1,0) D2(0) LO1 D3(0); + } HI1 D1(1) QLO2(b2, 7) LDSCL3(b0,O0) D2(3) LO1 D3(0) HI1 D1(1) QLO2(b2, 6) PRESCALE4(d0) D2(4) LO1 SCALE22(b0,0) D3(2) HI1 D1(1) QLO2(b2, 5) RORSC04(b0,1) D2(4) LO1 ROR1(b0) CLC1 D3(2) @@ -266,6 +278,12 @@ public: HI1 D1(1) QLO2(b2, 2) SCROR04(b0,5) D2(4) LO1 SCALE02(b0,6) D3(2) HI1 D1(1) QLO2(b2, 1) RORSC04(b0,7) D2(4) LO1 ROR1(b0) CLC1 D3(2) HI1 D1(1) QLO2(b2, 0) DCOUNT2 BRLOOP1 D2(3) LO1 D3(2) JMPLOOP2 + switch(XTRA0) { + case 4: HI1 D1(1) QLO2(b1,0) D2(0) LO1 D3(0); + case 3: HI1 D1(1) QLO2(b1,0) D2(0) LO1 D3(0); + case 2: HI1 D1(1) QLO2(b1,0) D2(0) LO1 D3(0); + case 1: HI1 D1(1) QLO2(b1,0) D2(0) LO1 D3(0); + } #else // no inline scaling - non-straight RGB ordering HI1 D1(1) QLO2(b0, 7) LD2(b1,O1) D2(2) LO1 D3(0) -- cgit v1.2.3 From 2e5f90fd114d7498ed19b463c2ab40bd6648df0c Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Sun, 9 Mar 2014 18:09:07 -0700 Subject: Reference/beginning of hardware SPI support for the due, some other code cleanup --- fastpin_arm_sam.h | 3 + fastspi.h | 6 ++ fastspi_arm_k20.h | 3 +- fastspi_arm_sam.h | 162 ++++++++++++++++++++++++++++++++++++++++++++++------ fastspi_ref.h | 98 +++++++++++++++++++++++++++++++ preview_changes.txt | 8 ++- 6 files changed, 257 insertions(+), 23 deletions(-) create mode 100644 fastspi_ref.h diff --git a/fastpin_arm_sam.h b/fastpin_arm_sam.h index 9aad9425..164754c8 100644 --- a/fastpin_arm_sam.h +++ b/fastpin_arm_sam.h @@ -96,6 +96,9 @@ _DEFPIN_DUE(68, 1, A); _DEFPIN_DUE(69, 0, A); _DEFPIN_DUE(70, 17, A); _DEFPIN_DU _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); +#define SPI_DATA 75 +#define SPI_CLOCK 76 +#define ARM_HARDWARE_SPI #define HAS_HARDWARE_PIN_SUPPORT #endif diff --git a/fastspi.h b/fastspi.h index 831bae34..68d74a99 100644 --- a/fastspi.h +++ b/fastspi.h @@ -43,6 +43,7 @@ public: // Include the various specific SPI implementations #include "fastspi_bitbang.h" #include "fastspi_arm_k20.h" +#include "fastspi_arm_sam.h" #include "fastspi_avr.h" #include "fastspi_dma.h" @@ -67,6 +68,11 @@ class SoftwareSPIOutput : public AVRSoftwareSPIOutput<_DATA_PIN, _CLOCK_PIN, _SP template class SPIOutput : public ARMHardwareSPIOutput {}; +#elif defined(__SAM3X8E__) + +template +class SPIOutput : public SAMHardwareSPIOutput {}; + #else template diff --git a/fastspi_arm_k20.h b/fastspi_arm_k20.h index 706755d2..906e1a27 100644 --- a/fastspi_arm_k20.h +++ b/fastspi_arm_k20.h @@ -247,7 +247,7 @@ public: template inline static void writeBit(uint8_t b) { uint32_t ctar1_save = SPI0_CTAR1; - // Clear out the FMSZ bits, reset them for 9 bits transferd for the start bit + // 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); @@ -278,6 +278,7 @@ public: 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++)); } diff --git a/fastspi_arm_sam.h b/fastspi_arm_sam.h index 9b58049d..e9d822c1 100644 --- a/fastspi_arm_sam.h +++ b/fastspi_arm_sam.h @@ -1,60 +1,184 @@ #ifndef __INC_FASTSPI_ARM_SAM_H #define __INC_FASTSPI_ARM_SAM_H +#if defined(__SAM3X8E__) +#define m_SPI ((Spi*)SPI0) + template 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_SPIEN; } + + void readyTransferBits(register byte 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] = (bits << SPI_CSR_BITS_Pos) | SPI_CSR_SCBR(_SPI_CLOCK_DIVIDER); + } + + template static inline void writeBits(uint16_t w) { + waitForEmpty(); + m_SPI->SPI_CSR[0] = (BITS << SPI_CSR_BITS_Pos) | SPI_CSR_SCBR(_SPI_CLOCK_DIVIDER); + m_SPI->SPI_TDR = w; + } public: - SAMHardwareSPIOutput() { /* TODO */ } - SAMHArdwareSPIOutput(Selectable *pSelect) { /* TODO */ } + 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() { /* TODO */ } + void init() { + // m_SPI = SPI0; + + // set the output pins + FastPin<_DATA_PIN>::setOutput(); + FastPin<_CLOCK_PIN>::setOutput(); + release(); + + // Configure the SPI clock, divider between 1-255 + // SCBR = _SPI_CLOCK_DIVIDER + + // Enable writes + enableConfig(); + + // Configure SPI as master, enable + enableSPI(); + + // Only bit in MR we want on is master, everything is left to 0, see commented out psuedocode + m_SPI->SPI_MR = SPI_MR_MSTR; + // SPI_MR.MSTR = 1; set master + // SPI_MR.PS = 0 fixed peripheral select + // SPI_MR.PCSDEC = 0 direct connect CS decode + // SPI_MR.PCS = 0 device 0 + // SPI_MR.DLYBCS = 0; 0 delay between chip selects + + // set inter-transfer delay to 0 + // DLYBCT = 0; + // DLYBS = 0; + + // CSR items + // SPI_CSR0 = 0; + // SPI_CSR0.BITS = 0 (8bit), 1 (9bit), 8 (16bit) + // SPI_CSR0.SCBR = _SPI_CLOCK_DIVIDER + // SPI_CSR0.DLYBS = 0, SPI_CSR0.DLYBCT = 0 + + } // latch the CS select - void select() { /* TODO */ } + void inline select() __attribute__((always_inline)) { if(m_pSelect != NULL) { m_pSelect->select(); } } // release the CS select - void release() { /* TODO */ } + void inline release() __attribute__((always_inline)) { if(m_pSelect != NULL) { m_pSelect->release(); } } // wait until all queued up data has been written - void waitFully(); + void waitFully() { while((m_SPI->SPI_SR & SPI_SR_TXEMPTY) == 0); } // write a byte out via SPI (returns immediately on writing register) - void writeByte(uint8_t b) { /* TODO */ } + static void writeByte(uint8_t b) { + writeBits<8>(b); + } + // write a word out via SPI (returns immediately on writing register) - void writeWord(uint16_t w) { /* TODO */ } + static void writeWord(uint16_t w) { + writeBits<16>(w); + } // A raw set of writing byte values, assumes setup/init/waiting done elsewhere - void writeBytesValueRaw(uint8_t value, int len) { /* TODO */ } + 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) { /* TODO */ } + void writeBytesValue(uint8_t value, int len) { + select(); writeBytesValueRaw(value, len); release(); + } + + template 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(); + } - // A full cycle of writing a raw block of data out, including select, release, and waiting - void writeBytes(uint8_t *data, int len) { /* TODO */ } + void writeBytes(register uint8_t *data, int len) { writeBytes(data, len); } // write a single bit out, which bit from the passed in byte is determined by template parameter - template inline static void writeBit(uint8_t b) { /* TODO */ } + // not the most efficient mechanism in the world - but should be enough for sm16716 and friends + template 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(); + } - template void writeBytes3(register uint8_t *data, int len, register uint8_t scale, bool advance=true, uint8_t skip=0) { /* TODO*/ } + 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 void writeBytes3(register uint8_t *data, int len, register CRGB scale, bool advance=true, uint8_t skip=0) { + select(); + uint8_t *end = data + len; + + // Setup the pixel controller + PixelController pixels(data, scale, true, advance, skip); + + while(data != end) { + 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(); + data += (3+skip); + } + D::postBlock(len); + release(); + } // template instantiations for writeBytes 3 - template void writeBytes3(register uint8_t *data, int len, register uint8_t scale, bool advance=true, uint8_t skip=0) { - writeBytes3(data, len, scale, advance, skip); + template void writeBytes3(register uint8_t *data, int len, register CRGB scale, bool advance=true, uint8_t skip=0) { + writeBytes3(data, len, scale, advance, skip); } - template void writeBytes3(register uint8_t *data, int len, register uint8_t scale, bool advance=true, uint8_t skip=0) { + template void writeBytes3(register uint8_t *data, int len, register CRGB scale, bool advance=true, uint8_t skip=0) { writeBytes3<0, D, RGB_ORDER>(data, len, scale, advance, skip); } - template void writeBytes3(register uint8_t *data, int len, register uint8_t scale, bool advance=true, uint8_t skip=0) { + template void writeBytes3(register uint8_t *data, int len, register CRGB scale, bool advance=true, uint8_t skip=0) { writeBytes3<0, DATA_NOP, RGB_ORDER>(data, len, scale, advance, skip); } - void writeBytes3(register uint8_t *data, int len, register uint8_t scale, bool advance=true, uint8_t skip=0) { + void writeBytes3(register uint8_t *data, int len, register CRGB scale, bool advance=true, uint8_t skip=0) { writeBytes3<0, DATA_NOP, RGB>(data, len, scale, advance, skip); + } }; +#endif + #endif \ No newline at end of file diff --git a/fastspi_ref.h b/fastspi_ref.h new file mode 100644 index 00000000..709bec34 --- /dev/null +++ b/fastspi_ref.h @@ -0,0 +1,98 @@ +#ifndef __INC_FASTSPI_ARM_SAM_H +#define __INC_FASTSPI_ARM_SAM_H + +// A skeletal implementation of hardware SPI support. Fill in the necessary code for init, waiting, and writing. The rest of +// the method implementations should provide a starting point, even if not hte most efficient to start with +template +class REFHardwareSPIOutput { + Selectable *m_pSelect; +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() { /* TODO */ } + + // 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 + static void waitFully() { /* TODO */ } + + // write a byte out via SPI (returns immediately on writing register) + static void writeByte(uint8_t b) { /* TODO */ } + + // write a word out via SPI (returns immediately on writing register) + static void writeWord(uint16_t w) { /* TODO */ } + + // 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(); + } + + // A full cycle of writing a value for len bytes, including select, release, and waiting + template 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(); + } + + // A full cycle of writing a value for len bytes, including select, release, and waiting + void writeBytes(register uint8_t *data, int len) { writeBytes(data, len); } + + // write a single bit out, which bit from the passed in byte is determined by template parameter + template inline static void writeBit(uint8_t b) { /* TODO */ } + + // 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 void writeBytes3(register uint8_t *data, int len, register CRGB scale, bool advance=true, uint8_t skip=0) { + select(); + while(data != end) { + 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(); + data += (3+skip); + } + D::postBlock(len); + release(); + } + + // template instantiations for writeBytes 3 + template void writeBytes3(register uint8_t *data, int len, register CRGB scale, bool advance=true, uint8_t skip=0) { + writeBytes3(data, len, scale, advance, skip); + } + template void writeBytes3(register uint8_t *data, int len, register CRGB scale, bool advance=true, uint8_t skip=0) { + writeBytes3<0, D, RGB_ORDER>(data, len, scale, advance, skip); + } + template void writeBytes3(register uint8_t *data, int len, register CRGB scale, bool advance=true, uint8_t skip=0) { + writeBytes3<0, DATA_NOP, RGB_ORDER>(data, len, scale, advance, skip); + } + void writeBytes3(register uint8_t *data, int len, register CRGB scale, bool advance=true, uint8_t skip=0) { + writeBytes3<0, DATA_NOP, RGB>(data, len, scale, advance, skip); + +}; + +#endif \ No newline at end of file diff --git a/preview_changes.txt b/preview_changes.txt index 60562fef..2866abbd 100644 --- a/preview_changes.txt +++ b/preview_changes.txt @@ -1,7 +1,9 @@ * ALL UNTESTED, USE AT YOUR OWN RISK! -* Preliminary teensy 3.1 support -* Preliminary due support (no hardware SPI, yet) -* Preliminary P9813 (aka Cool Neon Total Control Lighting support) +* RGB based scaling, allow for color balancing +* (The moon) dithering support +* Teensy 3.1 support +* Due support +* P9813 (aka Cool Neon Total Control Lighting support) * Preliminary 2-way ws2812 support * Preliminary n-way clockless support on due * Preliminary TM1829 support (broken, don't use!) -- cgit v1.2.3 From 0bb025ef288e09173a06e74f4e647f479e555d9d Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Mon, 10 Mar 2014 17:27:55 -0700 Subject: Due hardware SPI, FTW\! --- examples/Cylon/Cylon.ino | 2 +- fastspi_arm_sam.h | 55 +++++++++++++++++++----------------------------- 2 files changed, 23 insertions(+), 34 deletions(-) diff --git a/examples/Cylon/Cylon.ino b/examples/Cylon/Cylon.ino index 3f066425..94cb7541 100644 --- a/examples/Cylon/Cylon.ino +++ b/examples/Cylon/Cylon.ino @@ -13,7 +13,7 @@ CRGB leds[NUM_LEDS]; void setup() { - FastLED.addLeds(leds, NUM_LEDS); + FastLED.addLeds(leds, NUM_LEDS); } void loop() { diff --git a/fastspi_arm_sam.h b/fastspi_arm_sam.h index e9d822c1..5b205e0f 100644 --- a/fastspi_arm_sam.h +++ b/fastspi_arm_sam.h @@ -13,20 +13,20 @@ class SAMHardwareSPIOutput { 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_SPIEN; } + 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; } - void readyTransferBits(register byte bits) { + static inline void readyTransferBits(register byte 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] = (bits << SPI_CSR_BITS_Pos) | SPI_CSR_SCBR(_SPI_CLOCK_DIVIDER); + 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 static inline void writeBits(uint16_t w) { - waitForEmpty(); - m_SPI->SPI_CSR[0] = (BITS << SPI_CSR_BITS_Pos) | SPI_CSR_SCBR(_SPI_CLOCK_DIVIDER); - m_SPI->SPI_TDR = w; + readyTransferBits(BITS); + m_SPI->SPI_TDR = (uint32_t)w | SPI_PCS(0); } public: @@ -40,38 +40,28 @@ public: void init() { // m_SPI = SPI0; - // set the output pins - FastPin<_DATA_PIN>::setOutput(); - FastPin<_CLOCK_PIN>::setOutput(); + // 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(); - // Enable writes - enableConfig(); + // reset twice (what the sam code does, not sure why?) + resetSPI(); + resetSPI(); // Configure SPI as master, enable - enableSPI(); - - // Only bit in MR we want on is master, everything is left to 0, see commented out psuedocode - m_SPI->SPI_MR = SPI_MR_MSTR; - // SPI_MR.MSTR = 1; set master - // SPI_MR.PS = 0 fixed peripheral select - // SPI_MR.PCSDEC = 0 direct connect CS decode - // SPI_MR.PCS = 0 device 0 - // SPI_MR.DLYBCS = 0; 0 delay between chip selects - - // set inter-transfer delay to 0 - // DLYBCT = 0; - // DLYBS = 0; - - // CSR items - // SPI_CSR0 = 0; - // SPI_CSR0.BITS = 0 (8bit), 1 (9bit), 8 (16bit) - // SPI_CSR0.SCBR = _SPI_CLOCK_DIVIDER - // SPI_CSR0.DLYBS = 0, SPI_CSR0.DLYBCT = 0 + // 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(); } // latch the CS select @@ -145,8 +135,7 @@ public: while(data != end) { if(FLAGS & FLAG_START_BIT) { - writeBit<0>(1); - writeByte(D::adjust(pixels.loadAndScale0())); + writeBits<9>((1<<8) | D::adjust(pixels.loadAndScale0())); writeByte(D::adjust(pixels.loadAndScale1())); writeByte(D::adjust(pixels.loadAndScale2())); } else { -- cgit v1.2.3 From a0f7b92622717e026503b1bb364752cf328bf118 Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Mon, 10 Mar 2014 20:11:33 -0700 Subject: Fix math noise error --- clockless_trinket.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clockless_trinket.h b/clockless_trinket.h index 1222106f..15746913 100644 --- a/clockless_trinket.h +++ b/clockless_trinket.h @@ -30,7 +30,7 @@ template __attribute__((always_inline)) inline void _dc(register uin _dc_AVR(loopvar); } template<> __attribute__((always_inline)) inline void _dc<0>(register uint8_t & loopvar) {} -template<> __attribute__((always_inline)) inline void _dc<1>(register uint8_t & loopvar) {asm __volatile__("cp r0,r0":::);} +template<> __attribute__((always_inline)) inline void _dc<1>(register uint8_t & loopvar) {asm __volatile__("mov r0,r0":::);} template<> __attribute__((always_inline)) inline void _dc<2>(register uint8_t & loopvar) {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); } -- cgit v1.2.3 From acef646ca264792887523e02f0dbcd7cb44812cd Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Mon, 10 Mar 2014 20:34:38 -0700 Subject: Cleaning up some of the SAM hardware SPI bits --- fastspi_arm_sam.h | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/fastspi_arm_sam.h b/fastspi_arm_sam.h index 5b205e0f..a0d9fdc4 100644 --- a/fastspi_arm_sam.h +++ b/fastspi_arm_sam.h @@ -17,7 +17,7 @@ class SAMHardwareSPIOutput { void disableSPI() { m_SPI->SPI_CR = SPI_CR_SPIDIS; } void resetSPI() { m_SPI->SPI_CR = SPI_CR_SWRST; } - static inline void readyTransferBits(register byte bits) { + 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(); @@ -25,7 +25,7 @@ class SAMHardwareSPIOutput { } template static inline void writeBits(uint16_t w) { - readyTransferBits(BITS); + waitForEmpty(); m_SPI->SPI_TDR = (uint32_t)w | SPI_PCS(0); } @@ -62,6 +62,9 @@ public: 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 @@ -133,20 +136,24 @@ public: // Setup the pixel controller PixelController pixels(data, scale, true, advance, skip); - while(data != end) { - if(FLAGS & FLAG_START_BIT) { + if(FLAGS & FLAG_START_BIT) { + while(data < end) { writeBits<9>((1<<8) | D::adjust(pixels.loadAndScale0())); writeByte(D::adjust(pixels.loadAndScale1())); writeByte(D::adjust(pixels.loadAndScale2())); - } else { + pixels.advanceData(); + pixels.stepDithering(); + data += (3+skip); + } + } else { + while(data < end) { writeByte(D::adjust(pixels.loadAndScale0())); writeByte(D::adjust(pixels.loadAndScale1())); writeByte(D::adjust(pixels.loadAndScale2())); + pixels.advanceData(); + pixels.stepDithering(); + data += (3+skip); } - - pixels.advanceData(); - pixels.stepDithering(); - data += (3+skip); } D::postBlock(len); release(); -- cgit v1.2.3 From 17799cb623c595d62f53c3a72710645aeeaea872 Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Tue, 11 Mar 2014 11:39:26 -0700 Subject: Fix up trinket dithering/timing/flag states --- clockless_trinket.h | 108 +++++++++++++++++++++++++++++----------------------- 1 file changed, 60 insertions(+), 48 deletions(-) diff --git a/clockless_trinket.h b/clockless_trinket.h index 15746913..26210f24 100644 --- a/clockless_trinket.h +++ b/clockless_trinket.h @@ -13,8 +13,6 @@ #define TRINKET_SCALE 1 // whether or not to use dithering #define DITHER 1 -// whether or not to enable scale_video adjustments -#define SCALE_VIDEO 0 #endif // Variations on the functions in delay.h - w/a loop var passed in to preserve registers across calls by the optimizer/compiler @@ -22,12 +20,17 @@ template inline void _dc(register uint8_t & loopvar); template inline void _dc_AVR(register uint8_t & loopvar) { _dc(loopvar); - asm __volatile__ ( "LDI %[loopvar], %[_LOOP]\n\tL_%=: DEC %[loopvar]\n\t BRNE L_%=\n\t" : + // 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\tL_%=: DEC %[loopvar]\n\t BRNE L_%=\n\tBSET 0\n\t" + "L_DONE%=:\n\t" + : [loopvar] "+a" (loopvar) : [_LOOP] "M" (_LOOP) : ); } template __attribute__((always_inline)) inline void _dc(register uint8_t & loopvar) { - _dc_AVR(loopvar); + _dc_AVR(loopvar); } template<> __attribute__((always_inline)) inline void _dc<0>(register uint8_t & loopvar) {} template<> __attribute__((always_inline)) inline void _dc<1>(register uint8_t & loopvar) {asm __volatile__("mov r0,r0":::);} @@ -38,6 +41,8 @@ template<> __attribute__((always_inline)) inline void _dc<5>(register uint8_t & 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); } #define D1(ADJ) _dc(loopvar); #define D2(ADJ) _dc(loopvar); @@ -106,6 +111,9 @@ public: [b0] "+a" (b0), \ [b1] "+a" (b1), \ [b2] "+a" (b2), \ + [d0] "+r" (d0), \ + [d1] "+r" (d1), \ + [d2] "+r" (d2), \ [scale_base] "+a" (scale_base), \ [loopvar] "+a" (loopvar) \ : /* use variables */ \ @@ -115,9 +123,6 @@ public: [s0] "r" (s0), \ [s1] "r" (s1), \ [s2] "r" (s2), \ - [d0] "r" (pixels.d[RO(0)]), \ - [d1] "r" (pixels.d[RO(1)]), \ - [d2] "r" (pixels.d[RO(2)]), \ [PORT] "M" (FastPin::port()-0x20), \ [O0] "M" (RGB_BYTE0(RGB_ORDER)), \ [O1] "M" (RGB_BYTE1(RGB_ORDER)), \ @@ -126,15 +131,15 @@ public: // 1 cycle, write hi to the port -#define HI1 if((int)(FastPin::port()) < 64) { asm __volatile__("out %[PORT], %[hi]" ASM_VARS ); } else { *FastPin::port()=hi; } +#define HI1 if((int)(FastPin::port())-0x20 < 64) { asm __volatile__("out %[PORT], %[hi]" ASM_VARS ); } else { *FastPin::port()=hi; } // 1 cycle, write lo to the port -#define LO1 if((int)(FastPin::port()) < 64) { asm __volatile__("out %[PORT], %[lo]" ASM_VARS ); } else { *FastPin::port()=lo; } +#define LO1 if((int)(FastPin::port())-0x20 < 64) { asm __volatile__("out %[PORT], %[lo]" ASM_VARS ); } else { *FastPin::port()=lo; } // 2 cycles, sbrs on flipping the lne 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 "]" ASM_VARS ); -// 3 cycles - load a byte from ram into the scaling scratch space with the given offset, clear the target var -#define LDSCL3(B,O) asm __volatile__("ldd %[scale_base], Z + %[" #O "]\n\tclr %[" #B "]" 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" ASM_VARS ); // 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) asm __volatile__("sbrc %[s0], " #N "\n\tadd %[" #B "], %[scale_base]" ASM_VARS ); #define SCALE12(B, N) asm __volatile__("sbrc %[s1], " #N "\n\tadd %[" #B "], %[scale_base]" ASM_VARS ); @@ -144,12 +149,13 @@ public: #define PRESCALE4(D) if(DITHER) { 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); } \ else { _dc<4>(loopvar); } -// Do a (rough) approximation of the nscale8_video jump -#if (SCALE_VIDEO == 1) -#define VIDADJ2(B) asm __volatile__("cpse %[scale_base], __zero_reg__\n\tsubi %[" #B "], 0xFF\n\t" ASM_VARS); -#else -#define VIDADJ2(B) asm __volatile__("rjmp .+0" ASM_VARS); -#endif +// Do the add for the prescale +#define PRESCALEA2(D) if(DITHER) { asm __volatile__("cpse %[scale_base], __zero_reg__\n\t add %[scale_base],%[" #D "]\n\t" ASM_VARS); } \ + else { _dc<2>(loopvar); } +// Do the clamp for the prescale, clear carry when we're done - NOTE: Must ensure carry flag state is preserved! +#define PRESCALEB3(D) if(DITHER) { asm __volatile__("brcc L_%=\n\tldi %[scale_base], 0xFF\n\tL_%=:\n\tCLC" ASM_VARS); } \ + else { _dc<3>(loopvar); } + // 1 cycle - rotate right, pulling in from carry #define ROR1(B) asm __volatile__("ror %[" #B "]" ASM_VARS ); @@ -221,6 +227,13 @@ public: uint8_t s0 = scale.raw[RO(0)]; uint8_t s1 = scale.raw[RO(1)]; uint8_t s2 = scale.raw[RO(2)]; + 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)]; + register uint8_t loopvar=0; { @@ -228,10 +241,10 @@ public: // Loop beginning, does some stuff that's outside of the pixel write cycle, namely incrementing d0-2 and masking off // by the E values (see the definition ) LOOP; - ADJDITHER2(pixels.d[RO(0)],pixels.e[RO(0)]) - ADJDITHER2(pixels.d[RO(1)],pixels.e[RO(1)]) - ADJDITHER2(pixels.d[RO(2)],pixels.e[RO(2)]) - VIDADJ2(b0); + ADJDITHER2(d0,e0); + ADJDITHER2(d1,e1); + ADJDITHER2(d2,e2); + // CLC1; // 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. @@ -242,48 +255,48 @@ public: // we're cycling back around and doing the above for byte 0. #if TRINKET_SCALE // Inline scaling - RGB ordering - HI1 D1(1) QLO2(b0, 7) LDSCL3(b1,O1) D2(3) LO1 D3(0) - HI1 D1(1) QLO2(b0, 6) PRESCALE4(d1) D2(4) LO1 SCALE12(b1,0) D3(2) + HI1 D1(1) QLO2(b0, 7) LDSCL4(b1,O1) D2(3) LO1 PRESCALEA2(d1) D3(2) + HI1 D1(1) QLO2(b0, 6) PRESCALEB3(d1) D2(3) LO1 SCALE12(b1,0) D3(2) HI1 D1(1) QLO2(b0, 5) RORSC14(b1,1) D2(4) LO1 ROR1(b1) CLC1 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 ROR1(b1) CLC1 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 ROR1(b1) CLC1 D3(2) - HI1 D1(1) QLO2(b0, 0) D2(0) LO1 VIDADJ2(b1) D3(2) - switch(XTRA0) { - case 4: HI1 D1(1) QLO2(b0,0) D2(0) LO1 D3(0); - case 3: HI1 D1(1) QLO2(b0,0) D2(0) LO1 D3(0); - case 2: HI1 D1(1) QLO2(b0,0) D2(0) LO1 D3(0); - case 1: HI1 D1(1) QLO2(b0,0) D2(0) LO1 D3(0); - } - HI1 D1(1) QLO2(b1, 7) LDSCL3(b2,O2) D2(3) LO1 D3(0) - HI1 D1(1) QLO2(b1, 6) PRESCALE4(d2) D2(4) LO1 SCALE22(b2,0) D3(2) + HI1 D1(1) QLO2(b0, 0) D2(0) LO1 D3(0) + // switch(XTRA0) { + // case 4: HI1 D1(1) QLO2(b0,0) D2(0) LO1 D3(0); + // case 3: HI1 D1(1) QLO2(b0,0) D2(0) LO1 D3(0); + // case 2: HI1 D1(1) QLO2(b0,0) D2(0) LO1 D3(0); + // case 1: HI1 D1(1) QLO2(b0,0) D2(0) LO1 D3(0); + // } + HI1 D1(1) QLO2(b1, 7) LDSCL4(b2,O2) D2(3) LO1 PRESCALEA2(d2) D3(2) + HI1 D1(1) QLO2(b1, 6) PRESCALEB3(d2) D2(3) LO1 SCALE22(b2,0) D3(2) HI1 D1(1) QLO2(b1, 5) RORSC24(b2,1) D2(4) LO1 ROR1(b2) CLC1 D3(2) HI1 D1(1) QLO2(b1, 4) SCROR24(b2,2) D2(4) LO1 SCALE22(b2,3) D3(2) HI1 D1(1) QLO2(b1, 3) RORSC24(b2,4) D2(4) LO1 ROR1(b2) CLC1 D3(2) HI1 D1(1) QLO2(b1, 2) SCROR24(b2,5) D2(4) LO1 SCALE22(b2,6) D3(2) HI1 D1(1) QLO2(b1, 1) RORSC24(b2,7) D2(4) LO1 ROR1(b2) CLC1 D3(2) - HI1 D1(1) QLO2(b1, 0) IDATA2 D2(2) LO1 VIDADJ2(b2) D3(0) - switch(XTRA0) { - case 4: HI1 D1(1) QLO2(b1,0) D2(0) LO1 D3(0); - case 3: HI1 D1(1) QLO2(b1,0) D2(0) LO1 D3(0); - case 2: HI1 D1(1) QLO2(b1,0) D2(0) LO1 D3(0); - case 1: HI1 D1(1) QLO2(b1,0) D2(0) LO1 D3(0); - } - HI1 D1(1) QLO2(b2, 7) LDSCL3(b0,O0) D2(3) LO1 D3(0) - HI1 D1(1) QLO2(b2, 6) PRESCALE4(d0) D2(4) LO1 SCALE22(b0,0) D3(2) + HI1 D1(1) QLO2(b1, 0) IDATA2 CLC1 D2(3) LO1 D3(0) + // switch(XTRA0) { + // case 4: HI1 D1(1) QLO2(b1,0) D2(0) LO1 D3(0); + // case 3: HI1 D1(1) QLO2(b1,0) D2(0) LO1 D3(0); + // case 2: HI1 D1(1) QLO2(b1,0) D2(0) LO1 D3(0); + // case 1: HI1 D1(1) QLO2(b1,0) D2(0) LO1 D3(0); + // } + HI1 D1(1) QLO2(b2, 7) LDSCL4(b0,O0) D2(3) LO1 PRESCALEA2(d0) D3(2) + HI1 D1(1) QLO2(b2, 6) PRESCALEB3(d0) D2(3) LO1 SCALE02(b0,0) D3(2) HI1 D1(1) QLO2(b2, 5) RORSC04(b0,1) D2(4) LO1 ROR1(b0) CLC1 D3(2) HI1 D1(1) QLO2(b2, 4) SCROR04(b0,2) D2(4) LO1 SCALE02(b0,3) D3(2) HI1 D1(1) QLO2(b2, 3) RORSC04(b0,4) D2(4) LO1 ROR1(b0) CLC1 D3(2) HI1 D1(1) QLO2(b2, 2) SCROR04(b0,5) D2(4) LO1 SCALE02(b0,6) D3(2) HI1 D1(1) QLO2(b2, 1) RORSC04(b0,7) D2(4) LO1 ROR1(b0) CLC1 D3(2) HI1 D1(1) QLO2(b2, 0) DCOUNT2 BRLOOP1 D2(3) LO1 D3(2) JMPLOOP2 - switch(XTRA0) { - case 4: HI1 D1(1) QLO2(b1,0) D2(0) LO1 D3(0); - case 3: HI1 D1(1) QLO2(b1,0) D2(0) LO1 D3(0); - case 2: HI1 D1(1) QLO2(b1,0) D2(0) LO1 D3(0); - case 1: HI1 D1(1) QLO2(b1,0) D2(0) LO1 D3(0); - } + // switch(XTRA0) { + // case 4: HI1 D1(1) QLO2(b1,0) D2(0) LO1 D3(0); + // case 3: HI1 D1(1) QLO2(b1,0) D2(0) LO1 D3(0); + // case 2: HI1 D1(1) QLO2(b1,0) D2(0) LO1 D3(0); + // case 1: HI1 D1(1) QLO2(b1,0) D2(0) LO1 D3(0); + // } #else // no inline scaling - non-straight RGB ordering HI1 D1(1) QLO2(b0, 7) LD2(b1,O1) D2(2) LO1 D3(0) @@ -315,7 +328,6 @@ public: D2(4) LO1 D3(0) } } - // save the d values // d[0] = d0; // d[1] = d1; -- cgit v1.2.3 From 5ff29548312ed8621fe08d67e22939938e9a5ecf Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Tue, 11 Mar 2014 12:08:34 -0700 Subject: First pass at color/temperature correction code --- FastLED.cpp | 6 ++++-- color.h | 51 ++++++++++++++++++++++++++++++++++++++++++++++++ controller.h | 44 ++++++++++++++++++++++++++++++++++++++++- examples/Cylon/Cylon.ino | 4 ++-- pixeltypes.h | 13 ++++++++++++ 5 files changed, 113 insertions(+), 5 deletions(-) create mode 100644 color.h diff --git a/FastLED.cpp b/FastLED.cpp index 539bd5d6..a361c80a 100644 --- a/FastLED.cpp +++ b/FastLED.cpp @@ -51,7 +51,8 @@ void CFastLED::show(CRGB scale) { for(int i = 0; i < m_nControllers; i++) { if(m_Controllers[i].pLedController != NULL) { m_Controllers[i].pLedController->show(m_Controllers[i].pLedData + m_Controllers[i].nOffset, - m_Controllers[i].nLeds, scale); + m_Controllers[i].nLeds, + m_Controllers[i].pLedController->getAdjustment(scale)); } else { return; } @@ -61,7 +62,8 @@ void CFastLED::show(CRGB scale) { void CFastLED::showColor(const struct CRGB & color, CRGB scale) { for(int i = 0; i < m_nControllers; i++) { if(m_Controllers[i].pLedController != NULL) { - m_Controllers[i].pLedController->showColor(color, m_Controllers[i].nLeds, scale); + m_Controllers[i].pLedController->showColor(color, m_Controllers[i].nLeds, + m_Controllers[i].pLedController->getAdjustment(scale)); } else { return; } diff --git a/color.h b/color.h new file mode 100644 index 00000000..1b40cec5 --- /dev/null +++ b/color.h @@ -0,0 +1,51 @@ +#ifndef __INC_COLOR_H +#define __INC_COLOR_H + +// definitions for color correction and light temperatures + +typedef enum { + // Color correction starting points + + // typical values for SMD5050 LEDs + SMD5050=0xFFA0F0 /* 255, 160, 240 */, + + // typical values for 8.25mm "pixels on a string" + // also for many through-hole T3 package LEDs + Pixel8MM=0xFFE08C /* 255, 224, 140 */, + + // uncorrected color + UncorrectedColor=0xFFFFFF +} LEDColorCorrection; + + +typedef enum { + // Black-body radiation light sources emit a (relatively) continuous + // spectrum, and can be described as having a Kelvin 'temperature' + Candle=0xFF9329 /* 1900 K, 255, 147, 41 */, + Tungsten40W=0xFFC58F /* 2600 K, 255, 197, 143 */, + Tungsten100W=0xFFD6AA /* 2850 K, 255, 214, 170 */, + Halogen=0xFFF1E0 /* 3200 K, 255, 241, 224 */, + CarbonArc=0xFFFAF4 /* 5200 K, 255, 250, 244 */, + HighNoonSun=0xFFFFFB /* 5400 K, 255, 255, 251 */, + DirectSunlight=0xFFFFFF /* 6000 K, 255, 255, 255 */, + OvercastSky=0xC9E2FF /* 7000 K, 201, 226, 255 */, + ClearBlueSky=0x409CFF /* 20000 K, 64, 156, 255 */, + + // Gaseous light sources emit discrete spectral bands, and while we can + // approximate their aggregate hue with RGB values, they don't actually + // have a proper Kelvin temperature. + WarmFluorescent=0xFFF4E5 /* 0 K, 255, 244, 229 */, + StandardFluorescent=0xF4FFFA /* 0 K, 244, 255, 250 */, + CoolWhiteFluorescent=0xD4EBFF /* 0 K, 212, 235, 255 */, + FullSpectrumFluorescent=0xFFF4F2 /* 0 K, 255, 244, 242 */, + GrowLightFluorescent=0xFFEFF7 /* 0 K, 255, 239, 247 */, + BlackLightFluorescent=0xA700FF /* 0 K, 167, 0, 255 */, + MercuryVapor=0xD8F7FF /* 0 K, 216, 247, 255 */, + SodiumVapor=0xFFD1B2 /* 0 K, 255, 209, 178 */, + MetalHalide=0xF2FCFF /* 0 K, 242, 252, 255 */, + HighPressureSodium=0xFFB74C /* 0 K, 255, 183, 76 */, + + // Uncorrected temperature 0xFFFFFF + UncorrectedTemperature=0xFFFFFF +} ColorTemperature; +#endif \ No newline at end of file diff --git a/controller.h b/controller.h index e51d8cdc..a7967176 100644 --- a/controller.h +++ b/controller.h @@ -3,6 +3,7 @@ #include "led_sysdefs.h" #include "pixeltypes.h" +#include "color.h" #define RO(X) RGB_BYTE(RGB_ORDER, X) #define RGB_BYTE(RO,X) (((RO)>>(3*(2-(X)))) & 0x3) @@ -26,7 +27,12 @@ /// to methods, make them references to this type, keeps your code saner. However, most people won't be seeing/using these objects /// directly at all class CLEDController { + CRGB m_ColorCorrection; + CRGB m_ColorTemperature; + public: + CLEDController() : m_ColorCorrection(UncorrectedColor), m_ColorTemperature(UncorrectedTemperature) {} + // initialize the LED controller virtual void init() = 0; @@ -54,6 +60,41 @@ public: // wait until the controller is ready to write data out virtual void wait() { return; } + virtual CLEDController & setCorrection(CRGB correction) { m_ColorCorrection = correction; return *this; } + virtual CLEDController & setCorrection(LEDColorCorrection correction) { m_ColorCorrection = correction; return *this; } + virtual CRGB getCorrection() { return m_ColorCorrection; } + + virtual CLEDController & setTemperature(CRGB temperature) { m_ColorTemperature = temperature; return *this; } + virtual CLEDController & setTemperature(ColorTemperature temperature) { m_ColorTemperature = temperature; return *this; } + virtual CRGB getTemperature() { return m_ColorTemperature; } + + virtual CRGB getAdjustment(CRGB scale) { + // if(1) return scale; + uint32_t r = ((uint32_t)m_ColorCorrection.r * (uint32_t)m_ColorTemperature.r * (uint32_t)scale.r) / (uint32_t)0x10000L; + uint32_t g = ((uint32_t)m_ColorCorrection.g * (uint32_t)m_ColorTemperature.g * (uint32_t)scale.g) / (uint32_t)0x10000L; + uint32_t b = ((uint32_t)m_ColorCorrection.b * (uint32_t)m_ColorTemperature.b * (uint32_t)scale.b) / (uint32_t)0x10000L; + + // static int done = 0; + // if(!done) { + // done = 1; + // Serial.print("Correction: "); + // Serial.print(m_ColorCorrection.r); Serial.print(" "); + // Serial.print(m_ColorCorrection.g); Serial.print(" "); + // Serial.print(m_ColorCorrection.b); Serial.println(" "); + // Serial.print("Temperature: "); + // Serial.print(m_ColorTemperature.r); Serial.print(" "); + // Serial.print(m_ColorTemperature.g); Serial.print(" "); + // Serial.print(m_ColorTemperature.b); Serial.println(" "); + // Serial.print("Scale: "); + // Serial.print(scale.r); Serial.print(" "); + // Serial.print(scale.g); Serial.print(" "); + // Serial.print(scale.b); Serial.println(" "); + // Serial.print("Combined: "); + // Serial.print(r); Serial.print(" "); Serial.print(g); Serial.print(" "); Serial.print(b); Serial.println(); + // } + return CRGB(r,g,b); + } + }; // Pixel controller class. This is the class that we use to centralize pixel access in a block of data, including @@ -92,7 +133,8 @@ struct PixelController { if(R & 0x80) { Q |= 0x01; } // setup the seed d and e values - for(int i = 0; i < 3; i++) { byte s = mScale.raw[i]; + for(int i = 0; i < 3; i++) { + byte s = mScale.raw[i]; e[i] = s ? (256/s) + 1 : 0; d[i] = scale8(Q, e[i]); if(e[i]) e[i]--; diff --git a/examples/Cylon/Cylon.ino b/examples/Cylon/Cylon.ino index 94cb7541..28cd0026 100644 --- a/examples/Cylon/Cylon.ino +++ b/examples/Cylon/Cylon.ino @@ -1,7 +1,7 @@ #include "FastLED.h" // How many leds in your strip? -#define NUM_LEDS 40 +#define NUM_LEDS 8 // For led chips like Neopixels, which have a data line, ground, and power, you just // need to define DATA_PIN. For led chipsets that are SPI based (four wires - data, clock, @@ -13,7 +13,7 @@ CRGB leds[NUM_LEDS]; void setup() { - FastLED.addLeds(leds, NUM_LEDS); + FastLED.addLeds(leds, NUM_LEDS); } void loop() { diff --git a/pixeltypes.h b/pixeltypes.h index e1dfa610..67689b12 100644 --- a/pixeltypes.h +++ b/pixeltypes.h @@ -3,6 +3,7 @@ #include #include "lib8tion.h" +#include "color.h" struct CRGB; struct CHSV; @@ -113,6 +114,18 @@ struct CRGB { { } + inline CRGB( LEDColorCorrection colorcode) __attribute__((always_inline)) + : r((colorcode >> 16) & 0xFF), g((colorcode >> 8) & 0xFF), b((colorcode >> 0) & 0xFF) + { + + } + + inline CRGB( ColorTemperature colorcode) __attribute__((always_inline)) + : r((colorcode >> 16) & 0xFF), g((colorcode >> 8) & 0xFF), b((colorcode >> 0) & 0xFF) + { + + } + // allow copy construction inline CRGB(const CRGB& rhs) __attribute__((always_inline)) { -- cgit v1.2.3 From ff1d48b314ea14e73f2f14762fab01c087e9ee20 Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Tue, 11 Mar 2014 12:28:07 -0700 Subject: Make FastLED.addLeds return a reference instead of a pointer. --- FastLED.cpp | 5 ++--- FastLED.h | 27 ++++++++++++--------------- 2 files changed, 14 insertions(+), 18 deletions(-) diff --git a/FastLED.cpp b/FastLED.cpp index a361c80a..4db607a6 100644 --- a/FastLED.cpp +++ b/FastLED.cpp @@ -18,7 +18,7 @@ CFastLED::CFastLED() { memset8(m_Controllers, 0, m_nControllers * sizeof(CControllerInfo)); } -CLEDController *CFastLED::addLeds(CLEDController *pLed, +CLEDController &CFastLED::addLeds(CLEDController *pLed, const struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset) { int nOffset = (nLedsIfOffset > 0) ? nLedsOrOffset : 0; @@ -41,10 +41,9 @@ CLEDController *CFastLED::addLeds(CLEDController *pLed, m_Controllers[target].nOffset = nOffset; m_Controllers[target].nLeds = nLeds; pLed->init(); - return pLed; } - return NULL; + return *pLed; } void CFastLED::show(CRGB scale) { diff --git a/FastLED.h b/FastLED.h index 78bb77c7..94c2d2e1 100644 --- a/FastLED.h +++ b/FastLED.h @@ -59,9 +59,9 @@ class CFastLED { public: CFastLED(); - CLEDController *addLeds(CLEDController *pLed, const struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0); + CLEDController &addLeds(CLEDController *pLed, const struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0); - template CLEDController *addLeds(const struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) { + template CLEDController &addLeds(const struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) { switch(CHIPSET) { case LPD8806: { static LPD8806Controller c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); } case WS2801: { static WS2801Controller c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); } @@ -69,7 +69,7 @@ public: } } - template CLEDController *addLeds(const struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) { + template CLEDController &addLeds(const struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) { switch(CHIPSET) { case LPD8806: { static LPD8806Controller c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); } case WS2801: { static WS2801Controller c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); } @@ -78,7 +78,7 @@ public: } } - template CLEDController *addLeds(const struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) { + template CLEDController &addLeds(const struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) { switch(CHIPSET) { case LPD8806: { static LPD8806Controller c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); } case WS2801: { static WS2801Controller c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); } @@ -88,22 +88,22 @@ public: } #ifdef SPI_DATA - template CLEDController *addLeds(const struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) { + template CLEDController &addLeds(const struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) { return addLeds(data, nLedsOrOffset, nLedsIfOffset); } - template CLEDController *addLeds(const struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) { + template CLEDController &addLeds(const struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) { return addLeds(data, nLedsOrOffset, nLedsIfOffset); } - template CLEDController *addLeds(const struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) { + template CLEDController &addLeds(const struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) { return addLeds(data, nLedsOrOffset, nLedsIfOffset); } #endif template - CLEDController *addLeds(const struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) { + CLEDController &addLeds(const struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) { switch(CHIPSET) { #ifdef FASTSPI_USE_DMX_SIMPLE case DMX: { static DMXController controller; return addLeds(&controller, data, nLedsOrOffset, nLedsIfOffset); } @@ -122,11 +122,10 @@ public: case GW6205: { static GW6205Controller800Khz controller; return addLeds(&controller, data, nLedsOrOffset, nLedsIfOffset); } case GW6205_400: { static GW6205Controller400Khz controller; return addLeds(&controller, data, nLedsOrOffset, nLedsIfOffset); } } - return NULL; } template - CLEDController *addLeds(const struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) { + CLEDController &addLeds(const struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) { switch(CHIPSET) { #ifdef FASTSPI_USE_DMX_SIMPLE case DMX: {static DMXController controller; return addLeds(&controller, data, nLedsOrOffset, nLedsIfOffset); } @@ -145,18 +144,16 @@ public: case GW6205: { static GW6205Controller800Khz controller; return addLeds(&controller, data, nLedsOrOffset, nLedsIfOffset); } case GW6205_400: { static GW6205Controller400Khz controller; return addLeds(&controller, data, nLedsOrOffset, nLedsIfOffset); } } - return NULL; } +#ifdef HAS_BLOCKLESS template - CLEDController *addLeds(const struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) { + CLEDController &addLeds(const struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) { switch(CHIPSET) { -#ifdef HAS_BLOCKLESS case WS2811_PORTC: return addLeds(new BlockClocklessController(), data, nLedsOrOffset, nLedsIfOffset); -#endif } - return NULL; } +#endif void setBrightness(CRGB scale) { m_Scale = scale; } void setBrightness(uint8_t scale) { m_Scale = CRGB(scale,scale,scale); } -- cgit v1.2.3 From af082f261b6f6afd97b17034d0669fd4d5eded25 Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Tue, 11 Mar 2014 15:01:11 -0700 Subject: Fuck you, gcc. Just fuck you. --- clockless_trinket.h | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/clockless_trinket.h b/clockless_trinket.h index 26210f24..259683ae 100644 --- a/clockless_trinket.h +++ b/clockless_trinket.h @@ -130,6 +130,9 @@ public: : /* clobber registers */ +#define xstr(s) str(s) +#define str(s) #s + // 1 cycle, write hi to the port #define HI1 if((int)(FastPin::port())-0x20 < 64) { asm __volatile__("out %[PORT], %[hi]" ASM_VARS ); } else { *FastPin::port()=hi; } // 1 cycle, write lo to the port @@ -237,10 +240,11 @@ public: register uint8_t loopvar=0; { + while(count--) { // Loop beginning, does some stuff that's outside of the pixel write cycle, namely incrementing d0-2 and masking off // by the E values (see the definition ) - LOOP; + // LOOP; ADJDITHER2(d0,e0); ADJDITHER2(d1,e1); ADJDITHER2(d2,e2); @@ -290,7 +294,8 @@ public: HI1 D1(1) QLO2(b2, 3) RORSC04(b0,4) D2(4) LO1 ROR1(b0) CLC1 D3(2) HI1 D1(1) QLO2(b2, 2) SCROR04(b0,5) D2(4) LO1 SCALE02(b0,6) D3(2) HI1 D1(1) QLO2(b2, 1) RORSC04(b0,7) D2(4) LO1 ROR1(b0) CLC1 D3(2) - HI1 D1(1) QLO2(b2, 0) DCOUNT2 BRLOOP1 D2(3) LO1 D3(2) JMPLOOP2 + // HI1 D1(1) QLO2(b2, 0) DCOUNT2 BRLOOP1 D2(3) LO1 D3(2) JMPLOOP2 + HI1 D1(1) QLO2(b2, 0) D2(0) LO1 D3(0) // switch(XTRA0) { // case 4: HI1 D1(1) QLO2(b1,0) D2(0) LO1 D3(0); // case 3: HI1 D1(1) QLO2(b1,0) D2(0) LO1 D3(0); @@ -324,8 +329,8 @@ public: HI1 D1(1) QLO2(b2, 1) D2(0) LO1 D3(0) HI1 D1(1) QLO2(b2, 0) DCOUNT2 BRLOOP1 D2(3) LO1 D3(2) JMPLOOP2 #endif - DONE - D2(4) LO1 D3(0) + // DONE + // D2(4) LO1 D3(0) } } // save the d values -- cgit v1.2.3 From 2e769e007add6caeb1804f03a69fee7bd2018f0e Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Tue, 11 Mar 2014 16:46:08 -0700 Subject: Re-enable the extra bit output in the trinket code --- clockless_arm_sam.h | 7 ++++--- clockless_trinket.h | 40 +++++++++++++++++++--------------------- 2 files changed, 23 insertions(+), 24 deletions(-) diff --git a/clockless_arm_sam.h b/clockless_arm_sam.h index 5c418509..a09e0b3d 100644 --- a/clockless_arm_sam.h +++ b/clockless_arm_sam.h @@ -6,9 +6,10 @@ #if defined(__SAM3X8E__) -#define TOTAL ( (T1+2) + (T2+2) + (T3+2) ) -#define T1_MARK (TOTAL - (T1+2)) -#define T2_MARK (T1_MARK - (T2+2)) +#define TADJUST 1 +#define TOTAL ( (T1+TADJUST) + (T2+TADJUST) + (T3+TADJUST) ) +#define T1_MARK (TOTAL - (T1+TADJUST)) +#define T2_MARK (T1_MARK - (T2+TADJUST)) #define SCALE(S,V) scale8_video(S,V) // #define SCALE(S,V) scale8(S,V) diff --git a/clockless_trinket.h b/clockless_trinket.h index 259683ae..c2d9bf54 100644 --- a/clockless_trinket.h +++ b/clockless_trinket.h @@ -244,11 +244,9 @@ public: { // Loop beginning, does some stuff that's outside of the pixel write cycle, namely incrementing d0-2 and masking off // by the E values (see the definition ) - // LOOP; ADJDITHER2(d0,e0); ADJDITHER2(d1,e1); ADJDITHER2(d2,e2); - // CLC1; // 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. @@ -267,12 +265,12 @@ public: 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 ROR1(b1) CLC1 D3(2) HI1 D1(1) QLO2(b0, 0) D2(0) LO1 D3(0) - // switch(XTRA0) { - // case 4: HI1 D1(1) QLO2(b0,0) D2(0) LO1 D3(0); - // case 3: HI1 D1(1) QLO2(b0,0) D2(0) LO1 D3(0); - // case 2: HI1 D1(1) QLO2(b0,0) D2(0) LO1 D3(0); - // case 1: HI1 D1(1) QLO2(b0,0) D2(0) LO1 D3(0); - // } + switch(XTRA0) { + case 4: HI1 D1(1) QLO2(b0,0) D2(0) LO1 D3(0); + case 3: HI1 D1(1) QLO2(b0,0) D2(0) LO1 D3(0); + case 2: HI1 D1(1) QLO2(b0,0) D2(0) LO1 D3(0); + case 1: HI1 D1(1) QLO2(b0,0) D2(0) LO1 D3(0); + } HI1 D1(1) QLO2(b1, 7) LDSCL4(b2,O2) D2(3) LO1 PRESCALEA2(d2) D3(2) HI1 D1(1) QLO2(b1, 6) PRESCALEB3(d2) D2(3) LO1 SCALE22(b2,0) D3(2) HI1 D1(1) QLO2(b1, 5) RORSC24(b2,1) D2(4) LO1 ROR1(b2) CLC1 D3(2) @@ -281,12 +279,12 @@ public: HI1 D1(1) QLO2(b1, 2) SCROR24(b2,5) D2(4) LO1 SCALE22(b2,6) D3(2) HI1 D1(1) QLO2(b1, 1) RORSC24(b2,7) D2(4) LO1 ROR1(b2) CLC1 D3(2) HI1 D1(1) QLO2(b1, 0) IDATA2 CLC1 D2(3) LO1 D3(0) - // switch(XTRA0) { - // case 4: HI1 D1(1) QLO2(b1,0) D2(0) LO1 D3(0); - // case 3: HI1 D1(1) QLO2(b1,0) D2(0) LO1 D3(0); - // case 2: HI1 D1(1) QLO2(b1,0) D2(0) LO1 D3(0); - // case 1: HI1 D1(1) QLO2(b1,0) D2(0) LO1 D3(0); - // } + switch(XTRA0) { + case 4: HI1 D1(1) QLO2(b1,0) D2(0) LO1 D3(0); + case 3: HI1 D1(1) QLO2(b1,0) D2(0) LO1 D3(0); + case 2: HI1 D1(1) QLO2(b1,0) D2(0) LO1 D3(0); + case 1: HI1 D1(1) QLO2(b1,0) D2(0) LO1 D3(0); + } HI1 D1(1) QLO2(b2, 7) LDSCL4(b0,O0) D2(3) LO1 PRESCALEA2(d0) D3(2) HI1 D1(1) QLO2(b2, 6) PRESCALEB3(d0) D2(3) LO1 SCALE02(b0,0) D3(2) HI1 D1(1) QLO2(b2, 5) RORSC04(b0,1) D2(4) LO1 ROR1(b0) CLC1 D3(2) @@ -296,12 +294,12 @@ public: HI1 D1(1) QLO2(b2, 1) RORSC04(b0,7) D2(4) LO1 ROR1(b0) CLC1 D3(2) // HI1 D1(1) QLO2(b2, 0) DCOUNT2 BRLOOP1 D2(3) LO1 D3(2) JMPLOOP2 HI1 D1(1) QLO2(b2, 0) D2(0) LO1 D3(0) - // switch(XTRA0) { - // case 4: HI1 D1(1) QLO2(b1,0) D2(0) LO1 D3(0); - // case 3: HI1 D1(1) QLO2(b1,0) D2(0) LO1 D3(0); - // case 2: HI1 D1(1) QLO2(b1,0) D2(0) LO1 D3(0); - // case 1: HI1 D1(1) QLO2(b1,0) D2(0) LO1 D3(0); - // } + switch(XTRA0) { + case 4: HI1 D1(1) QLO2(b1,0) D2(0) LO1 D3(0); + case 3: HI1 D1(1) QLO2(b1,0) D2(0) LO1 D3(0); + case 2: HI1 D1(1) QLO2(b1,0) D2(0) LO1 D3(0); + case 1: HI1 D1(1) QLO2(b1,0) D2(0) LO1 D3(0); + } #else // no inline scaling - non-straight RGB ordering HI1 D1(1) QLO2(b0, 7) LD2(b1,O1) D2(2) LO1 D3(0) @@ -327,7 +325,7 @@ public: HI1 D1(1) QLO2(b2, 3) D2(0) LO1 D3(0) HI1 D1(1) QLO2(b2, 2) D2(0) LO1 D3(0) HI1 D1(1) QLO2(b2, 1) D2(0) LO1 D3(0) - HI1 D1(1) QLO2(b2, 0) DCOUNT2 BRLOOP1 D2(3) LO1 D3(2) JMPLOOP2 + HI1 D1(1) QLO2(b2, 0) D2(0) LO1 D3(0) #endif // DONE // D2(4) LO1 D3(0) -- cgit v1.2.3 From d3e6c3ede915ff7d7181193e119d1bce8a51ecde Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Wed, 12 Mar 2014 11:43:24 -0700 Subject: Fix ordering of steping the dithering --- clockless_arm_k20.h | 3 ++- clockless_arm_sam.h | 3 ++- clockless_trinket.h | 1 + controller.h | 7 +++++-- 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/clockless_arm_k20.h b/clockless_arm_k20.h index 961789a2..876fb98c 100644 --- a/clockless_arm_k20.h +++ b/clockless_arm_k20.h @@ -90,8 +90,9 @@ public: // Setup the pixel controller and load/scale the first byte PixelController pixels(data, scale, true, ADVANCE, SKIP); + pixels.preStepFirstByteDithering(); register uint8_t b = pixels.loadAndScale0(); - + // Get access to the clock ARM_DEMCR |= ARM_DEMCR_TRCENA; ARM_DWT_CTRL |= ARM_DWT_CTRL_CYCCNTENA; diff --git a/clockless_arm_sam.h b/clockless_arm_sam.h index a09e0b3d..28207acb 100644 --- a/clockless_arm_sam.h +++ b/clockless_arm_sam.h @@ -169,8 +169,9 @@ public: // Setup the pixel controller and load/scale the first byte PixelController pixels(data, scale, true, ADVANCE, SKIP); + pixels.preStepFirstByteDithering(); register uint8_t b = pixels.loadAndScale0(); - + // Setup and start the clock register volatile uint32_t *CTPTR asm("r6")= &SysTick->CTRL; FORCE_REFERENCE(CTPTR); _LOAD = TOTAL; diff --git a/clockless_trinket.h b/clockless_trinket.h index c2d9bf54..73c7f371 100644 --- a/clockless_trinket.h +++ b/clockless_trinket.h @@ -224,6 +224,7 @@ public: // Setup the pixel controller and load/scale the first byte PixelController pixels(data, scale, true, advance, skip); + pixels.stepFirstByteDithering(); b0 = pixels.loadAndScale0(); // pull the dithering/adjustment values out of the pixels object for direct asm access diff --git a/controller.h b/controller.h index a7967176..791b8080 100644 --- a/controller.h +++ b/controller.h @@ -139,8 +139,6 @@ struct PixelController { d[i] = scale8(Q, e[i]); if(e[i]) e[i]--; } - - d[0] = e[0] - d[0]; } // toggle dithering enable @@ -161,6 +159,11 @@ struct PixelController { d[2] = e[2] - d[2]; } + // Some chipsets pre-cycle the first byte, which means we want to cycle byte 0's dithering separately + __attribute__((always_inline)) inline void preStepFirstByteDithering() { + d[RO(0)] = e[RO(0)] - d[RO(0)]; + } + template __attribute__((always_inline)) inline static uint8_t loadByte(PixelController & pc) { return pc.mData[RO(SLOT)]; } template __attribute__((always_inline)) inline static uint8_t dither(PixelController & pc, uint8_t b) { return qadd8(b, pc.d[RO(SLOT)]); } template __attribute__((always_inline)) inline static uint8_t scale(PixelController & pc, uint8_t b) { return scale8(b, pc.mScale.raw[RO(SLOT)]); } -- cgit v1.2.3 From 83579ac9e6e952b5b150cef06ae0f8e1420919eb Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Wed, 12 Mar 2014 11:44:53 -0700 Subject: Fix ordering of steping the dithering --- clockless_trinket.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clockless_trinket.h b/clockless_trinket.h index 73c7f371..8024fc96 100644 --- a/clockless_trinket.h +++ b/clockless_trinket.h @@ -224,7 +224,7 @@ public: // Setup the pixel controller and load/scale the first byte PixelController pixels(data, scale, true, advance, skip); - pixels.stepFirstByteDithering(); + pixels.preStepFirstByteDithering(); b0 = pixels.loadAndScale0(); // pull the dithering/adjustment values out of the pixels object for direct asm access -- cgit v1.2.3 From 8f6253d138ebe2051759c142aa746289b5e1a5b7 Mon Sep 17 00:00:00 2001 From: Mark Kriegsman Date: Thu, 13 Mar 2014 23:39:37 -0400 Subject: Change to 'twothirds' to a slightly (one bit) more accurate value. --- hsv2rgb.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/hsv2rgb.cpp b/hsv2rgb.cpp index b0abdab9..43379a0e 100644 --- a/hsv2rgb.cpp +++ b/hsv2rgb.cpp @@ -337,7 +337,8 @@ void hsv2rgb_rainbow( const CHSV& hsv, CRGB& rgb) } if( Y2 ) { r = K171 + third; - uint8_t twothirds = (third << 1); + //uint8_t twothirds = (third << 1); + uint8_t twothirds = scale8( offset8, ((256 * 2) / 3)); g = K85 + twothirds; b = 0; FORCE_REFERENCE(b); @@ -350,7 +351,8 @@ void hsv2rgb_rainbow( const CHSV& hsv, CRGB& rgb) // 010 //case 2: // Y -> G if( Y1 ) { - uint8_t twothirds = (third << 1); + //uint8_t twothirds = (third << 1); + uint8_t twothirds = scale8( offset8, ((256 * 2) / 3)); r = K171 - twothirds; g = K171 + third; b = 0; @@ -381,7 +383,8 @@ void hsv2rgb_rainbow( const CHSV& hsv, CRGB& rgb) //case 4: // A -> B r = 0; FORCE_REFERENCE(r); - uint8_t twothirds = (third << 1); + //uint8_t twothirds = (third << 1); + uint8_t twothirds = scale8( offset8, ((256 * 2) / 3)); g = K171 - twothirds; b = K85 + twothirds; -- cgit v1.2.3 From 4f8d771dfbd234350d586d35653167d2866566e9 Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Fri, 14 Mar 2014 02:21:41 -0700 Subject: fix compile error --- fastpin_avr.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fastpin_avr.h b/fastpin_avr.h index eeb30040..2c6103a1 100644 --- a/fastpin_avr.h +++ b/fastpin_avr.h @@ -55,7 +55,7 @@ _DEFPIN_AVR(4, 0x10, B); _DEFPIN_AVR(5, 0x20, B); #define HAS_HARDWARE_PIN_SUPPORT 1 -#elif defined(__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__) || defined(__AVR_ATtiny25__) || +#elif defined(__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__) || defined(__AVR_ATtiny25__) _IO(A); _IO(B); _DEFPIN_AVR(0, 0x01, A); _DEFPIN_AVR(1, 0x02, A); _DEFPIN_AVR(2, 0x04, A); _DEFPIN_AVR(3, 0x08, A); -- cgit v1.2.3 From 4d92865634495b39ceff9e588495c08ad67790f3 Mon Sep 17 00:00:00 2001 From: Romain Bazile Date: Fri, 14 Mar 2014 15:12:47 +0100 Subject: Update to line 58 fastpin_avr.h Corrected the || operator that was forgotten. --- fastpin_avr.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fastpin_avr.h b/fastpin_avr.h index eeb30040..165ad50e 100644 --- a/fastpin_avr.h +++ b/fastpin_avr.h @@ -55,7 +55,7 @@ _DEFPIN_AVR(4, 0x10, B); _DEFPIN_AVR(5, 0x20, B); #define HAS_HARDWARE_PIN_SUPPORT 1 -#elif defined(__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__) || defined(__AVR_ATtiny25__) || +#elif defined(__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__) || defined(__AVR_ATtiny25__) _IO(A); _IO(B); _DEFPIN_AVR(0, 0x01, A); _DEFPIN_AVR(1, 0x02, A); _DEFPIN_AVR(2, 0x04, A); _DEFPIN_AVR(3, 0x08, A); -- cgit v1.2.3 From 39bbc47df996017083b51e4df6394e8a566c0aec Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Sat, 15 Mar 2014 15:20:53 -0700 Subject: Move responsibility for scaling brightness to color correction/temperature into the controller objects. Return scale to being a uint8_t --- FastLED.cpp | 10 +++---- FastLED.h | 11 ++++---- chipsets.h | 16 ++++++------ clockless_arm_k20.h | 6 ++--- clockless_arm_sam.h | 6 ++--- clockless_trinket.h | 6 ++--- controller.h | 75 +++++++++++++++++++++++++++++++++++++---------------- 7 files changed, 79 insertions(+), 51 deletions(-) diff --git a/FastLED.cpp b/FastLED.cpp index 4db607a6..ce3f9fd3 100644 --- a/FastLED.cpp +++ b/FastLED.cpp @@ -46,23 +46,21 @@ CLEDController &CFastLED::addLeds(CLEDController *pLed, return *pLed; } -void CFastLED::show(CRGB scale) { +void CFastLED::show(uint8_t scale) { for(int i = 0; i < m_nControllers; i++) { if(m_Controllers[i].pLedController != NULL) { m_Controllers[i].pLedController->show(m_Controllers[i].pLedData + m_Controllers[i].nOffset, - m_Controllers[i].nLeds, - m_Controllers[i].pLedController->getAdjustment(scale)); + m_Controllers[i].nLeds, scale); } else { return; } } } -void CFastLED::showColor(const struct CRGB & color, CRGB scale) { +void CFastLED::showColor(const struct CRGB & color, uint8_t scale) { for(int i = 0; i < m_nControllers; i++) { if(m_Controllers[i].pLedController != NULL) { - m_Controllers[i].pLedController->showColor(color, m_Controllers[i].nLeds, - m_Controllers[i].pLedController->getAdjustment(scale)); + m_Controllers[i].pLedController->showColor(color, m_Controllers[i].nLeds, scale); } else { return; } diff --git a/FastLED.h b/FastLED.h index 94c2d2e1..8dbebb69 100644 --- a/FastLED.h +++ b/FastLED.h @@ -54,7 +54,7 @@ class CFastLED { CControllerInfo m_Controllers[NUM_CONTROLLERS]; int m_nControllers; - CRGB m_Scale; + uint8_t m_Scale; public: CFastLED(); @@ -155,12 +155,11 @@ public: } #endif - void setBrightness(CRGB scale) { m_Scale = scale; } - void setBrightness(uint8_t scale) { m_Scale = CRGB(scale,scale,scale); } - uint8_t getBrightness() { return m_Scale.raw[0]; } + void setBrightness(uint8_t scale) { m_Scale = scale; } + uint8_t getBrightness() { return m_Scale; } /// Update all our controllers with the current led colors, using the passed in brightness - void show(CRGB scale); + void show(uint8_t scale); /// Update all our controllers with the current led colors void show() { show(m_Scale); } @@ -169,7 +168,7 @@ public: void clearData(); - void showColor(const struct CRGB & color, CRGB scale); + void showColor(const struct CRGB & color, uint8_t scale); void showColor(const struct CRGB & color) { showColor(color, m_Scale); } diff --git a/chipsets.h b/chipsets.h index 78821b0a..4815138e 100644 --- a/chipsets.h +++ b/chipsets.h @@ -7,7 +7,7 @@ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // LPD8806 controller class - takes data/clock/select pin values (N.B. should take an SPI definition?) -// +// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// template @@ -52,11 +52,11 @@ public: mSPI.release(); } - virtual void showColor(const struct CRGB & data, int nLeds, CRGB scale = CRGB::White) { + virtual void showColor(const struct CRGB & data, int nLeds, CRGB scale) { mSPI.template writeBytes3((byte*)data.raw, nLeds * 3, scale, false); } - virtual void show(const struct CRGB *data, int nLeds, CRGB scale = CRGB::White) { + virtual void show(const struct CRGB *data, int nLeds, CRGB scale) { // TODO rgb-ize scale mSPI.template writeBytes3((byte*)data, nLeds * 3, scale); } @@ -95,7 +95,7 @@ public: mWaitDelay.mark(); } - virtual void showColor(const struct CRGB & data, int nLeds, CRGB scale = CRGB::White) { + virtual void showColor(const struct CRGB & data, int nLeds, CRGB scale) { mWaitDelay.wait(); mSPI.template writeBytes3((byte*)data.raw, nLeds * 3, scale, false); mWaitDelay.mark(); @@ -145,7 +145,7 @@ public: showColor(CRGB(0,0,0), nLeds); } - virtual void showColor(const struct CRGB & data, int nLeds, CRGB scale = CRGB::White) { + virtual void showColor(const struct CRGB & data, int nLeds, CRGB scale) { PixelController pixels(data.raw, scale, true, false, 0); mSPI.select(); @@ -237,12 +237,12 @@ public: writeHeader(); } - virtual void showColor(const struct CRGB & data, int nLeds, CRGB scale = CRGB::White) { + virtual void showColor(const struct CRGB & data, int nLeds, CRGB scale) { mSPI.template writeBytes3((byte*)data.raw, nLeds * 3, scale, false); writeHeader(); } - virtual void show(const struct CRGB *data, int nLeds, CRGB scale = CRGB::White) { + virtual void show(const struct CRGB *data, int nLeds, CRGB scale) { // Make sure the FLAG_START_BIT flag is set to ensure that an extra 1 bit is sent at the start // of each triplet of bytes for rgb data // writeHeader(); @@ -251,7 +251,7 @@ public: } #ifdef SUPPORT_ARGB - virtual void show(const struct CARGB *data, int nLeds, CRGB scale = CRGB::White) { + virtual void show(const struct CARGB *data, int nLeds, CRGB scale) { mSPI.writeBytesValue(0, 6); mSPI.template writeBit<0>(0); mSPI.template writeBit<0>(0); diff --git a/clockless_arm_k20.h b/clockless_arm_k20.h index 09830527..d5f5a1c0 100644 --- a/clockless_arm_k20.h +++ b/clockless_arm_k20.h @@ -24,7 +24,7 @@ public: } // set all the leds on the controller to a given color - virtual void showColor(const struct CRGB & data, int nLeds, CRGB scale = CRGB::White) { + virtual void showColor(const struct CRGB & data, int nLeds, CRGB scale) { mWait.wait(); cli(); @@ -37,7 +37,7 @@ public: mWait.mark(); } - virtual void show(const struct CRGB *rgbdata, int nLeds, CRGB scale = CRGB::White) { + virtual void show(const struct CRGB *rgbdata, int nLeds, CRGB scale) { mWait.wait(); cli(); @@ -51,7 +51,7 @@ public: } #ifdef SUPPORT_ARGB - virtual void show(const struct CARGB *rgbdata, int nLeds, CRGB scale = CRGB::White) { + virtual void show(const struct CARGB *rgbdata, int nLeds, CRGB scale) { mWait.wait(); cli(); diff --git a/clockless_arm_sam.h b/clockless_arm_sam.h index 28207acb..e17c902d 100644 --- a/clockless_arm_sam.h +++ b/clockless_arm_sam.h @@ -34,7 +34,7 @@ public: } // set all the leds on the controller to a given color - virtual void showColor(const struct CRGB & data, int nLeds, CRGB scale = CRGB::White) { + virtual void showColor(const struct CRGB & data, int nLeds, CRGB scale) { mWait.wait(); cli(); SysClockSaver savedClock(TOTAL); @@ -50,7 +50,7 @@ public: mWait.mark(); } - virtual void show(const struct CRGB *rgbdata, int nLeds, CRGB scale = CRGB::White) { + virtual void show(const struct CRGB *rgbdata, int nLeds, CRGB scale) { mWait.wait(); cli(); SysClockSaver savedClock(TOTAL); @@ -72,7 +72,7 @@ public: } #ifdef SUPPORT_ARGB - virtual void show(const struct CARGB *rgbdata, int nLeds, CRGB scale = CRGB::White) { + virtual void show(const struct CARGB *rgbdata, int nLeds, CRGB scale) { mWait.wait(); cli(); SysClockSaver savedClock(TOTAL); diff --git a/clockless_trinket.h b/clockless_trinket.h index 8024fc96..5dcecafa 100644 --- a/clockless_trinket.h +++ b/clockless_trinket.h @@ -73,16 +73,16 @@ public: } // set all the leds on the controller to a given color - virtual void showColor(const struct CRGB & data, int nLeds, CRGB scale = CRGB::White) { + virtual void showColor(const struct CRGB & data, int nLeds, CRGB scale) { showRGBInternal_AdjTime(0, false, nLeds, scale, (const byte*)&data); } - virtual void show(const struct CRGB *rgbdata, int nLeds, CRGB scale = CRGB::White) { + virtual void show(const struct CRGB *rgbdata, int nLeds, CRGB scale) { showRGBInternal_AdjTime(0, true, nLeds, scale, (const byte*)rgbdata); } #ifdef SUPPORT_ARGB - virtual void show(const struct CARGB *rgbdata, int nLeds, CRGB scale = CRGB::White) { + virtual void show(const struct CARGB *rgbdata, int nLeds, CRGB scale) { showRGBInternal_AdjTime(1, true, nLeds, scale, (const byte*)rgbdata); } #endif diff --git a/controller.h b/controller.h index 791b8080..131ec4a2 100644 --- a/controller.h +++ b/controller.h @@ -27,9 +27,21 @@ /// to methods, make them references to this type, keeps your code saner. However, most people won't be seeing/using these objects /// directly at all class CLEDController { +protected: CRGB m_ColorCorrection; CRGB m_ColorTemperature; + // set all the leds on the controller to a given color + virtual void showColor(const struct CRGB & data, int nLeds, CRGB scale) = 0; + + // note that the uint8_ts will be in the order that you want them sent out to the device. + // nLeds is the number of RGB leds being written to + virtual void show(const struct CRGB *data, int nLeds, CRGB scale) = 0; + +#ifdef SUPPORT_ARGB + // as above, but every 4th uint8_t is assumed to be alpha channel data, and will be skipped + virtual void show(const struct CARGB *data, int nLeds, CRGB scale) = 0; +#endif public: CLEDController() : m_ColorCorrection(UncorrectedColor), m_ColorTemperature(UncorrectedTemperature) {} @@ -42,38 +54,57 @@ public: // clear out/zero out the given number of leds. virtual void clearLeds(int nLeds) = 0; - // set all the leds on the controller to a given color - virtual void showColor(const struct CRGB & data, int nLeds, CRGB scale = CRGB::White) = 0; - - // note that the uint8_ts will be in the order that you want them sent out to the device. - // nLeds is the number of RGB leds being written to - virtual void show(const struct CRGB *data, int nLeds, CRGB scale = CRGB::White) = 0; - -#ifdef SUPPORT_ARGB - // as above, but every 4th uint8_t is assumed to be alpha channel data, and will be skipped - virtual void show(const struct CARGB *data, int nLeds, CRGB scale = CRGB::White) = 0; -#endif - // is the controller ready to write data out virtual bool ready() { return true; } // wait until the controller is ready to write data out virtual void wait() { return; } - virtual CLEDController & setCorrection(CRGB correction) { m_ColorCorrection = correction; return *this; } - virtual CLEDController & setCorrection(LEDColorCorrection correction) { m_ColorCorrection = correction; return *this; } - virtual CRGB getCorrection() { return m_ColorCorrection; } + // show function w/integer brightness, will scale for color correction and temperature + void show(const struct CRGB *data, int nLeds, uint8_t brightness) { + show(data, nLeds, getAdjustment(brightness)); + } + + // show function w/integer brightness, will scale for color correction and temperature + void showColor(const struct CRGB &data, int nLeds, uint8_t brightness) { + showColor(data, nLeds, getAdjustment(brightness)); + } + + #ifdef SUPPORT_ARGB + // as above, but every 4th uint8_t is assumed to be alpha channel data, and will be skipped + void show(const struct CARGB *data, int nLeds, uint8_t brightness) { + show(data, nLeds, getAdjustment(brightness)) + } +#endif + + CLEDController & setCorrection(CRGB correction) { m_ColorCorrection = correction; return *this; } + CLEDController & setCorrection(LEDColorCorrection correction) { m_ColorCorrection = correction; return *this; } + CRGB getCorrection() { return m_ColorCorrection; } - virtual CLEDController & setTemperature(CRGB temperature) { m_ColorTemperature = temperature; return *this; } - virtual CLEDController & setTemperature(ColorTemperature temperature) { m_ColorTemperature = temperature; return *this; } - virtual CRGB getTemperature() { return m_ColorTemperature; } + CLEDController & setTemperature(CRGB temperature) { m_ColorTemperature = temperature; return *this; } + CLEDController & setTemperature(ColorTemperature temperature) { m_ColorTemperature = temperature; return *this; } + CRGB getTemperature() { return m_ColorTemperature; } - virtual CRGB getAdjustment(CRGB scale) { + CRGB getAdjustment(uint8_t scale) { // if(1) return scale; - uint32_t r = ((uint32_t)m_ColorCorrection.r * (uint32_t)m_ColorTemperature.r * (uint32_t)scale.r) / (uint32_t)0x10000L; - uint32_t g = ((uint32_t)m_ColorCorrection.g * (uint32_t)m_ColorTemperature.g * (uint32_t)scale.g) / (uint32_t)0x10000L; - uint32_t b = ((uint32_t)m_ColorCorrection.b * (uint32_t)m_ColorTemperature.b * (uint32_t)scale.b) / (uint32_t)0x10000L; + uint32_t r = 0; + uint32_t g = 0; + uint32_t b = 0; + if(m_ColorCorrection.r > 0 && m_ColorTemperature.r > 0 && scale > 0) { + r = ((uint32_t)m_ColorCorrection.r+1) * ((uint32_t)m_ColorTemperature.r+1) * scale; + r /= 0x10000L; + } + if(m_ColorCorrection.g > 0 && m_ColorTemperature.g > 0 && scale > 0) { + g = ((uint32_t)m_ColorCorrection.g+1) * ((uint32_t)m_ColorTemperature.g+1) * scale; + g /= 0x10000L; + } + + if(m_ColorCorrection.b > 0 && m_ColorTemperature.b > 0 && scale > 0) { + b = ((uint32_t)m_ColorCorrection.b+1) * ((uint32_t)m_ColorTemperature.b+1) * scale; + b /= 0x10000L; + } + // static int done = 0; // if(!done) { // done = 1; -- cgit v1.2.3 From 6408c785f9803beaa8dfff5a8e2daff005638941 Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Sat, 15 Mar 2014 18:34:03 -0700 Subject: * Move brightness into a 8 bit scalar * Move loop control into PixelController and update everything to use PixelController * Replace writeBytes3 methods in the SPI implementations with writePixels instead, and have them use PixelControllers. * Prototype using the DWT cycle counter for sam like k20 (doesn't work yet, however) * Other minor code cleanups --- FastLED.cpp | 2 +- chipsets.h | 24 +++++++------- clockless_arm_k20.h | 17 +++++----- clockless_arm_sam.h | 81 ++++++++++++++++++++++++++++++++++++++---------- clockless_trinket.h | 49 ++++++++++++++--------------- controller.h | 73 ++++++++++++++++++++++++++++++++++++------- examples/Cylon/Cylon.ino | 10 +++--- fastspi_arm_k20.h | 34 +++++++++----------- fastspi_arm_sam.h | 31 ++++++++---------- fastspi_avr.h | 26 +++++++--------- fastspi_bitbang.h | 39 +++++++++-------------- 11 files changed, 229 insertions(+), 157 deletions(-) diff --git a/FastLED.cpp b/FastLED.cpp index ce3f9fd3..076bac21 100644 --- a/FastLED.cpp +++ b/FastLED.cpp @@ -14,7 +14,7 @@ uint32_t CRGB::Squant = ((uint32_t)((__TIME__[4]-'0') * 28))<<16 | ((__TIME__[6] CFastLED::CFastLED() { // clear out the array of led controllers m_nControllers = NUM_CONTROLLERS; - m_Scale = CRGB::White; + m_Scale = 255; memset8(m_Controllers, 0, m_nControllers * sizeof(CControllerInfo)); } diff --git a/chipsets.h b/chipsets.h index 4815138e..2cc98dba 100644 --- a/chipsets.h +++ b/chipsets.h @@ -53,18 +53,18 @@ public: } virtual void showColor(const struct CRGB & data, int nLeds, CRGB scale) { - mSPI.template writeBytes3((byte*)data.raw, nLeds * 3, scale, false); + mSPI.template writePixels(PixelController(data, nLeds, scale, getDither())); } virtual void show(const struct CRGB *data, int nLeds, CRGB scale) { // TODO rgb-ize scale - mSPI.template writeBytes3((byte*)data, nLeds * 3, scale); + mSPI.template writePixels(PixelController(data, nLeds, scale, getDither())); } #ifdef SUPPORT_ARGB virtual void show(const struct CARGB *data, int nLeds, uint8_t scale) { checkClear(nLeds); - mSPI.template writeBytes3((byte*)data, nLeds * 4, scale, true, 1); + mSPI.template writePixels(PixelController(data, nLeds, scale, getDither())); } #endif }; @@ -97,20 +97,20 @@ public: virtual void showColor(const struct CRGB & data, int nLeds, CRGB scale) { mWaitDelay.wait(); - mSPI.template writeBytes3((byte*)data.raw, nLeds * 3, scale, false); + mSPI.template writePixels(PixelController(data, nLeds, scale, getDither())); mWaitDelay.mark(); } virtual void show(const struct CRGB *data, int nLeds, CRGB scale) { mWaitDelay.wait(); - mSPI.template writeBytes3((byte*)data, nLeds * 3, scale); + mSPI.template writePixels(PixelController(data, nLeds, scale, getDither())); mWaitDelay.mark(); } #ifdef SUPPORT_ARGB virtual void show(const struct CRGB *data, int nLeds, CRGB scale) { mWaitDelay.wait(); - mSPI.template writeBytes3((byte*)data, nLeds * 4, scale, true, 1); + mSPI.template writePixels(PixelController(data, nLeds, scale, getDither())); mWaitDelay.mark(); } #endif @@ -146,7 +146,7 @@ public: } virtual void showColor(const struct CRGB & data, int nLeds, CRGB scale) { - PixelController pixels(data.raw, scale, true, false, 0); + PixelController pixels(data, nLeds, scale, getDither()); mSPI.select(); @@ -162,7 +162,7 @@ public: } virtual void show(const struct CRGB *data, int nLeds, CRGB scale) { - PixelController pixels((byte*)data, scale, true, true, 0); + PixelController pixels(data, scale, getDither()); mSPI.select(); @@ -179,7 +179,7 @@ public: #ifdef SUPPORT_ARGB virtual void show(const struct CRGB *data, int nLeds, CRGB scale) { - PixelController pixels(data, scale, true, true, 1); + PixelController pixels(data, scale, getDither()); mSPI.select(); @@ -238,7 +238,7 @@ public: } virtual void showColor(const struct CRGB & data, int nLeds, CRGB scale) { - mSPI.template writeBytes3((byte*)data.raw, nLeds * 3, scale, false); + mSPI.template writePixels(PixelController(data, nLeds, scale, getDither())); writeHeader(); } @@ -246,7 +246,7 @@ public: // Make sure the FLAG_START_BIT flag is set to ensure that an extra 1 bit is sent at the start // of each triplet of bytes for rgb data // writeHeader(); - mSPI.template writeBytes3((byte*)data, nLeds * 3, scale); + mSPI.template writePixels( PixelController(data, nLeds, scale, getDither())); writeHeader(); } @@ -258,7 +258,7 @@ public: // Make sure the FLAG_START_BIT flag is set to ensure that an extra 1 bit is sent at the start // of each triplet of bytes for rgb data - mSPI.template writeBytes3((byte*)data, nLeds * 4, scale, true, 1); + mSPI.template writePixels(PixelController(data, nLeds, scale, getDither())); } #endif }; diff --git a/clockless_arm_k20.h b/clockless_arm_k20.h index d5f5a1c0..2ab6d27a 100644 --- a/clockless_arm_k20.h +++ b/clockless_arm_k20.h @@ -24,11 +24,11 @@ public: } // set all the leds on the controller to a given color - virtual void showColor(const struct CRGB & data, int nLeds, CRGB scale) { + virtual void showColor(const struct CRGB & rgbdata, int nLeds, CRGB scale) { mWait.wait(); cli(); - showRGBInternal<0, false>(nLeds, scale, (const byte*)&data); + showRGBInternal(PixelController(rgbdata, nLeds, scale, getDither())); // Adjust the timer long microsTaken = CLKS_TO_MICROS((long)nLeds * 8 * (T1 + T2 + T3)); @@ -41,8 +41,8 @@ public: mWait.wait(); cli(); - showRGBInternal<0, true>(nLeds, scale, (const byte*)rgbdata); - + showRGBInternal(PixelController(rgbdata, nLeds, scale, getDither())); + // Adjust the timer long microsTaken = CLKS_TO_MICROS((long)nLeds * 8 * (T1 + T2 + T3)); MS_COUNTER += (microsTaken / 1000); @@ -55,7 +55,8 @@ public: mWait.wait(); cli(); - showRGBInternal<1, true>(nLeds, scale, (const byte*)rgbdata); + showRGBInternal(PixelController(rgbdata, nLeds, scale, getDither())); + // Adjust the timer long microsTaken = CLKS_TO_MICROS((long)nLeds * 8 * (T1 + T2 + T3)); @@ -79,15 +80,13 @@ public: // 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. - template static void showRGBInternal(register int nLeds, register CRGB scale, register const byte *rgbdata) { - register byte *data = (byte*)rgbdata; + static void showRGBInternal(PixelController pixels) { register data_ptr_t port = FastPin::port(); register data_t hi = *port | FastPin::mask();; register data_t lo = *port & ~FastPin::mask();; *port = lo; // Setup the pixel controller and load/scale the first byte - PixelController pixels(data, scale, true, ADVANCE, SKIP); pixels.preStepFirstByteDithering(); register uint8_t b = pixels.loadAndScale0(); @@ -97,7 +96,7 @@ public: ARM_DWT_CYCCNT = 0; uint32_t next_mark = ARM_DWT_CYCCNT + (T1+T2+T3); - while(nLeds-- > 0) { + while(pixels.has(1)) { pixels.stepDithering(); // Write first byte, read next byte diff --git a/clockless_arm_sam.h b/clockless_arm_sam.h index e17c902d..c7781970 100644 --- a/clockless_arm_sam.h +++ b/clockless_arm_sam.h @@ -6,7 +6,8 @@ #if defined(__SAM3X8E__) -#define TADJUST 1 + +#define TADJUST 3 #define TOTAL ( (T1+TADJUST) + (T2+TADJUST) + (T3+TADJUST) ) #define T1_MARK (TOTAL - (T1+TADJUST)) #define T2_MARK (T1_MARK - (T2+TADJUST)) @@ -39,7 +40,7 @@ public: cli(); SysClockSaver savedClock(TOTAL); - showRGBInternal<0, false>(nLeds, scale, (const byte*)&data); + showRGBInternal(PixelController(data, nLeds, scale, getDither())); // Adjust the timer long microsTaken = CLKS_TO_MICROS((long)nLeds * 8 * (TOTAL)); @@ -60,7 +61,7 @@ public: // Serial.print(scale.raw[1]); Serial.print(" "); // Serial.print(scale.raw[2]); Serial.println(" "); // FastPinBB::hi(); delay(1); FastPinBB::lo(); - showRGBInternal<0, true>(nLeds, scale, (const byte*)rgbdata); + showRGBInternal(PixelController(rgbdata, nLeds, scale, getDither())); // Adjust the timer long microsTaken = CLKS_TO_MICROS((long)nLeds * 8 * (TOTAL)); @@ -77,7 +78,7 @@ public: cli(); SysClockSaver savedClock(TOTAL); - showRGBInternal<1, true>(nLeds, scale, (const byte*)rgbdata); + showRGBInternal(PixelController(rgbdata, nLeds, scale, getDither())); // Adjust the timer long microsTaken = CLKS_TO_MICROS((long)nLeds * 8 * (TOTAL)); @@ -89,6 +90,59 @@ public: } #endif +#if 0 +// Get the arm defs, register/macro defs from the k20 +#define ARM_DEMCR *(volatile uint32_t *)0xE000EDFC // Debug Exception and Monitor Control +#define ARM_DEMCR_TRCENA (1 << 24) // Enable debugging & monitoring blocks +#define ARM_DWT_CTRL *(volatile uint32_t *)0xE0001000 // DWT control register +#define ARM_DWT_CTRL_CYCCNTENA (1 << 0) // Enable cycle count +#define ARM_DWT_CYCCNT *(volatile uint32_t *)0xE0001004 // Cycle count register + + template __attribute__ ((always_inline)) inline static void writeBits(register uint32_t & next_mark, register data_ptr_t port, register uint8_t & b) { + for(register uint32_t i = BITS; i > 0; i--) { + while(ARM_DWT_CYCCNT < next_mark); + next_mark = ARM_DWT_CYCCNT + (T1+T2+T3); + *port = 1; + uint32_t flip_mark = next_mark - ((b&0x80) ? (T3) : (T2+T3)); + b <<= 1; + while(ARM_DWT_CYCCNT < flip_mark); + *port = 0; + } + } + + // 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 showRGBInternal(PixelController pixels) { + register data_ptr_t port = FastPinBB::port(); + *port = 0; + + // Setup the pixel controller and load/scale the first byte + pixels.preStepFirstByteDithering(); + register uint8_t b = pixels.loadAndScale0(); + + // Get access to the clock + ARM_DEMCR |= ARM_DEMCR_TRCENA; + ARM_DWT_CTRL |= ARM_DWT_CTRL_CYCCNTENA; + ARM_DWT_CYCCNT = 0; + uint32_t next_mark = ARM_DWT_CYCCNT + (T1+T2+T3); + + while(pixels.has(1)) { + pixels.stepDithering(); + + // Write first byte, read next byte + writeBits<8+XTRA0>(next_mark, port, b); + b = pixels.loadAndScale1(); + + // Write second byte, read 3rd byte + writeBits<8+XTRA0>(next_mark, port, b); + b = pixels.loadAndScale2(); + + // Write third byte + writeBits<8+XTRA0>(next_mark, port, b); + b = pixels.advanceAndLoadAndScale0(); + }; + } +#else // I hate using defines for these, should find a better representation at some point #define _CTRL CTPTR[0] #define _LOAD CTPTR[1] @@ -127,14 +181,6 @@ public: #define AT_MARK(X) wait_loop_mark(CTPTR); { X; } #define AT_END(X) wait_loop_mark(CTPTR); { X; } -// #define AT_BIT_START(X) while(!(_CTRL & SysTick_CTRL_COUNTFLAG_Msk)); { X; } -// #define AT_MARK(X) while(_VAL > T1_MARK); { X; } -// #define AT_END(X) while(_VAL > T2_MARK); { X; } - -//#define AT_MARK(X) delayclocks_until(_VAL); X; -//#define AT_END(X) delayclocks_until(_VAL); X; - - template __attribute__((always_inline)) static inline void delayclocks_until(register byte b) { __asm__ __volatile__ ( " sub %0, %0, %1\n" @@ -147,6 +193,7 @@ public: } + template __attribute__ ((always_inline)) inline static void writeBits(register volatile uint32_t *CTPTR, register data_ptr_t port, register uint8_t & b) { // TODO: hand rig asm version of this method. The timings are based on adjusting/studying GCC compiler ouptut. This // will bite me in the ass at some point, I know it. @@ -161,14 +208,13 @@ public: #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. - template static void showRGBInternal(register int nLeds, register CRGB scale, register const byte *rgbdata) { + static void showRGBInternal(PixelController pixels) { + // Serial.print("Going to show "); Serial.print(pixels.mLen); Serial.println(" pixels."); + register data_ptr_t port asm("r7") = FastPinBB::port(); FORCE_REFERENCE(port); - register byte *data = (byte*)rgbdata; - register uint8_t *end = data + (nLeds*3 + SKIP); *port = 0; // Setup the pixel controller and load/scale the first byte - PixelController pixels(data, scale, true, ADVANCE, SKIP); pixels.preStepFirstByteDithering(); register uint8_t b = pixels.loadAndScale0(); @@ -181,7 +227,7 @@ public: // read to clear the loop flag _CTRL; - while(nLeds-- > 0) { + while(pixels.has(1)) { pixels.stepDithering(); writeBits<8+XTRA0>(CTPTR, port, b); @@ -195,6 +241,7 @@ public: b = pixels.advanceAndLoadAndScale0(); }; } +#endif }; #endif diff --git a/clockless_trinket.h b/clockless_trinket.h index 5dcecafa..c0e9da1e 100644 --- a/clockless_trinket.h +++ b/clockless_trinket.h @@ -68,34 +68,32 @@ public: } virtual void clearLeds(int nLeds) { - static byte zeros[3] = {0,0,0}; - showRGBInternal_AdjTime(0, false, nLeds, CRGB(0,0,0), zeros); + static CRGB zeros(0,0,0); + showRGBInternal_AdjTime(PixelController(zeros, nLeds, zeros, getDither())); } // set all the leds on the controller to a given color - virtual void showColor(const struct CRGB & data, int nLeds, CRGB scale) { - showRGBInternal_AdjTime(0, false, nLeds, scale, (const byte*)&data); + virtual void showColor(const struct CRGB & rgbdata, int nLeds, CRGB scale) { + showRGBInternal_AdjTime(PixelController(rgbdata, nLeds, scale, getDither())); } virtual void show(const struct CRGB *rgbdata, int nLeds, CRGB scale) { - showRGBInternal_AdjTime(0, true, nLeds, scale, (const byte*)rgbdata); + showRGBInternal_AdjTime(PixelController(rgbdata, nLeds, scale, getDither())); } #ifdef SUPPORT_ARGB virtual void show(const struct CARGB *rgbdata, int nLeds, CRGB scale) { - showRGBInternal_AdjTime(1, true, nLeds, scale, (const byte*)rgbdata); + showRGBInternal_AdjTime(PixelController(rgbdata, nLeds, scale, getDither())); } #endif - void __attribute__ ((noinline)) showRGBInternal_AdjTime(int skip, bool advance, int nLeds, CRGB scale, const byte *rgbdata) { + void __attribute__ ((noinline)) showRGBInternal_AdjTime(PixelController pixels) { mWait.wait(); cli(); - - showRGBInternal(skip, advance, nLeds, scale, rgbdata); - + showRGBInternal(pixels); // Adjust the timer - long microsTaken = CLKS_TO_MICROS((long)nLeds * 24 * (T1 + T2 + T3)); + long microsTaken = CLKS_TO_MICROS((long)pixels.mLen * 24 * (T1 + T2 + T3)); MS_COUNTER += (microsTaken / 1000); sei(); mWait.mark(); @@ -204,8 +202,11 @@ public: // 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__ ((noinline)) showRGBInternal(int skip, bool advance, int nLeds, CRGB & scale, const byte *rgbdata) { - byte *data = (byte*)rgbdata; + static void __attribute__ ((noinline)) showRGBInternal(PixelController & pixels) { + register byte *data = (byte*)pixels.mData; + uint16_t advanceBy = pixels.advanceBy(); + uint16_t count = pixels.mLen; + data_t mask = FastPin::mask(); data_ptr_t port = FastPin::port(); // register uint8_t *end = data + nLeds; @@ -213,24 +214,20 @@ public: data_t lo = *port & ~mask; *port = lo; - uint16_t count = nLeds; - uint8_t scale_base = 0; - uint16_t advanceBy = advance ? (skip+3) : 0; - // uint8_t dadv = DADVANCE; - uint8_t b0 = 0; uint8_t b1 = 0; uint8_t b2 = 0; // Setup the pixel controller and load/scale the first byte - PixelController pixels(data, scale, true, advance, skip); pixels.preStepFirstByteDithering(); b0 = pixels.loadAndScale0(); // pull the dithering/adjustment values out of the pixels object for direct asm access - uint8_t s0 = scale.raw[RO(0)]; - uint8_t s1 = scale.raw[RO(1)]; - uint8_t s2 = scale.raw[RO(2)]; + uint8_t scale_base = 0; + + uint8_t s0 = pixels.mScale.raw[RO(0)]; + uint8_t s1 = pixels.mScale.raw[RO(1)]; + uint8_t s2 = pixels.mScale.raw[RO(2)]; uint8_t d0 = pixels.d[RO(0)]; uint8_t d1 = pixels.d[RO(1)]; uint8_t d2 = pixels.d[RO(2)]; @@ -245,9 +242,11 @@ public: { // Loop beginning, does some stuff that's outside of the pixel write cycle, namely incrementing d0-2 and masking off // by the E values (see the definition ) + // LOOP; ADJDITHER2(d0,e0); ADJDITHER2(d1,e1); ADJDITHER2(d2,e2); + CLC1; // 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. @@ -258,7 +257,7 @@ public: // we're cycling back around and doing the above for byte 0. #if TRINKET_SCALE // Inline scaling - RGB ordering - HI1 D1(1) QLO2(b0, 7) LDSCL4(b1,O1) D2(3) LO1 PRESCALEA2(d1) D3(2) + HI1 D1(1) QLO2(b0, 7) LDSCL4(b1,O1) D2(4) LO1 PRESCALEA2(d1) D3(2) HI1 D1(1) QLO2(b0, 6) PRESCALEB3(d1) D2(3) LO1 SCALE12(b1,0) D3(2) HI1 D1(1) QLO2(b0, 5) RORSC14(b1,1) D2(4) LO1 ROR1(b1) CLC1 D3(2) HI1 D1(1) QLO2(b0, 4) SCROR14(b1,2) D2(4) LO1 SCALE12(b1,3) D3(2) @@ -272,7 +271,7 @@ public: case 2: HI1 D1(1) QLO2(b0,0) D2(0) LO1 D3(0); case 1: HI1 D1(1) QLO2(b0,0) D2(0) LO1 D3(0); } - HI1 D1(1) QLO2(b1, 7) LDSCL4(b2,O2) D2(3) LO1 PRESCALEA2(d2) D3(2) + HI1 D1(1) QLO2(b1, 7) LDSCL4(b2,O2) D2(4) LO1 PRESCALEA2(d2) D3(2) HI1 D1(1) QLO2(b1, 6) PRESCALEB3(d2) D2(3) LO1 SCALE22(b2,0) D3(2) HI1 D1(1) QLO2(b1, 5) RORSC24(b2,1) D2(4) LO1 ROR1(b2) CLC1 D3(2) HI1 D1(1) QLO2(b1, 4) SCROR24(b2,2) D2(4) LO1 SCALE22(b2,3) D3(2) @@ -286,7 +285,7 @@ public: case 2: HI1 D1(1) QLO2(b1,0) D2(0) LO1 D3(0); case 1: HI1 D1(1) QLO2(b1,0) D2(0) LO1 D3(0); } - HI1 D1(1) QLO2(b2, 7) LDSCL4(b0,O0) D2(3) LO1 PRESCALEA2(d0) D3(2) + HI1 D1(1) QLO2(b2, 7) LDSCL4(b0,O0) D2(4) LO1 PRESCALEA2(d0) D3(2) HI1 D1(1) QLO2(b2, 6) PRESCALEB3(d0) D2(3) LO1 SCALE02(b0,0) D3(2) HI1 D1(1) QLO2(b2, 5) RORSC04(b0,1) D2(4) LO1 ROR1(b0) CLC1 D3(2) HI1 D1(1) QLO2(b2, 4) SCROR04(b0,2) D2(4) LO1 SCALE02(b0,3) D3(2) diff --git a/controller.h b/controller.h index 131ec4a2..1156f9e9 100644 --- a/controller.h +++ b/controller.h @@ -14,6 +14,10 @@ // operator byte *(struct CRGB[] arr) { return (byte*)arr; } +enum EDitherMode { + DISABLE = 0x00, + BINARY_DITHER = 0x01 +}; ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // @@ -30,6 +34,7 @@ class CLEDController { protected: CRGB m_ColorCorrection; CRGB m_ColorTemperature; + EDitherMode m_DitherMode; // set all the leds on the controller to a given color virtual void showColor(const struct CRGB & data, int nLeds, CRGB scale) = 0; @@ -77,6 +82,9 @@ public: } #endif + inline CLEDController & setDither(EDitherMode = BINARY_DITHER) { m_DitherMode = BINARY_DITHER; return *this; } + inline EDitherMode getDither() { return m_DitherMode; } + CLEDController & setCorrection(CRGB correction) { m_ColorCorrection = correction; return *this; } CLEDController & setCorrection(LEDColorCorrection correction) { m_ColorCorrection = correction; return *this; } CRGB getCorrection() { return m_ColorCorrection; } @@ -136,19 +144,50 @@ struct PixelController { uint8_t d[3]; uint8_t e[3]; const uint8_t *mData; - CRGB & mScale; + CRGB mScale; uint8_t mAdvance; + int mLen; + + PixelController(const PixelController & other) { + d[0] = other.d[0]; + d[1] = other.d[1]; + d[2] = other.d[2]; + e[0] = other.e[0]; + e[1] = other.e[1]; + e[2] = other.e[2]; + mData = other.mData; + mScale = other.mScale; + mAdvance = other.mAdvance; + mLen = other.mLen; + } - PixelController(const uint8_t *d, CRGB & s, bool dodithering, bool doadvance=0, uint8_t skip=0) : mData(d), mScale(s) { - enable_dithering(dodithering); + PixelController(const CRGB *d, int len, CRGB & s, EDitherMode dither = BINARY_DITHER) : mData((const uint8_t*)d), mScale(s), mLen(len) { + enable_dithering(dither); + mAdvance = 3; + } + + PixelController(const CRGB &d, int len, CRGB & s, EDitherMode dither = BINARY_DITHER) : mData((const uint8_t*)&d), mScale(s), mLen(len) { + enable_dithering(dither); + mAdvance = 0; + } - mData += skip; +#ifdef SUPPORT_ARGB + PixelController(const CARGB &d, int len, CRGB & s, EDitherMode dither = BINARY_DITHER) : mData((const uint8_t*)&d), mScale(s), mLen(len) { + enable_dithering(dither); + // skip the A in CARGB + mData += 1; + mAdvance = 0; + } - mAdvance = 0; - if(doadvance) { mAdvance = 3 + skip; } + PixelController(const CARGB *d, int len, CRGB & s, EDitherMode dither = BINARY_DITHER) : mData((const uint8_t*)d), mScale(s), mLen(len) { + enable_dithering(dither); + // skip the A in CARGB + mData += 1; + mAdvance = 4; } +#endif - void init_dithering() { + void init_binary_dithering() { static byte R = 0; R++; @@ -172,14 +211,24 @@ struct PixelController { } } + // Do we have n pixels left to process? + __attribute__((always_inline)) inline bool has(int n) { + return mLen >= n; + } + // toggle dithering enable - void enable_dithering(bool enable) { - if(enable) { init_dithering(); } - else { d[0]=d[1]=d[2]=e[0]=e[1]=e[2]=0; } + void enable_dithering(EDitherMode dither) { + switch(dither) { + case BINARY_DITHER: init_binary_dithering(); break; + default: d[0]=d[1]=d[2]=e[0]=e[1]=e[2]=0; break; + } } - // advance the data pointer forward - __attribute__((always_inline)) inline void advanceData() { mData += mAdvance; } + // get the amount to advance the pointer by + __attribute__((always_inline)) inline int advanceBy() { return mAdvance; } + + // advance the data pointer forward, adjust position counter + __attribute__((always_inline)) inline void advanceData() { mData += mAdvance; mLen--;} // step the dithering forward __attribute__((always_inline)) inline void stepDithering() { diff --git a/examples/Cylon/Cylon.ino b/examples/Cylon/Cylon.ino index 28cd0026..443b84d6 100644 --- a/examples/Cylon/Cylon.ino +++ b/examples/Cylon/Cylon.ino @@ -1,19 +1,19 @@ #include "FastLED.h" // How many leds in your strip? -#define NUM_LEDS 8 +#define NUM_LEDS 40 // For led chips like Neopixels, which have a data line, ground, and power, you just // need to define DATA_PIN. For led chipsets that are SPI based (four wires - data, clock, // ground, and power), like the LPD8806, define both DATA_PIN and CLOCK_PIN -#define DATA_PIN 4 +#define DATA_PIN 2 #define CLOCK_PIN 13 // Define the array of leds CRGB leds[NUM_LEDS]; void setup() { - FastLED.addLeds(leds, NUM_LEDS); + FastLED.addLeds(leds, NUM_LEDS); } void loop() { @@ -26,7 +26,7 @@ void loop() { // now that we've shown the leds, reset the i'th led to black leds[i] = CRGB::Black; // Wait a little bit before we loop around and do it again - delay(30); + delay(300); } // Now go in the other direction. @@ -38,6 +38,6 @@ void loop() { // now that we've shown the leds, reset the i'th led to black leds[i] = CRGB::Black; // Wait a little bit before we loop around and do it again - delay(30); + delay(300); } } diff --git a/fastspi_arm_k20.h b/fastspi_arm_k20.h index 906e1a27..ea7cdf33 100644 --- a/fastspi_arm_k20.h +++ b/fastspi_arm_k20.h @@ -291,18 +291,15 @@ public: // 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 void writeBytes3(register uint8_t *data, int len, register CRGB scale, bool advance=true, uint8_t skip=0) { + template void writePixels(PixelController & pixels) { // setSPIRate(); select(); - uint8_t *end = data + len; + int len = pixels.mLen; // Setup the pixel controller - PixelController pixels(data, scale, true, advance, skip); - if((FLAGS & FLAG_START_BIT) == 0) { //If no start bit stupiditiy, write out as many 16-bit blocks as we can - uint8_t *first_end = end - (len % ((3+skip)*2)); - while(data != first_end) { + while(pixels.has(2)) { // Load and write out the first two bytes if(WM == NONE) { wait1(); } Write::writeWord(D::adjust(pixels.loadAndScale0()) << 8 | D::adjust(pixels.loadAndScale1())); @@ -315,11 +312,9 @@ public: Write::writeWord(D::adjust(pixels.loadAndScale1()) << 8 | D::adjust(pixels.loadAndScale2())); pixels.stepDithering(); pixels.advanceData(); - - data += ((3+skip)*2); } - if(data != end) { + if(pixels.has(1)) { if(WM == NONE) { wait1(); } // write out the rest as alternating 16/8-bit blocks (likely to be just one) Write::writeWord(D::adjust(pixels.loadAndScale0()) << 8 | D::adjust(pixels.loadAndScale1())); @@ -335,13 +330,12 @@ public: uint32_t ctar1 = (ctar1_save & (~SPI_CTAR_FMSZ(15))) | SPI_CTAR_FMSZ(8); update_ctar1(ctar1); - while(data != end) { + while(pixels.has(1)) { writeWord( 0x100 | D::adjust(pixels.loadAndScale0())); writeByte(D::adjust(pixels.loadAndScale1())); writeByte(D::adjust(pixels.loadAndScale2())); pixels.advanceData(); pixels.stepDithering(); - data += (3+skip); } D::postBlock(len); waitFully(); @@ -352,18 +346,18 @@ public: release(); } - // template instantiations for writeBytes 3 - template void writeBytes3(register uint8_t *data, int len, register CRGB scale, bool advance=true, uint8_t skip=0) { - writeBytes3(data, len, scale, advance, skip); + // template instantiations for writePixels + template __attribute__((always_inline)) inline void writePixels(PixelController & pixels) { + writePixels(pixels); } - template void writeBytes3(register uint8_t *data, int len, register CRGB scale, bool advance=true, uint8_t skip=0) { - writeBytes3<0, D, RGB_ORDER>(data, len, scale, advance, skip); + template __attribute__((always_inline)) inline void writePixels(PixelController & pixels) { + writePixels<0, D, RGB_ORDER>(pixels); } - template void writeBytes3(register uint8_t *data, int len, register CRGB scale, bool advance=true, uint8_t skip=0) { - writeBytes3<0, DATA_NOP, RGB_ORDER>(data, len, scale, advance, skip); + template __attribute__((always_inline)) inline void writePixels(PixelController & pixels) { + writePixels<0, DATA_NOP, RGB_ORDER>(pixels); } - void writeBytes3(register uint8_t *data, int len, register CRGB scale, bool advance=true, uint8_t skip=0) { - writeBytes3<0, DATA_NOP, RGB>(data, len, scale, advance, skip); + __attribute__((always_inline)) inline void writePixels(PixelController & pixels) { + writePixels<0, DATA_NOP, RGB>(pixels); } }; #endif diff --git a/fastspi_arm_sam.h b/fastspi_arm_sam.h index a0d9fdc4..03a2daad 100644 --- a/fastspi_arm_sam.h +++ b/fastspi_arm_sam.h @@ -129,48 +129,43 @@ public: // 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 void writeBytes3(register uint8_t *data, int len, register CRGB scale, bool advance=true, uint8_t skip=0) { + template void writeBytes3(PixelController & pixels) { select(); - uint8_t *end = data + len; - - // Setup the pixel controller - PixelController pixels(data, scale, true, advance, skip); + int len = pixels.mLen; if(FLAGS & FLAG_START_BIT) { - while(data < end) { + 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(); - data += (3+skip); } } else { - while(data < end) { + while(pixels.has(1)) { writeByte(D::adjust(pixels.loadAndScale0())); writeByte(D::adjust(pixels.loadAndScale1())); writeByte(D::adjust(pixels.loadAndScale2())); pixels.advanceData(); pixels.stepDithering(); - data += (3+skip); } } D::postBlock(len); release(); } - // template instantiations for writeBytes 3 - template void writeBytes3(register uint8_t *data, int len, register CRGB scale, bool advance=true, uint8_t skip=0) { - writeBytes3(data, len, scale, advance, skip); + // template instantiations for writePixels + template __attribute__((always_inline)) inline void writePixels(PixelController & pixels) { + writePixels(pixels); } - template void writeBytes3(register uint8_t *data, int len, register CRGB scale, bool advance=true, uint8_t skip=0) { - writeBytes3<0, D, RGB_ORDER>(data, len, scale, advance, skip); + template __attribute__((always_inline)) inline void writePixels(PixelController & pixels) { + writePixels<0, D, RGB_ORDER>(pixels); } - template void writeBytes3(register uint8_t *data, int len, register CRGB scale, bool advance=true, uint8_t skip=0) { - writeBytes3<0, DATA_NOP, RGB_ORDER>(data, len, scale, advance, skip); + template __attribute__((always_inline)) inline void writePixels(PixelController & pixels) { + writePixels<0, DATA_NOP, RGB_ORDER>(pixels); } - void writeBytes3(register uint8_t *data, int len, register CRGB scale, bool advance=true, uint8_t skip=0) { - writeBytes3<0, DATA_NOP, RGB>(data, len, scale, advance, skip); + __attribute__((always_inline)) inline void writePixels(PixelController & pixels) { + writePixels<0, DATA_NOP, RGB>(pixels); } }; diff --git a/fastspi_avr.h b/fastspi_avr.h index 3099672a..964ab1eb 100644 --- a/fastspi_avr.h +++ b/fastspi_avr.h @@ -267,13 +267,12 @@ public: // 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 void writeBytes3(register uint8_t *data, int len, register CRGB scale, bool advance=true, uint8_t skip=0) { + template void writePixels(PixelController & pixels) { //setSPIRate(); - uint8_t *end = data + len; - PixelController pixels(data, scale, true, advance, skip); + int len = pixels.mLen; select(); - while(data != end) { + while(pixels.has(1)) { if(FLAGS & FLAG_START_BIT) { writeBit<0>(1); writeBytePostWait(D::adjust(pixels.loadAndScale0())); @@ -287,24 +286,23 @@ public: pixels.advanceData(); pixels.stepDithering(); - data += (3+skip); } D::postBlock(len); release(); } - // template instantiations for writeBytes 3 - template void writeBytes3(register uint8_t *data, int len, register CRGB scale, bool advance=true, uint8_t skip=0) { - writeBytes3(data, len, scale, advance, skip); + // template instantiations for writePixels + template __attribute__((always_inline)) inline void writePixels(PixelController & pixels) { + writePixels(pixels); } - template void writeBytes3(register uint8_t *data, int len, register CRGB scale, bool advance=true, uint8_t skip=0) { - writeBytes3<0, D, RGB_ORDER>(data, len, scale, advance, skip); + template __attribute__((always_inline)) inline void writePixels(PixelController & pixels) { + writePixels<0, D, RGB_ORDER>(pixels); } - template void writeBytes3(register uint8_t *data, int len, register CRGB scale, bool advance=true, uint8_t skip=0) { - writeBytes3<0, DATA_NOP, RGB_ORDER>(data, len, scale, advance, skip); + template __attribute__((always_inline)) inline void writePixels(PixelController & pixels) { + writePixels<0, DATA_NOP, RGB_ORDER>(pixels); } - void writeBytes3(register uint8_t *data, int len, register CRGB scale, bool advance=true, uint8_t skip=0) { - writeBytes3<0, DATA_NOP, RGB>(data, len, scale, advance, skip); + __attribute__((always_inline)) inline void writePixels(PixelController & pixels) { + writePixels<0, DATA_NOP, RGB>(pixels); } }; diff --git a/fastspi_bitbang.h b/fastspi_bitbang.h index 8c3650c6..b65a2750 100644 --- a/fastspi_bitbang.h +++ b/fastspi_bitbang.h @@ -286,17 +286,14 @@ public: // 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 of each grouping, as well as a class specifying a per // byte of data modification to be made. (See DATA_NOP above) - template void writeBytes3(register uint8_t *data, int len, register CRGB scale, bool advance=true, uint8_t skip=0) { - // Setup the pixel controller - PixelController pixels(data, scale, true, advance, skip); - + template void writePixels(PixelController & pixels) { select(); + int len = pixels.mLen; #ifdef FAST_SPI_INTERRUPTS_WRITE_PINS // If interrupts or other things may be generating output while we're working on things, then we need // to use this block - uint8_t *end = data + len; - while(data != end) { + while(pixels.has(1)) { if(FLAGS & FLAG_START_BIT) { writeBit<0>(1); } @@ -305,7 +302,6 @@ public: writeByte(D::adjust(pixels.loadAndScale2())); pixels.advanceData(); pixels.stepDithering(); - data += (skip+3); } #else // If we can guaruntee that no one else will be writing data while we are running (namely, changing the values of the PORT/PDOR pins) @@ -320,9 +316,8 @@ public: register data_t datalo = FastPin::loval(); register clock_t clockhi = FastPin::hival(); register clock_t clocklo = FastPin::loval(); - uint8_t *end = data + len; - - while(data != end) { + + while(pixels.has(1)) { if(FLAGS & FLAG_START_BIT) { writeBit<0>(1, clockpin, datapin, datahi, datalo, clockhi, clocklo); } @@ -331,7 +326,6 @@ public: writeByte(D::adjust(pixels.loadAndScale2()), clockpin, datapin, datahi, datalo, clockhi, clocklo); pixels.advanceData(); pixels.stepDithering(); - data += (skip+3); } } else { @@ -341,9 +335,7 @@ public: register data_t datahi_clocklo = FastPin::hival() & ~FastPin::mask(); register data_t datalo_clocklo = FastPin::loval() & ~FastPin::mask(); - uint8_t *end = data + len; - - while(data != end) { + while(pixels.has(1)) { if(FLAGS & FLAG_START_BIT) { writeBit<0>(1, datapin, datahi_clockhi, datalo_clockhi, datahi_clocklo, datalo_clocklo); } @@ -352,7 +344,6 @@ public: writeByte(D::adjust(pixels.loadAndScale2()), datapin, datahi_clockhi, datalo_clockhi, datahi_clocklo, datalo_clocklo); pixels.advanceData(); pixels.stepDithering(); - data += (skip+3); } } #endif @@ -360,18 +351,18 @@ public: release(); } - // template instantiations for writeBytes 3 - template void writeBytes3(register uint8_t *data, int len, register CRGB scale, bool advance=true, uint8_t skip=0) { - writeBytes3(data, len, scale, advance, skip); + // template instantiations for writePixels + template __attribute__((always_inline)) inline void writePixels(PixelController & pixels) { + writePixels(pixels); } - template void writeBytes3(register uint8_t *data, int len, register CRGB scale, bool advance=true, uint8_t skip=0) { - writeBytes3<0, D, RGB_ORDER>(data, len, scale, advance, skip); + template __attribute__((always_inline)) inline void writePixels(PixelController & pixels) { + writePixels<0, D, RGB_ORDER>(pixels); } - template void writeBytes3(register uint8_t *data, int len, register CRGB scale, bool advance=true, uint8_t skip=0) { - writeBytes3<0, DATA_NOP, RGB_ORDER>(data, len, scale, advance, skip); + template __attribute__((always_inline)) inline void writePixels(PixelController & pixels) { + writePixels<0, DATA_NOP, RGB_ORDER>(pixels); } - void writeBytes3(register uint8_t *data, int len, register CRGB scale, bool advance=true, uint8_t skip=0) { - writeBytes3<0, DATA_NOP, RGB>(data, len, scale, advance, skip); + __attribute__((always_inline)) inline void writePixels(PixelController & pixels) { + writePixels<0, DATA_NOP, RGB>(pixels); } }; -- cgit v1.2.3 From 7890ad13620d74fabc242e36ffbd153751dcbfa7 Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Sat, 15 Mar 2014 18:52:55 -0700 Subject: Fix SPI builds --- chipsets.h | 24 ++++++++++++------------ fastspi_arm_k20.h | 16 +--------------- fastspi_arm_sam.h | 17 +---------------- fastspi_avr.h | 17 +---------------- fastspi_bitbang.h | 16 +--------------- 5 files changed, 16 insertions(+), 74 deletions(-) diff --git a/chipsets.h b/chipsets.h index 2cc98dba..e23ee017 100644 --- a/chipsets.h +++ b/chipsets.h @@ -53,18 +53,18 @@ public: } virtual void showColor(const struct CRGB & data, int nLeds, CRGB scale) { - mSPI.template writePixels(PixelController(data, nLeds, scale, getDither())); + mSPI.template writePixels<0, LPD8806_ADJUST, RGB_ORDER>(PixelController(data, nLeds, scale, getDither())); } virtual void show(const struct CRGB *data, int nLeds, CRGB scale) { // TODO rgb-ize scale - mSPI.template writePixels(PixelController(data, nLeds, scale, getDither())); + mSPI.template writePixels<0, LPD8806_ADJUST, RGB_ORDER>(PixelController(data, nLeds, scale, getDither())); } #ifdef SUPPORT_ARGB virtual void show(const struct CARGB *data, int nLeds, uint8_t scale) { checkClear(nLeds); - mSPI.template writePixels(PixelController(data, nLeds, scale, getDither())); + mSPI.template writePixels<0, LPD8806_ADJUST, RGB_ORDER>(PixelController(data, nLeds, scale, getDither())); } #endif }; @@ -97,20 +97,20 @@ public: virtual void showColor(const struct CRGB & data, int nLeds, CRGB scale) { mWaitDelay.wait(); - mSPI.template writePixels(PixelController(data, nLeds, scale, getDither())); + mSPI.template writePixels<0, DATA_NOP, RGB_ORDER>(PixelController(data, nLeds, scale, getDither())); mWaitDelay.mark(); } virtual void show(const struct CRGB *data, int nLeds, CRGB scale) { mWaitDelay.wait(); - mSPI.template writePixels(PixelController(data, nLeds, scale, getDither())); + mSPI.template writePixels<0, DATA_NOP, RGB_ORDER>(PixelController(data, nLeds, scale, getDither())); mWaitDelay.mark(); } #ifdef SUPPORT_ARGB virtual void show(const struct CRGB *data, int nLeds, CRGB scale) { mWaitDelay.wait(); - mSPI.template writePixels(PixelController(data, nLeds, scale, getDither())); + mSPI.template writePixels<0, DATA_NOP, RGB_ORDER>(PixelController(data, nLeds, scale, getDither())); mWaitDelay.mark(); } #endif @@ -142,7 +142,7 @@ public: } virtual void clearLeds(int nLeds) { - showColor(CRGB(0,0,0), nLeds); + showColor(CRGB(0,0,0), nLeds, CRGB(0,0,0)); } virtual void showColor(const struct CRGB & data, int nLeds, CRGB scale) { @@ -162,7 +162,7 @@ public: } virtual void show(const struct CRGB *data, int nLeds, CRGB scale) { - PixelController pixels(data, scale, getDither()); + PixelController pixels(data, nLeds, scale, getDither()); mSPI.select(); @@ -179,7 +179,7 @@ public: #ifdef SUPPORT_ARGB virtual void show(const struct CRGB *data, int nLeds, CRGB scale) { - PixelController pixels(data, scale, getDither()); + PixelController pixels(data, nLeds,, scale, getDither()); mSPI.select(); @@ -238,7 +238,7 @@ public: } virtual void showColor(const struct CRGB & data, int nLeds, CRGB scale) { - mSPI.template writePixels(PixelController(data, nLeds, scale, getDither())); + mSPI.template writePixels(PixelController(data, nLeds, scale, getDither())); writeHeader(); } @@ -246,7 +246,7 @@ public: // Make sure the FLAG_START_BIT flag is set to ensure that an extra 1 bit is sent at the start // of each triplet of bytes for rgb data // writeHeader(); - mSPI.template writePixels( PixelController(data, nLeds, scale, getDither())); + mSPI.template writePixels( PixelController(data, nLeds, scale, getDither())); writeHeader(); } @@ -258,7 +258,7 @@ public: // Make sure the FLAG_START_BIT flag is set to ensure that an extra 1 bit is sent at the start // of each triplet of bytes for rgb data - mSPI.template writePixels(PixelController(data, nLeds, scale, getDither())); + mSPI.template writePixels(PixelController(data, nLeds, scale, getDither())); } #endif }; diff --git a/fastspi_arm_k20.h b/fastspi_arm_k20.h index ea7cdf33..dba602a7 100644 --- a/fastspi_arm_k20.h +++ b/fastspi_arm_k20.h @@ -291,7 +291,7 @@ public: // 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 void writePixels(PixelController & pixels) { + template void writePixels(PixelController pixels) { // setSPIRate(); select(); int len = pixels.mLen; @@ -345,20 +345,6 @@ public: } release(); } - - // template instantiations for writePixels - template __attribute__((always_inline)) inline void writePixels(PixelController & pixels) { - writePixels(pixels); - } - template __attribute__((always_inline)) inline void writePixels(PixelController & pixels) { - writePixels<0, D, RGB_ORDER>(pixels); - } - template __attribute__((always_inline)) inline void writePixels(PixelController & pixels) { - writePixels<0, DATA_NOP, RGB_ORDER>(pixels); - } - __attribute__((always_inline)) inline void writePixels(PixelController & pixels) { - writePixels<0, DATA_NOP, RGB>(pixels); - } }; #endif diff --git a/fastspi_arm_sam.h b/fastspi_arm_sam.h index 03a2daad..8f73b884 100644 --- a/fastspi_arm_sam.h +++ b/fastspi_arm_sam.h @@ -129,7 +129,7 @@ public: // 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 void writeBytes3(PixelController & pixels) { + template void writePixels(PixelController pixels) { select(); int len = pixels.mLen; @@ -153,21 +153,6 @@ public: D::postBlock(len); release(); } - - // template instantiations for writePixels - template __attribute__((always_inline)) inline void writePixels(PixelController & pixels) { - writePixels(pixels); - } - template __attribute__((always_inline)) inline void writePixels(PixelController & pixels) { - writePixels<0, D, RGB_ORDER>(pixels); - } - template __attribute__((always_inline)) inline void writePixels(PixelController & pixels) { - writePixels<0, DATA_NOP, RGB_ORDER>(pixels); - } - __attribute__((always_inline)) inline void writePixels(PixelController & pixels) { - writePixels<0, DATA_NOP, RGB>(pixels); - } - }; #endif diff --git a/fastspi_avr.h b/fastspi_avr.h index 964ab1eb..e6e07fed 100644 --- a/fastspi_avr.h +++ b/fastspi_avr.h @@ -267,7 +267,7 @@ public: // 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 void writePixels(PixelController & pixels) { + template void writePixels(PixelController pixels) { //setSPIRate(); int len = pixels.mLen; @@ -290,21 +290,6 @@ public: D::postBlock(len); release(); } - - // template instantiations for writePixels - template __attribute__((always_inline)) inline void writePixels(PixelController & pixels) { - writePixels(pixels); - } - template __attribute__((always_inline)) inline void writePixels(PixelController & pixels) { - writePixels<0, D, RGB_ORDER>(pixels); - } - template __attribute__((always_inline)) inline void writePixels(PixelController & pixels) { - writePixels<0, DATA_NOP, RGB_ORDER>(pixels); - } - __attribute__((always_inline)) inline void writePixels(PixelController & pixels) { - writePixels<0, DATA_NOP, RGB>(pixels); - } - }; #endif diff --git a/fastspi_bitbang.h b/fastspi_bitbang.h index b65a2750..fa50e470 100644 --- a/fastspi_bitbang.h +++ b/fastspi_bitbang.h @@ -286,7 +286,7 @@ public: // 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 of each grouping, as well as a class specifying a per // byte of data modification to be made. (See DATA_NOP above) - template void writePixels(PixelController & pixels) { + template void writePixels(PixelController pixels) { select(); int len = pixels.mLen; @@ -350,20 +350,6 @@ public: D::postBlock(len); release(); } - - // template instantiations for writePixels - template __attribute__((always_inline)) inline void writePixels(PixelController & pixels) { - writePixels(pixels); - } - template __attribute__((always_inline)) inline void writePixels(PixelController & pixels) { - writePixels<0, D, RGB_ORDER>(pixels); - } - template __attribute__((always_inline)) inline void writePixels(PixelController & pixels) { - writePixels<0, DATA_NOP, RGB_ORDER>(pixels); - } - __attribute__((always_inline)) inline void writePixels(PixelController & pixels) { - writePixels<0, DATA_NOP, RGB>(pixels); - } }; #endif -- cgit v1.2.3 From 4f74b580304eb04b007a22457b4981360d620f5e Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Sat, 15 Mar 2014 21:30:46 -0700 Subject: Tweak variable ordering to play nicer w/gcc register allocation --- clockless_trinket.h | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/clockless_trinket.h b/clockless_trinket.h index c0e9da1e..dea96997 100644 --- a/clockless_trinket.h +++ b/clockless_trinket.h @@ -189,7 +189,7 @@ public: #define DONE asm __volatile__("2:" ASM_VARS ); // 2 cycles - increment the data pointer -#define IDATA2 asm __volatile__("add %A[data], %A[ADV]\n\tadc %B[data], %B[ADV]" ASM_VARS ); +#define IDATA2 asm __volatile__("add %A[data], %[ADV]\n\tadc %B[data], __zero_reg__" 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 @@ -203,9 +203,7 @@ public: // 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__ ((noinline)) showRGBInternal(PixelController & pixels) { - register byte *data = (byte*)pixels.mData; - uint16_t advanceBy = pixels.advanceBy(); - uint16_t count = pixels.mLen; + uint8_t *data = (uint8_t*)pixels.mData; data_t mask = FastPin::mask(); data_ptr_t port = FastPin::port(); @@ -225,6 +223,9 @@ public: // pull the dithering/adjustment values out of the pixels object for direct asm access uint8_t scale_base = 0; + 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)]; @@ -235,7 +236,7 @@ public: uint8_t e1 = pixels.e[RO(1)]; uint8_t e2 = pixels.e[RO(2)]; - register uint8_t loopvar=0; + uint8_t loopvar=0; { while(count--) -- cgit v1.2.3 From 4c8c94514f46d9cf944d6bec8d64180ae02b5d38 Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Sun, 16 Mar 2014 02:43:30 -0700 Subject: * Move controller linkage to linked list, get rid of constant array of controllers * Perform memory usage trimming on avr code and code across the board * Tweak template instantiations for clockless chipsets to get rid of spurious globals that were never being used. --- FastLED.cpp | 64 +++++---------- FastLED.h | 127 +++++++++++++++--------------- block_clockless.h | 6 +- clockless2.h | 8 +- clockless_arm_k20.h | 6 +- clockless_arm_sam.h | 6 +- clockless_avr.h | 201 ----------------------------------------------- clockless_trinket.h | 35 +++++---- controller.h | 127 ++++++++++++++++-------------- delay.h | 20 ++++- dmx.h | 20 ----- examples/Cylon/Cylon.ino | 6 +- fastpin.h | 17 ---- pixeltypes.h | 2 +- 14 files changed, 208 insertions(+), 437 deletions(-) delete mode 100644 clockless_avr.h diff --git a/FastLED.cpp b/FastLED.cpp index 076bac21..2b5d7698 100644 --- a/FastLED.cpp +++ b/FastLED.cpp @@ -9,13 +9,15 @@ CFastLED & FastSPI_LED = LEDS; CFastLED & FastSPI_LED2 = LEDS; CFastLED & FastLED = LEDS; -uint32_t CRGB::Squant = ((uint32_t)((__TIME__[4]-'0') * 28))<<16 | ((__TIME__[6]-'0')*50)<<8 | ((__TIME__[7]-'0')*28); +CLEDController *CLEDController::m_pHead = NULL; +CLEDController *CLEDController::m_pTail = NULL; + +// uint32_t CRGB::Squant = ((uint32_t)((__TIME__[4]-'0') * 28))<<16 | ((__TIME__[6]-'0')*50)<<8 | ((__TIME__[7]-'0')*28); CFastLED::CFastLED() { // clear out the array of led controllers - m_nControllers = NUM_CONTROLLERS; + // m_nControllers = 0; m_Scale = 255; - memset8(m_Controllers, 0, m_nControllers * sizeof(CControllerInfo)); } CLEDController &CFastLED::addLeds(CLEDController *pLed, @@ -24,46 +26,24 @@ CLEDController &CFastLED::addLeds(CLEDController *pLed, int nOffset = (nLedsIfOffset > 0) ? nLedsOrOffset : 0; int nLeds = (nLedsIfOffset > 0) ? nLedsIfOffset : nLedsOrOffset; - int target = -1; - - // Figure out where to put the new led controller - for(int i = 0; i < m_nControllers; i++) { - if(m_Controllers[i].pLedController == NULL) { - target = i; - break; - } - } - - // if we have a spot, use it! - if(target != -1) { - m_Controllers[target].pLedController = pLed; - m_Controllers[target].pLedData = data; - m_Controllers[target].nOffset = nOffset; - m_Controllers[target].nLeds = nLeds; - pLed->init(); - } - + pLed->init(); + pLed->setLeds(data + nOffset, nLeds); return *pLed; } void CFastLED::show(uint8_t scale) { - for(int i = 0; i < m_nControllers; i++) { - if(m_Controllers[i].pLedController != NULL) { - m_Controllers[i].pLedController->show(m_Controllers[i].pLedData + m_Controllers[i].nOffset, - m_Controllers[i].nLeds, scale); - } else { - return; - } + CLEDController *pCur = CLEDController::head(); + while(pCur) { + pCur->showLeds(scale); + pCur = pCur->next(); } } void CFastLED::showColor(const struct CRGB & color, uint8_t scale) { - for(int i = 0; i < m_nControllers; i++) { - if(m_Controllers[i].pLedController != NULL) { - m_Controllers[i].pLedController->showColor(color, m_Controllers[i].nLeds, scale); - } else { - return; - } + CLEDController *pCur = CLEDController::head(); + while(pCur) { + pCur->showColor(color, scale); + pCur = pCur->next(); } } @@ -71,20 +51,18 @@ void CFastLED::clear(boolean writeData) { if(writeData) { showColor(CRGB(0,0,0), 0); } - clearData(); + clearData(); } void CFastLED::clearData() { - for(int i = 0; i < m_nControllers; i++) { - if(m_Controllers[i].pLedData != NULL) { - memset8((void*)m_Controllers[i].pLedData, 0, sizeof(struct CRGB) * m_Controllers[i].nLeds); - } else { - return; - } + CLEDController *pCur = CLEDController::head(); + while(pCur) { + pCur->clearLedData(); + pCur = pCur->next(); } } void CFastLED::delay(unsigned long ms) { unsigned long start = millis(); - while((millis()-start) < ms) { LEDS.show(); } + while((millis()-start) < ms) { show(); } } diff --git a/FastLED.h b/FastLED.h index 8dbebb69..1fe8acdb 100644 --- a/FastLED.h +++ b/FastLED.h @@ -18,22 +18,41 @@ enum ESPIChipsets { }; enum EClocklessChipsets { - DMX, - TM1809, - TM1804, - TM1803, - WS2811, - WS2812, - WS2812B, - UCS1903, - UCS1903B, - WS2811_400, - NEOPIXEL, - GW6205, - GW6205_400, - TM1829 + DMX + // TM1809, + // TM1804, + // TM1803, + // WS2811, + // WS2812, + // WS2812B, + // UCS1903, + // UCS1903B, + // WS2811_400, + // // NEOPIXEL, + // GW6205, + // GW6205_400, + // TM1829 }; +template class NEOPIXEL : public WS2811Controller800Khz {}; +template class TM1829 : public TM1829Controller800Khz {}; +template class TM1809 : public TM1809Controller800Khz {}; +template class TM1804 : public TM1809Controller800Khz {}; +template class TM1803 : public TM1803Controller400Khz {}; +template class UCS1903 : public UCS1903Controller400Khz {}; +template class UCS1903B : public UCS1903BController800Khz {}; +template class WS2812 : public WS2811Controller800Khz {}; +template class WS2812B : public WS2811Controller800Khz {}; +template class WS2811 : public WS2811Controller800Khz {}; +template class WS2811_400 : public WS2811Controller400Khz {}; +template class GW6205 : public GW6205Controller800Khz {}; +template class GW6205_400 : public GW6205Controller400Khz {}; + +// template class LPD8806 : public LPD8806Controller {}; +// template class WS2801 : public WS2801Controller {}; +// template class P9813 : public P9813Controller {}; +// template class SM16716 : public SM16716Controller {}; + enum EBlockChipsets { WS2811_PORTC }; @@ -45,23 +64,15 @@ enum EBlockChipsets { #endif class CFastLED { - struct CControllerInfo { - CLEDController *pLedController; - const struct CRGB *pLedData; - int nLeds; - int nOffset; - }; - - CControllerInfo m_Controllers[NUM_CONTROLLERS]; - int m_nControllers; + // int m_nControllers; uint8_t m_Scale; public: CFastLED(); - CLEDController &addLeds(CLEDController *pLed, const struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0); + static CLEDController &addLeds(CLEDController *pLed, const struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0); - template CLEDController &addLeds(const struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) { + template static CLEDController &addLeds(const struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) { switch(CHIPSET) { case LPD8806: { static LPD8806Controller c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); } case WS2801: { static WS2801Controller c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); } @@ -69,7 +80,7 @@ public: } } - template CLEDController &addLeds(const struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) { + template static CLEDController &addLeds(const struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) { switch(CHIPSET) { case LPD8806: { static LPD8806Controller c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); } case WS2801: { static WS2801Controller c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); } @@ -88,67 +99,59 @@ public: } #ifdef SPI_DATA - template CLEDController &addLeds(const struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) { + template static CLEDController &addLeds(const struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) { return addLeds(data, nLedsOrOffset, nLedsIfOffset); } - template CLEDController &addLeds(const struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) { + template static CLEDController &addLeds(const struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) { return addLeds(data, nLedsOrOffset, nLedsIfOffset); } - template CLEDController &addLeds(const struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) { + template static CLEDController &addLeds(const struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) { return addLeds(data, nLedsOrOffset, nLedsIfOffset); } #endif + template class CHIPSET, uint8_t DATA_PIN> + static CLEDController &addLeds(const struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) { + static CHIPSET c; + return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); + } + + template class CHIPSET, uint8_t DATA_PIN, EOrder RGB_ORDER> + static CLEDController &addLeds(const struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) { + static CHIPSET c; + return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); + } + + template class CHIPSET, uint8_t DATA_PIN> + static CLEDController &addLeds(const struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) { + static CHIPSET c; + return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); + } + + +#ifdef FASTSPI_USE_DMX_SIMPLE template - CLEDController &addLeds(const struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) { + static CLEDController &addLeds(const struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) + { switch(CHIPSET) { -#ifdef FASTSPI_USE_DMX_SIMPLE case DMX: { static DMXController controller; return addLeds(&controller, data, nLedsOrOffset, nLedsIfOffset); } -#endif - case TM1829: { static TM1829Controller800Khz controller; return addLeds(&controller, data, nLedsOrOffset, nLedsIfOffset); } - case TM1804: - case TM1809: { static TM1809Controller800Khz controller; return addLeds(&controller, data, nLedsOrOffset, nLedsIfOffset); } - case TM1803: { static TM1803Controller400Khz controller; return addLeds(&controller, data, nLedsOrOffset, nLedsIfOffset); } - case UCS1903: { static UCS1903Controller400Khz controller; return addLeds(&controller, data, nLedsOrOffset, nLedsIfOffset); } - case UCS1903B: { static UCS1903BController800Khz controller; return addLeds(&controller, data, nLedsOrOffset, nLedsIfOffset); } - case WS2812: - case WS2812B: - case WS2811: { static WS2811Controller800Khz controller; return addLeds(&controller, data, nLedsOrOffset, nLedsIfOffset); } - case NEOPIXEL: { static WS2811Controller800Khz controller; return addLeds(&controller, data, nLedsOrOffset, nLedsIfOffset); } - case WS2811_400: { static WS2811Controller400Khz controller; return addLeds(&controller, data, nLedsOrOffset, nLedsIfOffset); } - case GW6205: { static GW6205Controller800Khz controller; return addLeds(&controller, data, nLedsOrOffset, nLedsIfOffset); } - case GW6205_400: { static GW6205Controller400Khz controller; return addLeds(&controller, data, nLedsOrOffset, nLedsIfOffset); } } } template - CLEDController &addLeds(const struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) { + static CLEDController &addLeds(const struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) { switch(CHIPSET) { -#ifdef FASTSPI_USE_DMX_SIMPLE case DMX: {static DMXController controller; return addLeds(&controller, data, nLedsOrOffset, nLedsIfOffset); } -#endif - case TM1829: { static TM1829Controller800Khz controller; return addLeds(&controller, data, nLedsOrOffset, nLedsIfOffset); } - case TM1804: - case TM1809: { static TM1809Controller800Khz controller; return addLeds(&controller, data, nLedsOrOffset, nLedsIfOffset); } - case TM1803: { static TM1803Controller400Khz controller; return addLeds(&controller, data, nLedsOrOffset, nLedsIfOffset); } - case UCS1903: { static UCS1903Controller400Khz controller; return addLeds(&controller, data, nLedsOrOffset, nLedsIfOffset); } - case UCS1903B: { static UCS1903BController800Khz controller; return addLeds(&controller, data, nLedsOrOffset, nLedsIfOffset); } - case WS2812: - case WS2812B: - case NEOPIXEL: - case WS2811: { static WS2811Controller800Khz controller; return addLeds(&controller, data, nLedsOrOffset, nLedsIfOffset); } - case WS2811_400: { static WS2811Controller400Khz controller; return addLeds(&controller, data, nLedsOrOffset, nLedsIfOffset); } - case GW6205: { static GW6205Controller800Khz controller; return addLeds(&controller, data, nLedsOrOffset, nLedsIfOffset); } - case GW6205_400: { static GW6205Controller400Khz controller; return addLeds(&controller, data, nLedsOrOffset, nLedsIfOffset); } } } +#endif #ifdef HAS_BLOCKLESS template - CLEDController &addLeds(const struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) { + static CLEDController &addLeds(const struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) { switch(CHIPSET) { case WS2811_PORTC: return addLeds(new BlockClocklessController(), data, nLedsOrOffset, nLedsIfOffset); } diff --git a/block_clockless.h b/block_clockless.h index 350e0d65..d561239c 100644 --- a/block_clockless.h +++ b/block_clockless.h @@ -90,7 +90,7 @@ public: // showRGBInternal<0, false>(nLeds, scale, (const byte*)&data); // Adjust the timer - long microsTaken = CLKS_TO_MICROS(nLeds * 8 * (T1 + T2 + T3)); + long microsTaken = nLeds * CLKS_TO_MICROS(24 * (T1 + T2 + T3)); MS_COUNTER += (microsTaken / 1000); savedClock.restore(); sei(); @@ -107,7 +107,7 @@ public: showRGBInternal<0, true>(nLeds); // Adjust the timer - long microsTaken = CLKS_TO_MICROS(nLeds * 8 * (T1 + T2 + T3)); + long microsTaken = nLeds * CLKS_TO_MICROS(24 * (T1 + T2 + T3)); MS_COUNTER += (microsTaken / 1000); savedClock.restore(); sei(); @@ -125,7 +125,7 @@ public: showRGBInternal<1, true>(nLeds, scale, (const byte*)rgbdata); // Adjust the timer - long microsTaken = CLKS_TO_MICROS(nLeds * 8 * (T1 + T2 + T3)); + long microsTaken = nLeds * CLKS_TO_MICROS(24 * (T1 + T2 + T3)); MS_COUNTER += (microsTaken / 1000); savedClock.restore(); sei(); diff --git a/clockless2.h b/clockless2.h index 68e6477a..c48cde5d 100644 --- a/clockless2.h +++ b/clockless2.h @@ -48,7 +48,7 @@ public: showRGBInternal<0, false>(nLeds, scale, (const byte*)&data, (const byte*)&data); // Adjust the timer - long microsTaken = CLKS_TO_MICROS(nLeds * 8 * (T1 + T2 + T3)); + long microsTaken = nLeds * CLKS_TO_MICROS(24 * (T1 + T2 + T3)); MS_COUNTER += (microsTaken / 1000); sei(); mWait.mark(); @@ -61,7 +61,7 @@ public: showRGBInternal<0, true>(nLeds, scale, (const byte*)rgbdata, (const byte*)rgbdata); // Adjust the timer - long microsTaken = CLKS_TO_MICROS(nLeds * 8 * (T1 + T2 + T3)); + long microsTaken = nLeds * CLKS_TO_MICROS(24 * (T1 + T2 + T3)); MS_COUNTER += (microsTaken / 1000); sei(); mWait.mark(); @@ -74,7 +74,7 @@ public: showRGBInternal<0, true>(nLeds, scale, (const byte*)rgbdata, (const byte*)rgbdata2 ); // Adjust the timer - long microsTaken = CLKS_TO_MICROS(nLeds * 8 * (T1 + T2 + T3)); + long microsTaken = nLeds * CLKS_TO_MICROS(24 * (T1 + T2 + T3)); MS_COUNTER += (microsTaken / 1000); sei(); mWait.mark(); @@ -88,7 +88,7 @@ public: showRGBInternal<1, true>(nLeds, scale, (const byte*)rgbdata); // Adjust the timer - long microsTaken = CLKS_TO_MICROS(nLeds * 8 * (T1 + T2 + T3)); + long microsTaken = nLeds * CLKS_TO_MICROS(24 * (T1 + T2 + T3)); MS_COUNTER += (microsTaken / 1000); sei(); mWait.mark(); diff --git a/clockless_arm_k20.h b/clockless_arm_k20.h index 2ab6d27a..59905d45 100644 --- a/clockless_arm_k20.h +++ b/clockless_arm_k20.h @@ -31,7 +31,7 @@ public: showRGBInternal(PixelController(rgbdata, nLeds, scale, getDither())); // Adjust the timer - long microsTaken = CLKS_TO_MICROS((long)nLeds * 8 * (T1 + T2 + T3)); + long microsTaken = nLeds * CLKS_TO_MICROS(24 * (T1 + T2 + T3)); MS_COUNTER += (microsTaken / 1000); sei(); mWait.mark(); @@ -44,7 +44,7 @@ public: showRGBInternal(PixelController(rgbdata, nLeds, scale, getDither())); // Adjust the timer - long microsTaken = CLKS_TO_MICROS((long)nLeds * 8 * (T1 + T2 + T3)); + long microsTaken = nLeds * CLKS_TO_MICROS(24 * (T1 + T2 + T3)); MS_COUNTER += (microsTaken / 1000); sei(); mWait.mark(); @@ -59,7 +59,7 @@ public: // Adjust the timer - long microsTaken = CLKS_TO_MICROS((long)nLeds * 8 * (T1 + T2 + T3)); + long microsTaken = nLeds * CLKS_TO_MICROS(24 * (T1 + T2 + T3)); MS_COUNTER += (microsTaken / 1000); sei(); mWait.mark(); diff --git a/clockless_arm_sam.h b/clockless_arm_sam.h index c7781970..3d0f9264 100644 --- a/clockless_arm_sam.h +++ b/clockless_arm_sam.h @@ -43,7 +43,7 @@ public: showRGBInternal(PixelController(data, nLeds, scale, getDither())); // Adjust the timer - long microsTaken = CLKS_TO_MICROS((long)nLeds * 8 * (TOTAL)); + long microsTaken = nLeds * CLKS_TO_MICROS(24 * (TOTAL)); long millisTaken = (microsTaken / 1000); savedClock.restore(); do { TimeTick_Increment(); } while(--millisTaken > 0); @@ -64,7 +64,7 @@ public: showRGBInternal(PixelController(rgbdata, nLeds, scale, getDither())); // Adjust the timer - long microsTaken = CLKS_TO_MICROS((long)nLeds * 8 * (TOTAL)); + long microsTaken = nLeds * CLKS_TO_MICROS(24 * (TOTAL)); long millisTaken = (microsTaken / 1000); savedClock.restore(); do { TimeTick_Increment(); } while(--millisTaken > 0); @@ -81,7 +81,7 @@ public: showRGBInternal(PixelController(rgbdata, nLeds, scale, getDither())); // Adjust the timer - long microsTaken = CLKS_TO_MICROS((long)nLeds * 8 * (TOTAL)); + long microsTaken = nLeds * CLKS_TO_MICROS(24 * (TOTAL)); long millisTaken = (microsTaken / 1000); savedClock.restore(); do { TimeTick_Increment(); } while(--millisTaken > 0); diff --git a/clockless_avr.h b/clockless_avr.h deleted file mode 100644 index 887188b3..00000000 --- a/clockless_avr.h +++ /dev/null @@ -1,201 +0,0 @@ -#ifndef __CLOCKLESS_AVR_H -#define __CLOCKLESS_AVR_H - -#ifdef FASTLED_AVR - -// Definition for a single channel clockless controller for the avr family of chips, like those used in -// the arduino and teensy 2.x. Note that there is a special case for hardware-mul-less versions of the avr, -// which are tracked in clockless_trinket.h -template -class ClocklessController : public CLEDController { - typedef typename FastPin::port_ptr_t data_ptr_t; - typedef typename FastPin::port_t data_t; - - data_t mPinMask; - data_ptr_t mPort; - CMinWait mWait; -public: - virtual void init() { - FastPin::setOutput(); - mPinMask = FastPin::mask(); - mPort = FastPin::port(); - } - - template inline static void bitSetLast(register data_ptr_t port, register data_t hi, register data_t lo, register uint8_t b) { - // First cycle - SET_HI; // 1 clock cycle if using out, 2 otherwise - delaycycles(); // 1st cycle length minus 1 clock for out, 1 clock for sbrs - __asm__ __volatile__ ("sbrs %0, %1" :: "r" (b), "M" (N) :); // 1 clock for check (+1 if skipping, next op is also 1 clock) - - // Second cycle - SET_LO; // 1/2 clock cycle if using out - delaycycles(); // 2nd cycle length minus 1/2 clock for out - - // Third cycle - SET_LO; // 1/2 clock cycle if using out - delaycycles(); // 3rd cycle length minus 7 clocks for out, loop compare, jump, next uint8_t load - } - - virtual void clearLeds(int nLeds) { - showColor(CRGB(0, 0, 0), nLeds, 0); - } - - // set all the leds on the controller to a given color - virtual void showColor(const struct CRGB & data, int nLeds, uint8_t scale = 255) { - mWait.wait(); - cli(); - - showRGBInternal<0, false>(nLeds, scale, (const byte*)&data); - - // Adjust the timer - long microsTaken = CLKS_TO_MICROS((long)nLeds * 8 * (T1 + T2 + T3)); - MS_COUNTER += (microsTaken / 1000); - sei(); - mWait.mark(); - } - - virtual void show(const struct CRGB *rgbdata, int nLeds, uint8_t scale = 255) { - mWait.wait(); - cli(); - - showRGBInternal<0, true>(nLeds, scale, (const byte*)rgbdata); - - // Adjust the timer - long microsTaken = CLKS_TO_MICROS((long)nLeds * 8 * (T1 + T2 + T3)); - MS_COUNTER += (microsTaken / 1000); - sei(); - mWait.mark(); - } - -#ifdef SUPPORT_ARGB - virtual void show(const struct CARGB *rgbdata, int nLeds, uint8_t scale = 255) { - mWait.wait(); - cli(); - - showRGBInternal<1, true>((long)nLeds, scale, (const byte*)rgbdata); - - // Adjust the timer - long microsTaken = CLKS_TO_MICROS((long)nLeds * 8 * (T1 + T2 + T3)); - MS_COUNTER += (microsTaken / 1000); - sei(); - mWait.mark(); - } -#endif - - // 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. - template static void showRGBInternal(register int nLeds, register uint8_t scale, register const byte *rgbdata) { - register byte *data = (byte*)rgbdata; - register data_ptr_t port = FastPin::port(); - nLeds *= (3 + SKIP); - register uint8_t *end = data + nLeds; - register data_t hi = FastPin::hival(); - register data_t lo = FastPin::loval();; - *port = lo; - - register uint8_t b; - - if(ADVANCE) { - b = data[SKIP + RGB_BYTE0(RGB_ORDER)]; - } else { - b = rgbdata[SKIP + RGB_BYTE0(RGB_ORDER)]; - } - b = scale8_LEAVING_R1_DIRTY(b, scale); - - register uint8_t c; - register uint8_t d; - while(data < end) { - for(register byte x=5; x; x--) { - bitSetLast<7, 4>(port, hi, lo, b); - b <<= 1; - } - delaycycles<1>(); - // Leave an extra 2 clocks for the next byte load - bitSetLast<7, 1>(port, hi, lo, b); - delaycycles<1>(); - - // Leave an extra 4 clocks for the scale - bitSetLast<6, 6>(port, hi, lo, b); - if(ADVANCE) { - c = data[SKIP + RGB_BYTE1(RGB_ORDER)]; - } else { - c = rgbdata[SKIP + RGB_BYTE1(RGB_ORDER)]; - delaycycles<1>(); - } - INLINE_SCALE(c, scale); - bitSetLast<5, 1>(port, hi, lo, b); - - if(XTRA0 > 0) { - for(register byte x=XTRA0; x; x--) { - bitSetLast<4,4>(port, hi, lo, b); - b <<=1; - } - delaycycles<1>(); - } - - for(register byte x=5; x; x--) { - bitSetLast<7, 4>(port, hi, lo, c); - c <<= 1; - } - delaycycles<1>(); - // Leave an extra 2 clocks for the next byte load - bitSetLast<7, 1>(port, hi, lo, c); - delaycycles<1>(); - - // Leave an extra 4 clocks for the scale - bitSetLast<6, 6>(port, hi, lo, c); - if(ADVANCE) { - d = data[SKIP + RGB_BYTE2(RGB_ORDER)]; - } else { - d = rgbdata[SKIP + RGB_BYTE2(RGB_ORDER)]; - delaycycles<1>(); - } - INLINE_SCALE(d, scale); - bitSetLast<5, 1>(port, hi, lo, c); - - if(XTRA0 > 0) { - for(register byte x=XTRA0; x; x--) { - bitSetLast<4,4>(port, hi, lo, c); - c <<=1; - } - delaycycles<1>(); - } - - for(register byte x=5; x; x--) { - bitSetLast<7, 4>(port, hi, lo, c); - c <<= 1; - } - delaycycles<1>(); - // Leave an extra 2 clocks for the next byte load - bitSetLast<7, 2>(port, hi, lo, d); - data += (SKIP + 3); - // Leave an extra 4 clocks for the scale - bitSetLast<6, 6>(port, hi, lo, d); - if(ADVANCE) { - b = data[SKIP + RGB_BYTE0(RGB_ORDER)]; - } else { - b = rgbdata[SKIP + RGB_BYTE0(RGB_ORDER)]; - delaycycles<1>(); - } - INLINE_SCALE(b, scale); - - if(XTRA0 > 0) { - bitSetLast<5, 1>(port, hi, lo, d); - for(register byte x=XTRA0-1; x; x--) { - bitSetLast<4,4>(port, hi, lo, d); - d <<=1; - } - delaycycles<1>(); - bitSetLast<4,6>(port,hi,lo,d); - } else { - bitSetLast<5,6>(port, hi, lo, d); - } - - } - cleanup_R1(); - } -}; -#endif - -#endif - diff --git a/clockless_trinket.h b/clockless_trinket.h index dea96997..83cd2e84 100644 --- a/clockless_trinket.h +++ b/clockless_trinket.h @@ -68,37 +68,38 @@ public: } virtual void clearLeds(int nLeds) { - static CRGB zeros(0,0,0); - showRGBInternal_AdjTime(PixelController(zeros, nLeds, zeros, getDither())); + CRGB zeros(0,0,0); + showAdjTime((uint8_t*)&zeros, nLeds, zeros, false, 0); } // set all the leds on the controller to a given color virtual void showColor(const struct CRGB & rgbdata, int nLeds, CRGB scale) { - showRGBInternal_AdjTime(PixelController(rgbdata, nLeds, scale, getDither())); + showAdjTime((uint8_t*)&rgbdata, nLeds, scale, false, 0); } virtual void show(const struct CRGB *rgbdata, int nLeds, CRGB scale) { - showRGBInternal_AdjTime(PixelController(rgbdata, nLeds, scale, getDither())); + showAdjTime((uint8_t*)rgbdata, nLeds, scale, true, 0); } #ifdef SUPPORT_ARGB virtual void show(const struct CARGB *rgbdata, int nLeds, CRGB scale) { - showRGBInternal_AdjTime(PixelController(rgbdata, nLeds, scale, getDither())); + showAdjTime((uint8_t*)rgbdata, nLeds, scale, true, 1); } #endif - void __attribute__ ((noinline)) showRGBInternal_AdjTime(PixelController pixels) { + void showAdjTime(const uint8_t *data, int nLeds, CRGB & scale, bool advance, int skip) { mWait.wait(); cli(); + + PixelController pixels(data, nLeds, scale, getDither(), advance, skip); showRGBInternal(pixels); // Adjust the timer - long microsTaken = CLKS_TO_MICROS((long)pixels.mLen * 24 * (T1 + T2 + T3)); - MS_COUNTER += (microsTaken / 1000); + uint16_t microsTaken = nLeds * CLKS_TO_MICROS(24 * (T1 + T2 + T3)); + MS_COUNTER += (microsTaken >> 10); 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 @@ -109,11 +110,11 @@ public: [b0] "+a" (b0), \ [b1] "+a" (b1), \ [b2] "+a" (b2), \ + [scale_base] "+a" (scale_base), \ + [loopvar] "+a" (loopvar), \ [d0] "+r" (d0), \ [d1] "+r" (d1), \ - [d2] "+r" (d2), \ - [scale_base] "+a" (scale_base), \ - [loopvar] "+a" (loopvar) \ + [d2] "+r" (d2) \ : /* use variables */ \ [ADV] "r" (advanceBy), \ [hi] "r" (hi), \ @@ -202,11 +203,12 @@ public: // 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__ ((noinline)) showRGBInternal(PixelController & pixels) { + static void __attribute__ ((always_inline)) showRGBInternal(PixelController & pixels) { uint8_t *data = (uint8_t*)pixels.mData; - - data_t mask = FastPin::mask(); data_ptr_t port = FastPin::port(); + data_t mask = FastPin::mask(); + uint8_t scale_base = 0; + // register uint8_t *end = data + nLeds; data_t hi = *port | mask; data_t lo = *port & ~mask; @@ -221,7 +223,6 @@ public: b0 = pixels.loadAndScale0(); // pull the dithering/adjustment values out of the pixels object for direct asm access - uint8_t scale_base = 0; uint8_t advanceBy = pixels.advanceBy(); uint16_t count = pixels.mLen; @@ -247,7 +248,7 @@ public: ADJDITHER2(d0,e0); ADJDITHER2(d1,e1); ADJDITHER2(d2,e2); - CLC1; + // 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. diff --git a/controller.h b/controller.h index 1156f9e9..ee2e6d62 100644 --- a/controller.h +++ b/controller.h @@ -14,10 +14,9 @@ // operator byte *(struct CRGB[] arr) { return (byte*)arr; } -enum EDitherMode { - DISABLE = 0x00, - BINARY_DITHER = 0x01 -}; +#define DISABLE_DITHER 0x00 +#define BINARY_DITHER 0x01 +typedef uint8_t EDitherMode; ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // @@ -32,9 +31,15 @@ enum EDitherMode { /// directly at all class CLEDController { protected: + friend class CFastLED; + const CRGB *m_Data; + CLEDController *m_pNext; CRGB m_ColorCorrection; CRGB m_ColorTemperature; EDitherMode m_DitherMode; + int m_nLeds; + static CLEDController *m_pHead; + static CLEDController *m_pTail; // set all the leds on the controller to a given color virtual void showColor(const struct CRGB & data, int nLeds, CRGB scale) = 0; @@ -48,23 +53,19 @@ protected: virtual void show(const struct CARGB *data, int nLeds, CRGB scale) = 0; #endif public: - CLEDController() : m_ColorCorrection(UncorrectedColor), m_ColorTemperature(UncorrectedTemperature) {} + CLEDController() : m_Data(NULL), m_ColorCorrection(UncorrectedColor), m_ColorTemperature(UncorrectedTemperature), m_DitherMode(BINARY_DITHER), m_nLeds(0) { + m_pNext = NULL; + if(m_pHead==NULL) { m_pHead = this; } + if(m_pTail != NULL) { m_pTail->m_pNext = this; } + m_pTail = this; + } // initialize the LED controller virtual void init() = 0; - // reset any internal state to a clean point - virtual void reset() { init(); } - // clear out/zero out the given number of leds. virtual void clearLeds(int nLeds) = 0; - // is the controller ready to write data out - virtual bool ready() { return true; } - - // wait until the controller is ready to write data out - virtual void wait() { return; } - // show function w/integer brightness, will scale for color correction and temperature void show(const struct CRGB *data, int nLeds, uint8_t brightness) { show(data, nLeds, getAdjustment(brightness)); @@ -75,6 +76,19 @@ public: showColor(data, nLeds, getAdjustment(brightness)); } + // show function using the "attached to this controller" led data + void showLeds(uint8_t brightness=255) { + show(m_Data, m_nLeds, getAdjustment(brightness)); + } + + void showColor(const struct CRGB & data, uint8_t brightness=255) { + showColor(data, m_nLeds, getAdjustment(brightness)); + } + + // navigating the list of controllers + static CLEDController *head() { return m_pHead; } + CLEDController *next() { return m_pNext; } + #ifdef SUPPORT_ARGB // as above, but every 4th uint8_t is assumed to be alpha channel data, and will be skipped void show(const struct CARGB *data, int nLeds, uint8_t brightness) { @@ -82,8 +96,20 @@ public: } #endif - inline CLEDController & setDither(EDitherMode = BINARY_DITHER) { m_DitherMode = BINARY_DITHER; return *this; } - inline EDitherMode getDither() { return m_DitherMode; } + CLEDController & setLeds(const CRGB *data, int nLeds) { + m_Data = data; + m_nLeds = nLeds; + return *this; + } + + void clearLedData() { + if(m_Data) { + memset8((void*)m_Data, 0, sizeof(struct CRGB) * m_nLeds); + } + } + + inline CLEDController & setDither(uint8_t ditherMode = BINARY_DITHER) { m_DitherMode = ditherMode; return *this; } + inline uint8_t getDither() { return m_DitherMode; } CLEDController & setCorrection(CRGB correction) { m_ColorCorrection = correction; return *this; } CLEDController & setCorrection(LEDColorCorrection correction) { m_ColorCorrection = correction; return *this; } @@ -94,46 +120,23 @@ public: CRGB getTemperature() { return m_ColorTemperature; } CRGB getAdjustment(uint8_t scale) { - // if(1) return scale; - uint32_t r = 0; - uint32_t g = 0; - uint32_t b = 0; - - if(m_ColorCorrection.r > 0 && m_ColorTemperature.r > 0 && scale > 0) { - r = ((uint32_t)m_ColorCorrection.r+1) * ((uint32_t)m_ColorTemperature.r+1) * scale; - r /= 0x10000L; - } - if(m_ColorCorrection.g > 0 && m_ColorTemperature.g > 0 && scale > 0) { - g = ((uint32_t)m_ColorCorrection.g+1) * ((uint32_t)m_ColorTemperature.g+1) * scale; - g /= 0x10000L; + // if(1) return CRGB(scale,scale,scale); + CRGB adj(0,0,0); + + if(scale > 0) { + for(uint8_t i = 0; i < 3; i++) { + uint8_t cc = m_ColorCorrection.raw[i]; + uint8_t ct = m_ColorTemperature.raw[i]; + if(cc > 0 && ct > 0) { + uint32_t work = (((uint32_t)cc)+1) * (((uint32_t)ct)+1) * scale; + work /= 0x10000L; + adj.raw[i] = work & 0xFF; + } + } } - if(m_ColorCorrection.b > 0 && m_ColorTemperature.b > 0 && scale > 0) { - b = ((uint32_t)m_ColorCorrection.b+1) * ((uint32_t)m_ColorTemperature.b+1) * scale; - b /= 0x10000L; - } - - // static int done = 0; - // if(!done) { - // done = 1; - // Serial.print("Correction: "); - // Serial.print(m_ColorCorrection.r); Serial.print(" "); - // Serial.print(m_ColorCorrection.g); Serial.print(" "); - // Serial.print(m_ColorCorrection.b); Serial.println(" "); - // Serial.print("Temperature: "); - // Serial.print(m_ColorTemperature.r); Serial.print(" "); - // Serial.print(m_ColorTemperature.g); Serial.print(" "); - // Serial.print(m_ColorTemperature.b); Serial.println(" "); - // Serial.print("Scale: "); - // Serial.print(scale.r); Serial.print(" "); - // Serial.print(scale.g); Serial.print(" "); - // Serial.print(scale.b); Serial.println(" "); - // Serial.print("Combined: "); - // Serial.print(r); Serial.print(" "); Serial.print(g); Serial.print(" "); Serial.print(b); Serial.println(); - // } - return CRGB(r,g,b); + return adj; } - }; // Pixel controller class. This is the class that we use to centralize pixel access in a block of data, including @@ -141,12 +144,12 @@ public: // centralize 8/12/16 conversions here as well. template struct PixelController { + const uint8_t *mData; + int mLen; uint8_t d[3]; uint8_t e[3]; - const uint8_t *mData; CRGB mScale; uint8_t mAdvance; - int mLen; PixelController(const PixelController & other) { d[0] = other.d[0]; @@ -161,25 +164,31 @@ struct PixelController { mLen = other.mLen; } - PixelController(const CRGB *d, int len, CRGB & s, EDitherMode dither = BINARY_DITHER) : mData((const uint8_t*)d), mScale(s), mLen(len) { + PixelController(const uint8_t *d, int len, CRGB & s, EDitherMode dither = BINARY_DITHER, bool advance=true, uint8_t skip=0) : mData(d), mLen(len), mScale(s) { + enable_dithering(dither); + mData += skip; + mAdvance = (advance) ? 3+skip : 0; + } + + PixelController(const CRGB *d, int len, CRGB & s, EDitherMode dither = BINARY_DITHER) : mData((const uint8_t*)d), mLen(len), mScale(s) { enable_dithering(dither); mAdvance = 3; } - PixelController(const CRGB &d, int len, CRGB & s, EDitherMode dither = BINARY_DITHER) : mData((const uint8_t*)&d), mScale(s), mLen(len) { + PixelController(const CRGB &d, int len, CRGB & s, EDitherMode dither = BINARY_DITHER) : mData((const uint8_t*)&d), mLen(len), mScale(s) { enable_dithering(dither); mAdvance = 0; } #ifdef SUPPORT_ARGB - PixelController(const CARGB &d, int len, CRGB & s, EDitherMode dither = BINARY_DITHER) : mData((const uint8_t*)&d), mScale(s), mLen(len) { + PixelController(const CARGB &d, int len, CRGB & s, EDitherMode dither = BINARY_DITHER) : mData((const uint8_t*)&d), mLen(len), mScale(s) { enable_dithering(dither); // skip the A in CARGB mData += 1; mAdvance = 0; } - PixelController(const CARGB *d, int len, CRGB & s, EDitherMode dither = BINARY_DITHER) : mData((const uint8_t*)d), mScale(s), mLen(len) { + PixelController(const CARGB *d, int len, CRGB & s, EDitherMode dither = BINARY_DITHER) : mData((const uint8_t*)d), mLen(len), mScale(s) { enable_dithering(dither); // skip the A in CARGB mData += 1; diff --git a/delay.h b/delay.h index f9600ae8..0eeda245 100644 --- a/delay.h +++ b/delay.h @@ -1,6 +1,24 @@ #ifndef __INC_DELAY_H #define __INC_DELAY_H +// Class to ensure that a minimum amount of time has kicked since the last time run - and delay if not enough time has passed yet +// this should make sure that chipsets that have +template class CMinWait { + uint16_t mLastMicros; +public: + CMinWait() { mLastMicros = 0; } + + void wait() { + uint16_t diff; + do { + diff = (micros() & 0xFFFF) - mLastMicros; + } while(diff < WAIT); + } + + void mark() { mLastMicros = micros() & 0xFFFF; } +}; + + //////////////////////////////////////////////////////////////////////////////////////////// // // Clock cycle counted delay loop @@ -85,7 +103,7 @@ template<> __attribute__((always_inline)) inline void delaycycles<5>() {NOP2;NOP // #define NS(_NS) (_NS / (1000 / (F_CPU / 1000000L))) #if 1 || (F_CPU < 96000000) #define NS(_NS) ( (_NS * (F_CPU / 1000000L))) / 1000 -#define CLKS_TO_MICROS(_CLKS) ((long)(_CLKS)) / (F_CPU / 1000000L) +#define CLKS_TO_MICROS(_CLKS) ((_CLKS)) / (F_CPU / 1000000L) #else #define NS(_NS) ( (_NS * (F_CPU / 2000000L))) / 1000 #define CLKS_TO_MICROS(_CLKS) ((long)(_CLKS)) / (F_CPU / 2000000L) diff --git a/dmx.h b/dmx.h index 03329d0e..1556e515 100644 --- a/dmx.h +++ b/dmx.h @@ -11,9 +11,6 @@ public: // initialize the LED controller virtual void init() { DmxSimple.usePin(DATA_PIN); } - // reset any internal state to a clean point - virtual void reset() { init(); } - // clear out/zero out the given number of leds. virtual void clearLeds(int nLeds) { int count = min(nLeds * 3, DMX_SIZE); @@ -48,13 +45,6 @@ public: // as above, but every 4th uint8_t is assumed to be alpha channel data, and will be skipped virtual void show(const struct CARGB *data, int nLeds, uint8_t scale = 255) = 0; #endif - - // is the controller ready to write data out - virtual bool ready() { return true; } - - // wait until the controller is ready to write data out - virtual void wait() { return; } - }; #elif defined(FASTSPI_USE_DMX_SERIAL) @@ -64,9 +54,6 @@ public: // initialize the LED controller virtual void init() { DMXSerial.init(DMXController); } - // reset any internal state to a clean point - virtual void reset() { init(); } - // clear out/zero out the given number of leds. virtual void clearLeds(int nLeds) { int count = min(nLeds * 3, DMX_SIZE); @@ -101,13 +88,6 @@ public: // as above, but every 4th uint8_t is assumed to be alpha channel data, and will be skipped virtual void show(const struct CARGB *data, int nLeds, uint8_t scale = 255) = 0; #endif - - // is the controller ready to write data out - virtual bool ready() { return true; } - - // wait until the controller is ready to write data out - virtual void wait() { return; } - }; #endif diff --git a/examples/Cylon/Cylon.ino b/examples/Cylon/Cylon.ino index 443b84d6..dfb6ed78 100644 --- a/examples/Cylon/Cylon.ino +++ b/examples/Cylon/Cylon.ino @@ -6,7 +6,7 @@ // For led chips like Neopixels, which have a data line, ground, and power, you just // need to define DATA_PIN. For led chipsets that are SPI based (four wires - data, clock, // ground, and power), like the LPD8806, define both DATA_PIN and CLOCK_PIN -#define DATA_PIN 2 +#define DATA_PIN 6 #define CLOCK_PIN 13 // Define the array of leds @@ -26,7 +26,7 @@ void loop() { // now that we've shown the leds, reset the i'th led to black leds[i] = CRGB::Black; // Wait a little bit before we loop around and do it again - delay(300); + delay(30); } // Now go in the other direction. @@ -38,6 +38,6 @@ void loop() { // now that we've shown the leds, reset the i'th led to black leds[i] = CRGB::Black; // Wait a little bit before we loop around and do it again - delay(300); + delay(30); } } diff --git a/fastpin.h b/fastpin.h index 4455089a..3bf22338 100644 --- a/fastpin.h +++ b/fastpin.h @@ -5,23 +5,6 @@ #define NO_PIN 255 -// Class to ensure that a minimum amount of time has kicked since the last time run - and delay if not enough time has passed yet -// this should make sure that chipsets that have -template class CMinWait { - long mLastMicros; -public: - CMinWait() { mLastMicros = 0; } - - void wait() { - long diff = micros() - mLastMicros; - if(diff > 0 && diff < WAIT) { - delayMicroseconds(WAIT - diff); - } - } - - void mark() { mLastMicros = micros(); } -}; - ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // Pin access class - needs to tune for various platforms (naive fallback solution?) diff --git a/pixeltypes.h b/pixeltypes.h index 67689b12..663c37bd 100644 --- a/pixeltypes.h +++ b/pixeltypes.h @@ -560,7 +560,7 @@ struct CRGB { Yellow=0xFFFF00, YellowGreen=0x9ACD32 } HTMLColorCode; - static uint32_t Squant; + // static uint32_t Squant; }; -- cgit v1.2.3 From 7f6bbb947ed572af63c1bd1f8b6a431414610582 Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Sun, 16 Mar 2014 10:46:06 -0700 Subject: Tweaking NEOPIXEL examples --- examples/Blink/Blink.ino | 8 ++++---- examples/FirstLight/FirstLight.ino | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/examples/Blink/Blink.ino b/examples/Blink/Blink.ino index fb0d90d8..123eafb7 100644 --- a/examples/Blink/Blink.ino +++ b/examples/Blink/Blink.ino @@ -1,12 +1,12 @@ #include "FastLED.h" // How many leds in your strip? -#define NUM_LEDS 6 +#define NUM_LEDS 1 // For led chips like Neopixels, which have a data line, ground, and power, you just // need to define DATA_PIN. For led chipsets that are SPI based (four wires - data, clock, // ground, and power), like the LPD8806 define both DATA_PIN and CLOCK_PIN -#define DATA_PIN 3 +#define DATA_PIN 6 #define CLOCK_PIN 13 // Define the array of leds @@ -20,9 +20,9 @@ void setup() { // FastLED.addLeds(leds, NUM_LEDS); // FastLED.addLeds(leds, NUM_LEDS); // FastLED.addLeds(leds, NUM_LEDS); - // FastLED.addLeds(leds, NUM_LEDS); + FastLED.addLeds(leds, NUM_LEDS); // FastLED.addLeds(leds, NUM_LEDS); - FastLED.addLeds(leds, NUM_LEDS); + // FastLED.addLeds(leds, NUM_LEDS); // FastLED.addLeds(leds, NUM_LEDS); // FastLED.addLeds(leds, NUM_LEDS); diff --git a/examples/FirstLight/FirstLight.ino b/examples/FirstLight/FirstLight.ino index ebd58f13..e4b4dd7c 100644 --- a/examples/FirstLight/FirstLight.ino +++ b/examples/FirstLight/FirstLight.ino @@ -35,7 +35,7 @@ void setup() { // FastLED.addLeds(leds, NUM_LEDS); // FastLED.addLeds(leds, NUM_LEDS); // FastLED.addLeds(leds, NUM_LEDS); - // FastLED.addLeds(leds, NUM_LEDS); + // FastLED.addLeds(leds, NUM_LEDS); // FastLED.addLeds(leds, NUM_LEDS); // FastLED.addLeds(leds, NUM_LEDS); // FastLED.addLeds(leds, NUM_LEDS); -- cgit v1.2.3 From 3daf11b508da67a47c481623305f4e1194da257b Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Sun, 16 Mar 2014 10:46:48 -0700 Subject: Making blink trinket friendly out of the box --- examples/Blink/Blink.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/Blink/Blink.ino b/examples/Blink/Blink.ino index 123eafb7..ab307fda 100644 --- a/examples/Blink/Blink.ino +++ b/examples/Blink/Blink.ino @@ -6,7 +6,7 @@ // For led chips like Neopixels, which have a data line, ground, and power, you just // need to define DATA_PIN. For led chipsets that are SPI based (four wires - data, clock, // ground, and power), like the LPD8806 define both DATA_PIN and CLOCK_PIN -#define DATA_PIN 6 +#define DATA_PIN 3 #define CLOCK_PIN 13 // Define the array of leds -- cgit v1.2.3 From 1138f9611224ff6579e90264c0cf0e0d4feac3d5 Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Sun, 16 Mar 2014 13:28:09 -0700 Subject: still unused code for ATTiny version of scale8, to get rid of calls to mul. Add ability to modify FastLED.h to disable color correction and/or dithering (with program space savings) --- FastLED.h | 3 +++ clockless_trinket.h | 2 ++ controller.h | 7 ++++++- lib8tion.h | 28 ++++++++++++++++++++++++++-- 4 files changed, 37 insertions(+), 3 deletions(-) diff --git a/FastLED.h b/FastLED.h index 1fe8acdb..6f335a1e 100644 --- a/FastLED.h +++ b/FastLED.h @@ -1,6 +1,9 @@ #ifndef __INC_FASTSPI_LED2_H #define __INC_FASTSPI_LED2_H +// #define NO_CORRECTION 1 +// #define NO_DITHERING 1 + #include "controller.h" #include "fastpin.h" #include "fastspi.h" diff --git a/clockless_trinket.h b/clockless_trinket.h index 83cd2e84..7d99cbd9 100644 --- a/clockless_trinket.h +++ b/clockless_trinket.h @@ -95,8 +95,10 @@ public: showRGBInternal(pixels); // Adjust the timer +#if !defined(NO_CORRECTION) || (NO_CORRECTION == 0) uint16_t microsTaken = nLeds * CLKS_TO_MICROS(24 * (T1 + T2 + T3)); MS_COUNTER += (microsTaken >> 10); +#endif sei(); mWait.mark(); } diff --git a/controller.h b/controller.h index ee2e6d62..cc9cd88e 100644 --- a/controller.h +++ b/controller.h @@ -120,7 +120,9 @@ public: CRGB getTemperature() { return m_ColorTemperature; } CRGB getAdjustment(uint8_t scale) { - // if(1) return CRGB(scale,scale,scale); +#if defined(NO_CORRECTION) && (NO_CORRECTION==1) + return CRGB(scale,scale,scale); +#else CRGB adj(0,0,0); if(scale > 0) { @@ -136,6 +138,7 @@ public: } return adj; +#endif } }; @@ -197,6 +200,7 @@ struct PixelController { #endif void init_binary_dithering() { +#if !defined(NO_DITHERING) || (NO_DITHERING != 1) static byte R = 0; R++; @@ -218,6 +222,7 @@ struct PixelController { d[i] = scale8(Q, e[i]); if(e[i]) e[i]--; } +#endif } // Do we have n pixels left to process? diff --git a/lib8tion.h b/lib8tion.h index d197b5a1..a2e70fe4 100644 --- a/lib8tion.h +++ b/lib8tion.h @@ -430,8 +430,31 @@ LIB8STATIC uint8_t sub8( uint8_t i, uint8_t j) LIB8STATIC uint8_t scale8( uint8_t i, fract8 scale) { #if SCALE8_C == 1 - return ((int)i * (int)(scale) ) >> 8; + return + ((int)i * (int)(scale) ) >> 8; #elif SCALE8_AVRASM == 1 +#if defined(LIB8_ATTINY) + uint8_t work=0; + uint8_t cnt=0x80; + asm volatile( + "LOOP_%=: \n\t" + /*" sbrc %[scale], 0 \n\t" + " add %[work], %[i] \n\t" + " ror %[work] \n\t" + " lsr %[scale] \n\t" + " clc \n\t"*/ + " sbrc %[scale], 0 \n\t" + " add %[work], %[i] \n\t" + " ror %[work] \n\t" + " lsr %[scale] \n\t" + " lsr %[cnt] \n\t" + "brcc LOOP_%=" + : [work] "+r" (work), [cnt] "+r" (cnt) + : [scale] "r" (scale), [i] "r" (i) + : + ); + return work; +#else asm volatile( /* Multiply 8-bit i * 8-bit scale, giving 16-bit r1,r0 */ "mul %0, %1 \n\t" @@ -446,6 +469,7 @@ LIB8STATIC uint8_t scale8( uint8_t i, fract8 scale) /* Return the result */ return i; +#endif #else #error "No implementation for scale8 available." #endif @@ -459,7 +483,7 @@ LIB8STATIC uint8_t scale8( uint8_t i, fract8 scale) // several additional cycles. LIB8STATIC uint8_t scale8_video( uint8_t i, fract8 scale) { -#if SCALE8_C == 1 +#if SCALE8_C == 1 || defined(LIB8_ATTINY) uint8_t j = (((int)i * (int)scale) >> 8) + (i?1:0); // uint8_t nonzeroscale = (scale != 0) ? 1 : 0; // uint8_t j = (i == 0) ? 0 : (((int)i * (int)(scale) ) >> 8) + nonzeroscale; -- cgit v1.2.3 From ae4f4357bef65b1a9ee0e7ecf6a0b92742f5a172 Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Wed, 19 Mar 2014 16:12:44 -0700 Subject: PixelController wasn't limiting applying the dithering to non-0 pixels --- controller.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/controller.h b/controller.h index cc9cd88e..35c02d08 100644 --- a/controller.h +++ b/controller.h @@ -259,7 +259,7 @@ struct PixelController { } template __attribute__((always_inline)) inline static uint8_t loadByte(PixelController & pc) { return pc.mData[RO(SLOT)]; } - template __attribute__((always_inline)) inline static uint8_t dither(PixelController & pc, uint8_t b) { return qadd8(b, pc.d[RO(SLOT)]); } + template __attribute__((always_inline)) inline static uint8_t dither(PixelController & pc, uint8_t b) { return b ? qadd8(b, pc.d[RO(SLOT)]) : 0; } template __attribute__((always_inline)) inline static uint8_t scale(PixelController & pc, uint8_t b) { return scale8(b, pc.mScale.raw[RO(SLOT)]); } // composite shortcut functions for loading, dithering, and scaling -- cgit v1.2.3 From 3a13da215264b4c79991a2b3c8e692d2e4f4e024 Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Fri, 21 Mar 2014 10:21:01 -0700 Subject: Add global setDither/setTemp/setCorrection methods - this will propagate the cahnge to all the controllers. --- FastLED.cpp | 25 +++++++++++++++++++++++++ FastLED.h | 4 ++++ 2 files changed, 29 insertions(+) diff --git a/FastLED.cpp b/FastLED.cpp index 2b5d7698..30b31cf2 100644 --- a/FastLED.cpp +++ b/FastLED.cpp @@ -66,3 +66,28 @@ void CFastLED::delay(unsigned long ms) { unsigned long start = millis(); while((millis()-start) < ms) { show(); } } + +void CFastLED::setTemperature(const struct CRGB & temp) { + CLEDController *pCur = CLEDController::head(); + while(pCur) { + pCur->setTemperature(temp); + pCur = pCur->next(); + } +} + +void CFastLED::setCorrection(const struct CRGB & correction) { + CLEDController *pCur = CLEDController::head(); + while(pCur) { + pCur->setCorrection(correction); + pCur = pCur->next(); + } +} + +void CFastLED::setDither(uint8_t ditherMode) { + CLEDController *pCur = CLEDController::head(); + while(pCur) { + pCur->setDither(ditherMode); + pCur = pCur->next(); + } +} + diff --git a/FastLED.h b/FastLED.h index 6f335a1e..7ce487ca 100644 --- a/FastLED.h +++ b/FastLED.h @@ -180,6 +180,10 @@ public: void delay(unsigned long ms); + void setTemperature(const struct CRGB & temp); + void setCorrection(const struct CRGB & correction); + void setDither(uint8_t ditherMode = BINARY_DITHER); + }; extern CFastLED & FastSPI_LED; -- cgit v1.2.3 From 52d4f2562f3e5f92c9b6389cd8b9d45cd00d7acd Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Mon, 24 Mar 2014 15:49:00 -0700 Subject: Stop trying to include avr/io.h when we don't recognize the platform --- led_sysdefs.h | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/led_sysdefs.h b/led_sysdefs.h index afcf6e1b..47ee5076 100644 --- a/led_sysdefs.h +++ b/led_sysdefs.h @@ -1,7 +1,16 @@ #ifndef __INC_LED_SYSDEFS_H #define __INC_LED_SYSDEFS_H -#ifndef __SAM3X8E__ +#if defined(__MK20DX128__) || defined(__MK20DX256__) +#define FASTLED_TEENSY3 +#define FASTLED_ARM +#elif defined(__SAM3X8E__) +#define FASTLED_ARM +#else +#define FASTLED_AVR +#endif + +#if defined(FASTLED_AVR) || defined(FASTLED_TEENSY3) #include #include // for cli/se definitions @@ -18,14 +27,6 @@ typedef volatile uint8_t RwReg; /**< Read-Write 8-bit register (volatile u #endif -#if defined(__MK20DX128__) || defined(__MK20DX256__) -#define FASTLED_TEENSY3 -#define FASTLED_ARM -#elif defined(__SAM3X8E__) -#define FASTLED_ARM -#else -#define FASTLED_AVR -#endif // Arduino.h needed for convinience functions digitalPinToPort/BitMask/portOutputRegister and the pinMode methods. #include -- cgit v1.2.3 From 11b7c1860d1f18cf05b4a3c9c805d7592a0643bb Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Mon, 31 Mar 2014 18:07:53 -0700 Subject: Pulling over, manually, a pull request to pack down the pin class a couple bytes. --- fastpin.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fastpin.h b/fastpin.h index 3bf22338..56a9ea61 100644 --- a/fastpin.h +++ b/fastpin.h @@ -19,10 +19,10 @@ public: }; class Pin : public Selectable { - RwReg mPinMask; - uint8_t mPin; volatile RwReg *mPort; volatile RoReg *mInPort; + RwReg mPinMask; + uint8_t mPin; void _init() { mPinMask = digitalPinToBitMask(mPin); -- cgit v1.2.3 From 65367c7a2cb3246b579b52ea485e59eda9332c0e Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Mon, 31 Mar 2014 18:08:10 -0700 Subject: tweaking digix timing. --- clockless_arm_sam.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clockless_arm_sam.h b/clockless_arm_sam.h index 3d0f9264..c1a7c548 100644 --- a/clockless_arm_sam.h +++ b/clockless_arm_sam.h @@ -7,7 +7,7 @@ #if defined(__SAM3X8E__) -#define TADJUST 3 +#define TADJUST 4 #define TOTAL ( (T1+TADJUST) + (T2+TADJUST) + (T3+TADJUST) ) #define T1_MARK (TOTAL - (T1+TADJUST)) #define T2_MARK (T1_MARK - (T2+TADJUST)) -- cgit v1.2.3 From a6f4b492e6d263ead41c955843bdb86dd6fd7673 Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Tue, 1 Apr 2014 11:29:48 -0700 Subject: updating notes files --- dithertodo.txt | 20 ++++++++++---------- preview_changes.txt | 2 -- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/dithertodo.txt b/dithertodo.txt index 58240e96..db093189 100644 --- a/dithertodo.txt +++ b/dithertodo.txt @@ -1,18 +1,18 @@ SPI: -o due -o bitbang -o k20 -o avr +x due +x bitbang +x k20 +x avr o stm Clockless: X due -o k20 -o avr +x k20 +x avr o stm Chipsets: -o LPD8806 -o WS2801 -o P9813 -o SM1676 +x LPD8806 +x WS2801 +x P9813 +x SM1676 diff --git a/preview_changes.txt b/preview_changes.txt index 2866abbd..1b6060b5 100644 --- a/preview_changes.txt +++ b/preview_changes.txt @@ -4,7 +4,5 @@ * Teensy 3.1 support * Due support * P9813 (aka Cool Neon Total Control Lighting support) -* Preliminary 2-way ws2812 support -* Preliminary n-way clockless support on due * Preliminary TM1829 support (broken, don't use!) * Random code changes and cleanups -- cgit v1.2.3 From 447682fe1984363434e667dcdafb4c5f970d1b9f Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Wed, 2 Apr 2014 01:12:42 -0700 Subject: Fix teensy at 48Mhz operations. --- chipsets.h | 51 +++++++++++---------------------------------------- 1 file changed, 11 insertions(+), 40 deletions(-) diff --git a/chipsets.h b/chipsets.h index e23ee017..7f5d69ff 100644 --- a/chipsets.h +++ b/chipsets.h @@ -271,64 +271,35 @@ public: // We want to force all avr's to use the Trinket controller when running at 8Mhz, because even the 328's at 8Mhz // need the more tightly defined timeframes. -#if defined(FASTLED_AVR) && (F_CPU == 8000000) // 125ns/clock +#if (F_CPU == 8000000 || F_CPU == 16000000 || F_CPU == 24000000 || F_CPU == 48000000) // 125ns/clock +#define FMUL (F_CPU/8000000) // WS2811@8Mhz 2 clocks, 5 clocks, 3 clocks template -class WS2811Controller800Khz : public ClocklessController {}; +class WS2811Controller800Khz : public ClocklessController {}; template -class WS2811Controller400Khz : public ClocklessController {}; +class WS2811Controller400Khz : public ClocklessController {}; template -class UCS1903Controller400Khz : public ClocklessController {}; +class UCS1903Controller400Khz : public ClocklessController {}; template -class UCS1903BController800Khz : public ClocklessController {}; +class UCS1903BController800Khz : public ClocklessController {}; template -class TM1809Controller800Khz : public ClocklessController {}; +class TM1809Controller800Khz : public ClocklessController {}; template -class TM1803Controller400Khz : public ClocklessController {}; +class TM1803Controller400Khz : public ClocklessController {}; template -class TM1829Controller800Khz : public ClocklessController {}; +class TM1829Controller800Khz : public ClocklessController {}; template -class GW6205Controller400Khz : public ClocklessController {}; +class GW6205Controller400Khz : public ClocklessController {}; template -class GW6205Controller800Khz : public ClocklessController {}; - -#elif defined(FASTLED_AVR) && (F_CPU == 16000000) // 62.5ns/clock - -// WS2811@16Mhz 4 clocks, 10 clocks, 6 clocks -template -class WS2811Controller800Khz : public ClocklessController {}; - -template -class WS2811Controller400Khz : public ClocklessController {}; - -template -class UCS1903Controller400Khz : public ClocklessController {}; - -template -class UCS1903BController800Khz : public ClocklessController {}; - -template -class TM1809Controller800Khz : public ClocklessController {}; - -template -class TM1803Controller400Khz : public ClocklessController {}; - -template -class TM1829Controller800Khz : public ClocklessController {}; - -template -class GW6205Controller400Khz : public ClocklessController {}; - -template -class GW6205Controller800Khz : public ClocklessController {}; +class GW6205Controller800Khz : public ClocklessController {}; #else // GW6205@400khz - 800ns, 800ns, 800ns -- cgit v1.2.3 From 949ff41fd6c5272919db568661c926b9d6c2d4aa Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Wed, 2 Apr 2014 01:43:19 -0700 Subject: Some k20 cleanup --- chipsets.h | 2 +- clockless_arm_k20.h | 31 +++++++++++++++++++++---------- 2 files changed, 22 insertions(+), 11 deletions(-) diff --git a/chipsets.h b/chipsets.h index 7f5d69ff..e1396d72 100644 --- a/chipsets.h +++ b/chipsets.h @@ -271,7 +271,7 @@ public: // We want to force all avr's to use the Trinket controller when running at 8Mhz, because even the 328's at 8Mhz // need the more tightly defined timeframes. -#if (F_CPU == 8000000 || F_CPU == 16000000 || F_CPU == 24000000 || F_CPU == 48000000) // 125ns/clock +#if (F_CPU == 8000000 || F_CPU == 16000000 || F_CPU == 24000000 || F_CPU == 48000000 || F_CPU == 96000000) // 125ns/clock #define FMUL (F_CPU/8000000) // WS2811@8Mhz 2 clocks, 5 clocks, 3 clocks template diff --git a/clockless_arm_k20.h b/clockless_arm_k20.h index 59905d45..319dd471 100644 --- a/clockless_arm_k20.h +++ b/clockless_arm_k20.h @@ -66,8 +66,8 @@ public: } #endif - template __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; i > 0; i--) { + template __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, PixelController & pixels, 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::fastset(port, hi); @@ -76,6 +76,20 @@ public: while(ARM_DWT_CYCCNT < flip_mark); FastPin::fastset(port, lo); } + + while(ARM_DWT_CYCCNT < next_mark); + next_mark = ARM_DWT_CYCCNT + (T1+T2+T3); + FastPin::fastset(port, hi); + uint32_t flip_mark = next_mark - ((b&0x80) ? (T3) : (T2+T3)); + + // load the next byte in the gap where we would've bit shifted in the past + switch(PX) { + case 0: b = pixels.advanceAndLoadAndScale0(); break; + case 1: b = pixels.loadAndScale1(); break; + case 2: b = pixels.loadAndScale2(); break; + } + while(ARM_DWT_CYCCNT < flip_mark); + FastPin::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 @@ -89,7 +103,7 @@ public: // Setup the pixel controller and load/scale the first byte pixels.preStepFirstByteDithering(); register uint8_t b = pixels.loadAndScale0(); - + // Get access to the clock ARM_DEMCR |= ARM_DEMCR_TRCENA; ARM_DWT_CTRL |= ARM_DWT_CTRL_CYCCNTENA; @@ -100,16 +114,13 @@ public: pixels.stepDithering(); // Write first byte, read next byte - writeBits<8+XTRA0>(next_mark, port, hi, lo, b); - b = pixels.loadAndScale1(); + writeBits<8+XTRA0,1>(next_mark, port, hi, lo, pixels, b); // Write second byte, read 3rd byte - writeBits<8+XTRA0>(next_mark, port, hi, lo, b); - b = pixels.loadAndScale2(); + writeBits<8+XTRA0,2>(next_mark, port, hi, lo, pixels, b); - // Write third byte - writeBits<8+XTRA0>(next_mark, port, hi, lo, b); - b = pixels.advanceAndLoadAndScale0(); + // Write third byte, read 1st byte of next pixel + writeBits<8+XTRA0,0>(next_mark, port, hi, lo, pixels, b); }; } }; -- cgit v1.2.3 From 276926272da6be767b3fe5189ab59c657f9ca026 Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Wed, 2 Apr 2014 02:03:59 -0700 Subject: Fix teensy @24Mhz for WS2812. --- clockless_arm_k20.h | 35 ++++++++++++++++++++--------------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/clockless_arm_k20.h b/clockless_arm_k20.h index 319dd471..003e470f 100644 --- a/clockless_arm_k20.h +++ b/clockless_arm_k20.h @@ -66,30 +66,32 @@ public: } #endif - template __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, PixelController & pixels, register uint8_t & b) { + template __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::fastset(port, hi); - uint32_t flip_mark = next_mark - ((b&0x80) ? (T3) : (T2+T3)); + if(b&0x80) { + while((next_mark - ARM_DWT_CYCCNT) > T3); + FastPin::fastset(port, lo); + } else { + while((next_mark - ARM_DWT_CYCCNT) > (T2+T3+1)); + FastPin::fastset(port, lo); + } b <<= 1; - while(ARM_DWT_CYCCNT < flip_mark); - FastPin::fastset(port, lo); } while(ARM_DWT_CYCCNT < next_mark); next_mark = ARM_DWT_CYCCNT + (T1+T2+T3); FastPin::fastset(port, hi); - uint32_t flip_mark = next_mark - ((b&0x80) ? (T3) : (T2+T3)); - // load the next byte in the gap where we would've bit shifted in the past - switch(PX) { - case 0: b = pixels.advanceAndLoadAndScale0(); break; - case 1: b = pixels.loadAndScale1(); break; - case 2: b = pixels.loadAndScale2(); break; + if(b&0x80) { + while((next_mark - ARM_DWT_CYCCNT) > T3); + FastPin::fastset(port, lo); + } else { + while((next_mark - ARM_DWT_CYCCNT) > (T2+T3+1)); + FastPin::fastset(port, lo); } - while(ARM_DWT_CYCCNT < flip_mark); - FastPin::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 @@ -114,13 +116,16 @@ public: pixels.stepDithering(); // Write first byte, read next byte - writeBits<8+XTRA0,1>(next_mark, port, hi, lo, pixels, b); + writeBits<8+XTRA0>(next_mark, port, hi, lo, b); + b = pixels.loadAndScale1(); // Write second byte, read 3rd byte - writeBits<8+XTRA0,2>(next_mark, port, hi, lo, pixels, b); + writeBits<8+XTRA0>(next_mark, port, hi, lo, b); + b = pixels.loadAndScale2(); // Write third byte, read 1st byte of next pixel - writeBits<8+XTRA0,0>(next_mark, port, hi, lo, pixels, b); + writeBits<8+XTRA0>(next_mark, port, hi, lo, b); + b = pixels.advanceAndLoadAndScale0(); }; } }; -- cgit v1.2.3 From bf4cb9e7b3e5c31e4797a1d1ecf2401caa66c375 Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Wed, 2 Apr 2014 02:17:22 -0700 Subject: Fix issue #47 - adjust when we setup the pixels controller to minimize the amount of overhead timing 'noise' introduced by initializing dithering. --- clockless_arm_k20.h | 19 ++++++++++++------- clockless_arm_sam.h | 13 ++++++++----- clockless_trinket.h | 3 ++- 3 files changed, 22 insertions(+), 13 deletions(-) diff --git a/clockless_arm_k20.h b/clockless_arm_k20.h index 003e470f..4abf0e9a 100644 --- a/clockless_arm_k20.h +++ b/clockless_arm_k20.h @@ -25,26 +25,30 @@ public: // set all the leds on the controller to a given color virtual void showColor(const struct CRGB & rgbdata, int nLeds, CRGB scale) { + PixelController pixels(rgbdata, nLeds, scale, getDither()); + mWait.wait(); cli(); - showRGBInternal(PixelController(rgbdata, nLeds, scale, getDither())); + showRGBInternal(pixels); // Adjust the timer - long microsTaken = nLeds * CLKS_TO_MICROS(24 * (T1 + T2 + T3)); + long microsTaken = nLeds * CLKS_TO_MICROS(24 * (T1 + T2 + T3 + 1)); MS_COUNTER += (microsTaken / 1000); sei(); mWait.mark(); } virtual void show(const struct CRGB *rgbdata, int nLeds, CRGB scale) { + PixelController pixels(rgbdata, nLeds, scale, getDither()); + mWait.wait(); cli(); - showRGBInternal(PixelController(rgbdata, nLeds, scale, getDither())); + showRGBInternal(pixels); // Adjust the timer - long microsTaken = nLeds * CLKS_TO_MICROS(24 * (T1 + T2 + T3)); + long microsTaken = nLeds * CLKS_TO_MICROS(24 * (T1 + T2 + T3 + 1)); MS_COUNTER += (microsTaken / 1000); sei(); mWait.mark(); @@ -52,14 +56,15 @@ public: #ifdef SUPPORT_ARGB virtual void show(const struct CARGB *rgbdata, int nLeds, CRGB scale) { + PixelController pixels(rgbdata, nLeds, scale, getDither()); mWait.wait(); cli(); - showRGBInternal(PixelController(rgbdata, nLeds, scale, getDither())); + showRGBInternal(pixels); // Adjust the timer - long microsTaken = nLeds * CLKS_TO_MICROS(24 * (T1 + T2 + T3)); + long microsTaken = nLeds * CLKS_TO_MICROS(24 * (T1 + T2 + T3 + 1)); MS_COUNTER += (microsTaken / 1000); sei(); mWait.mark(); @@ -96,7 +101,7 @@ public: // 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 showRGBInternal(PixelController pixels) { + static void showRGBInternal(PixelController & pixels) { register data_ptr_t port = FastPin::port(); register data_t hi = *port | FastPin::mask();; register data_t lo = *port & ~FastPin::mask();; diff --git a/clockless_arm_sam.h b/clockless_arm_sam.h index c1a7c548..fb0be86f 100644 --- a/clockless_arm_sam.h +++ b/clockless_arm_sam.h @@ -35,12 +35,13 @@ public: } // set all the leds on the controller to a given color - virtual void showColor(const struct CRGB & data, int nLeds, CRGB scale) { + virtual void showColor(const struct CRGB & rgbdata, int nLeds, CRGB scale) { + PixelController pixels(rgbdata, nLeds, scale, getDither()); mWait.wait(); cli(); SysClockSaver savedClock(TOTAL); - showRGBInternal(PixelController(data, nLeds, scale, getDither())); + showRGBInternal(pixels); // Adjust the timer long microsTaken = nLeds * CLKS_TO_MICROS(24 * (TOTAL)); @@ -52,6 +53,7 @@ public: } virtual void show(const struct CRGB *rgbdata, int nLeds, CRGB scale) { + PixelController pixels(rgbdata, nLeds, scale, getDither()); mWait.wait(); cli(); SysClockSaver savedClock(TOTAL); @@ -61,7 +63,7 @@ public: // Serial.print(scale.raw[1]); Serial.print(" "); // Serial.print(scale.raw[2]); Serial.println(" "); // FastPinBB::hi(); delay(1); FastPinBB::lo(); - showRGBInternal(PixelController(rgbdata, nLeds, scale, getDither())); + showRGBInternal(pixels); // Adjust the timer long microsTaken = nLeds * CLKS_TO_MICROS(24 * (TOTAL)); @@ -74,11 +76,12 @@ public: #ifdef SUPPORT_ARGB virtual void show(const struct CARGB *rgbdata, int nLeds, CRGB scale) { + PixelController pixels(rgbdata, nLeds, scale, getDither()); mWait.wait(); cli(); SysClockSaver savedClock(TOTAL); - showRGBInternal(PixelController(rgbdata, nLeds, scale, getDither())); + showRGBInternal(pixels); // Adjust the timer long microsTaken = nLeds * CLKS_TO_MICROS(24 * (TOTAL)); @@ -208,7 +211,7 @@ public: #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 void showRGBInternal(PixelController pixels) { + static void showRGBInternal(PixelController & pixels) { // Serial.print("Going to show "); Serial.print(pixels.mLen); Serial.println(" pixels."); register data_ptr_t port asm("r7") = FastPinBB::port(); FORCE_REFERENCE(port); diff --git a/clockless_trinket.h b/clockless_trinket.h index 7d99cbd9..50e49d85 100644 --- a/clockless_trinket.h +++ b/clockless_trinket.h @@ -88,10 +88,11 @@ public: #endif void showAdjTime(const uint8_t *data, int nLeds, CRGB & scale, bool advance, int skip) { + PixelController pixels(data, nLeds, scale, getDither(), advance, skip); + mWait.wait(); cli(); - PixelController pixels(data, nLeds, scale, getDither(), advance, skip); showRGBInternal(pixels); // Adjust the timer -- cgit v1.2.3 From c8701872a14a7a84682dafc4e95bef2a25bc82ed Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Wed, 2 Apr 2014 18:39:25 -0700 Subject: Make sure writePixels doesn't get inlined aggressively, there's really no good savings/reason for it to get inlined. --- fastspi_bitbang.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fastspi_bitbang.h b/fastspi_bitbang.h index fa50e470..24d2e41e 100644 --- a/fastspi_bitbang.h +++ b/fastspi_bitbang.h @@ -286,7 +286,7 @@ public: // 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 of each grouping, as well as a class specifying a per // byte of data modification to be made. (See DATA_NOP above) - template void writePixels(PixelController pixels) { + template __attribute__((noinline)) void writePixels(PixelController pixels) { select(); int len = pixels.mLen; -- cgit v1.2.3 From 8e08005dce4a34fc00dfa07aa26c688f991211b5 Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Wed, 2 Apr 2014 20:10:41 -0700 Subject: blah --- FastLED/FastLED.xcodeproj/project.pbxproj | 514 ++++++++++ .../project.xcworkspace/contents.xcworkspacedata | 7 + .../UserInterfaceState.xcuserstate | Bin 0 -> 4192 bytes .../dgarcia.xcuserdatad/xcschemes/All.xcscheme | 59 ++ .../dgarcia.xcuserdatad/xcschemes/Build.xcscheme | 59 ++ .../dgarcia.xcuserdatad/xcschemes/Index.xcscheme | 86 ++ .../dgarcia.xcuserdatad/xcschemes/Serial.xcscheme | 59 ++ .../dgarcia.xcuserdatad/xcschemes/Upload.xcscheme | 59 ++ .../xcschemes/xcschememanagement.plist | 62 ++ FastLED/FastLED/About/About.txt | 15 + .../FastLED/Configurations/Arduino Due.xcconfig | 45 + .../Configurations/Arduino Duemilanove.xcconfig | 46 + .../Configurations/Arduino Leonardo.xcconfig | 41 + .../Configurations/Arduino Mega 2560.xcconfig | 46 + .../Arduino Mini with ATmega328-3.3V.xcconfig | 45 + .../Arduino Mini with ATmega328-5V.xcconfig | 46 + .../Configurations/Arduino Robot Control.xcconfig | 40 + .../Configurations/Arduino Robot Motor.xcconfig | 40 + .../FastLED/Configurations/Arduino Uno.xcconfig | 40 + .../FastLED/Configurations/Arduino Yun.xcconfig | 40 + .../FastLED/Configurations/DFRobot BLuno.xcconfig | 40 + .../Configurations/Digispark Tiny Core.xcconfig | 44 + .../Experimeter Board with MSP430FR5739.xcconfig | 40 + .../LaunchPad Stellaris with LM4F120.xcconfig | 40 + .../LaunchPad Tiva C with TM4C123.xcconfig | 44 + .../LaunchPad with MSP430F5529.xcconfig | 39 + .../LaunchPad with MSP430G2231.xcconfig | 40 + .../LaunchPad with MSP430G2452.xcconfig | 40 + .../LaunchPad with MSP430G2553.xcconfig | 40 + .../Maple Flash revision 3+.xcconfig | 39 + .../Microduino Core with ATmega328-5V.xcconfig | 39 + .../Microduino Core+ with ATmega644-5V.xcconfig | 39 + .../FastLED/Configurations/Sparkfun Uno.xcconfig | 45 + FastLED/FastLED/Configurations/Teensy 2.0.xcconfig | 39 + FastLED/FastLED/Configurations/Teensy 3.0.xcconfig | 39 + FastLED/FastLED/Configurations/Teensy 3.1.xcconfig | 39 + FastLED/FastLED/Configurations/Wiring S.xcconfig | 40 + .../FastLED/Configurations/chipKIT Max32.xcconfig | 40 + .../FastLED/Configurations/chipKIT Uno32.xcconfig | 40 + .../FastLED/Configurations/chipKIT uC32.xcconfig | 45 + FastLED/FastLED/FastLED.ino | 91 ++ FastLED/FastLED/LocalLibrary.cpp | 29 + FastLED/FastLED/LocalLibrary.h | 55 ++ FastLED/FastLED/Makefile | 80 ++ FastLED/FastLED/Makefiles/Arduino.mk | 24 + FastLED/FastLED/Makefiles/Arduino1.mk | 91 ++ FastLED/FastLED/Makefiles/Arduino15avr.mk | 199 ++++ FastLED/FastLED/Makefiles/Arduino15sam.mk | 157 +++ FastLED/FastLED/Makefiles/Arduino23.mk | 69 ++ FastLED/FastLED/Makefiles/Avrdude.mk | 93 ++ FastLED/FastLED/Makefiles/Digispark.mk | 132 +++ FastLED/FastLED/Makefiles/Energia430.mk | 84 ++ FastLED/FastLED/Makefiles/EnergiaLM4F.mk | 102 ++ FastLED/FastLED/Makefiles/MapleIDE.mk | 108 +++ FastLED/FastLED/Makefiles/Microduino.mk | 93 ++ FastLED/FastLED/Makefiles/Mpide.mk | 77 ++ FastLED/FastLED/Makefiles/Step1.mk | 229 +++++ FastLED/FastLED/Makefiles/Step2.mk | 1021 ++++++++++++++++++++ FastLED/FastLED/Makefiles/Teensy.mk | 57 ++ FastLED/FastLED/Makefiles/Teensy2.mk | 99 ++ FastLED/FastLED/Makefiles/Teensy3.mk | 96 ++ FastLED/FastLED/Makefiles/Wiring.mk | 123 +++ FastLED/FastLED/ReadMe.txt | 26 + FastLED/FastLED/Sketchbook/Sketchbook.txt | 9 + FastLED/FastLED/Utilities/TemplateIcon.icns | Bin 0 -> 82737 bytes FastLED/FastLED/Utilities/embedXcode_check | Bin 0 -> 113608 bytes FastLED/FastLED/Utilities/embedXcode_chrono | Bin 0 -> 40868 bytes FastLED/FastLED/Utilities/embedXcode_prepare | Bin 0 -> 115748 bytes FastLED/FastLED/Utilities/reset.py | 124 +++ FastLED/FastLED/Utilities/serial1200.py | 13 + FastLED/FastLED/main.cpp | 475 +++++++++ 71 files changed, 5916 insertions(+) create mode 100644 FastLED/FastLED.xcodeproj/project.pbxproj create mode 100644 FastLED/FastLED.xcodeproj/project.xcworkspace/contents.xcworkspacedata create mode 100644 FastLED/FastLED.xcodeproj/project.xcworkspace/xcuserdata/dgarcia.xcuserdatad/UserInterfaceState.xcuserstate create mode 100644 FastLED/FastLED.xcodeproj/xcuserdata/dgarcia.xcuserdatad/xcschemes/All.xcscheme create mode 100644 FastLED/FastLED.xcodeproj/xcuserdata/dgarcia.xcuserdatad/xcschemes/Build.xcscheme create mode 100644 FastLED/FastLED.xcodeproj/xcuserdata/dgarcia.xcuserdatad/xcschemes/Index.xcscheme create mode 100644 FastLED/FastLED.xcodeproj/xcuserdata/dgarcia.xcuserdatad/xcschemes/Serial.xcscheme create mode 100644 FastLED/FastLED.xcodeproj/xcuserdata/dgarcia.xcuserdatad/xcschemes/Upload.xcscheme create mode 100644 FastLED/FastLED.xcodeproj/xcuserdata/dgarcia.xcuserdatad/xcschemes/xcschememanagement.plist create mode 100644 FastLED/FastLED/About/About.txt create mode 100755 FastLED/FastLED/Configurations/Arduino Due.xcconfig create mode 100644 FastLED/FastLED/Configurations/Arduino Duemilanove.xcconfig create mode 100755 FastLED/FastLED/Configurations/Arduino Leonardo.xcconfig create mode 100755 FastLED/FastLED/Configurations/Arduino Mega 2560.xcconfig create mode 100644 FastLED/FastLED/Configurations/Arduino Mini with ATmega328-3.3V.xcconfig create mode 100755 FastLED/FastLED/Configurations/Arduino Mini with ATmega328-5V.xcconfig create mode 100644 FastLED/FastLED/Configurations/Arduino Robot Control.xcconfig create mode 100644 FastLED/FastLED/Configurations/Arduino Robot Motor.xcconfig create mode 100755 FastLED/FastLED/Configurations/Arduino Uno.xcconfig create mode 100755 FastLED/FastLED/Configurations/Arduino Yun.xcconfig create mode 100755 FastLED/FastLED/Configurations/DFRobot BLuno.xcconfig create mode 100644 FastLED/FastLED/Configurations/Digispark Tiny Core.xcconfig create mode 100755 FastLED/FastLED/Configurations/Experimeter Board with MSP430FR5739.xcconfig create mode 100755 FastLED/FastLED/Configurations/LaunchPad Stellaris with LM4F120.xcconfig create mode 100644 FastLED/FastLED/Configurations/LaunchPad Tiva C with TM4C123.xcconfig create mode 100644 FastLED/FastLED/Configurations/LaunchPad with MSP430F5529.xcconfig create mode 100755 FastLED/FastLED/Configurations/LaunchPad with MSP430G2231.xcconfig create mode 100755 FastLED/FastLED/Configurations/LaunchPad with MSP430G2452.xcconfig create mode 100755 FastLED/FastLED/Configurations/LaunchPad with MSP430G2553.xcconfig create mode 100755 FastLED/FastLED/Configurations/Maple Flash revision 3+.xcconfig create mode 100644 FastLED/FastLED/Configurations/Microduino Core with ATmega328-5V.xcconfig create mode 100644 FastLED/FastLED/Configurations/Microduino Core+ with ATmega644-5V.xcconfig create mode 100755 FastLED/FastLED/Configurations/Sparkfun Uno.xcconfig create mode 100755 FastLED/FastLED/Configurations/Teensy 2.0.xcconfig create mode 100755 FastLED/FastLED/Configurations/Teensy 3.0.xcconfig create mode 100755 FastLED/FastLED/Configurations/Teensy 3.1.xcconfig create mode 100755 FastLED/FastLED/Configurations/Wiring S.xcconfig create mode 100644 FastLED/FastLED/Configurations/chipKIT Max32.xcconfig create mode 100755 FastLED/FastLED/Configurations/chipKIT Uno32.xcconfig create mode 100644 FastLED/FastLED/Configurations/chipKIT uC32.xcconfig create mode 100644 FastLED/FastLED/FastLED.ino create mode 100644 FastLED/FastLED/LocalLibrary.cpp create mode 100644 FastLED/FastLED/LocalLibrary.h create mode 100644 FastLED/FastLED/Makefile create mode 100755 FastLED/FastLED/Makefiles/Arduino.mk create mode 100755 FastLED/FastLED/Makefiles/Arduino1.mk create mode 100755 FastLED/FastLED/Makefiles/Arduino15avr.mk create mode 100755 FastLED/FastLED/Makefiles/Arduino15sam.mk create mode 100755 FastLED/FastLED/Makefiles/Arduino23.mk create mode 100755 FastLED/FastLED/Makefiles/Avrdude.mk create mode 100755 FastLED/FastLED/Makefiles/Digispark.mk create mode 100755 FastLED/FastLED/Makefiles/Energia430.mk create mode 100755 FastLED/FastLED/Makefiles/EnergiaLM4F.mk create mode 100755 FastLED/FastLED/Makefiles/MapleIDE.mk create mode 100755 FastLED/FastLED/Makefiles/Microduino.mk create mode 100755 FastLED/FastLED/Makefiles/Mpide.mk create mode 100755 FastLED/FastLED/Makefiles/Step1.mk create mode 100755 FastLED/FastLED/Makefiles/Step2.mk create mode 100755 FastLED/FastLED/Makefiles/Teensy.mk create mode 100755 FastLED/FastLED/Makefiles/Teensy2.mk create mode 100755 FastLED/FastLED/Makefiles/Teensy3.mk create mode 100755 FastLED/FastLED/Makefiles/Wiring.mk create mode 100644 FastLED/FastLED/ReadMe.txt create mode 100644 FastLED/FastLED/Sketchbook/Sketchbook.txt create mode 100644 FastLED/FastLED/Utilities/TemplateIcon.icns create mode 100755 FastLED/FastLED/Utilities/embedXcode_check create mode 100755 FastLED/FastLED/Utilities/embedXcode_chrono create mode 100755 FastLED/FastLED/Utilities/embedXcode_prepare create mode 100755 FastLED/FastLED/Utilities/reset.py create mode 100755 FastLED/FastLED/Utilities/serial1200.py create mode 100644 FastLED/FastLED/main.cpp diff --git a/FastLED/FastLED.xcodeproj/project.pbxproj b/FastLED/FastLED.xcodeproj/project.pbxproj new file mode 100644 index 00000000..76200e69 --- /dev/null +++ b/FastLED/FastLED.xcodeproj/project.pbxproj @@ -0,0 +1,514 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 7BA555FA18ED087600E45020 /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7BA555F918ED087600E45020 /* main.cpp */; }; + 7BA555FC18ED087600E45020 /* LocalLibrary.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7BA555FB18ED087600E45020 /* LocalLibrary.cpp */; }; + 7BA555FF18ED087600E45020 /* Makefile in Sources */ = {isa = PBXBuildFile; fileRef = 7BA555FE18ED087600E45020 /* Makefile */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 7BA555F618ED087600E45020 /* Index */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = Index; sourceTree = BUILT_PRODUCTS_DIR; }; + 7BA555F918ED087600E45020 /* main.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = ""; }; + 7BA555FB18ED087600E45020 /* LocalLibrary.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = LocalLibrary.cpp; sourceTree = ""; }; + 7BA555FD18ED087600E45020 /* LocalLibrary.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LocalLibrary.h; sourceTree = ""; }; + 7BA555FE18ED087600E45020 /* Makefile */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.make; path = Makefile; sourceTree = ""; }; + 7BA5560118ED087600E45020 /* Sketchbook.txt */ = {isa = PBXFileReference; lastKnownFileType = text; name = Sketchbook.txt; path = Sketchbook/Sketchbook.txt; sourceTree = ""; }; + 7BA5560318ED087600E45020 /* Arduino Due.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "Arduino Due.xcconfig"; path = "Configurations/Arduino Due.xcconfig"; sourceTree = ""; }; + 7BA5560418ED087600E45020 /* Arduino Duemilanove.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "Arduino Duemilanove.xcconfig"; path = "Configurations/Arduino Duemilanove.xcconfig"; sourceTree = ""; }; + 7BA5560518ED087600E45020 /* Arduino Leonardo.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "Arduino Leonardo.xcconfig"; path = "Configurations/Arduino Leonardo.xcconfig"; sourceTree = ""; }; + 7BA5560618ED087600E45020 /* Arduino Mega 2560.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "Arduino Mega 2560.xcconfig"; path = "Configurations/Arduino Mega 2560.xcconfig"; sourceTree = ""; }; + 7BA5560718ED087600E45020 /* Arduino Mini with ATmega328-3.3V.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "Arduino Mini with ATmega328-3.3V.xcconfig"; path = "Configurations/Arduino Mini with ATmega328-3.3V.xcconfig"; sourceTree = ""; }; + 7BA5560818ED087600E45020 /* Arduino Mini with ATmega328-5V.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "Arduino Mini with ATmega328-5V.xcconfig"; path = "Configurations/Arduino Mini with ATmega328-5V.xcconfig"; sourceTree = ""; }; + 7BA5560918ED087600E45020 /* Arduino Robot Control.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "Arduino Robot Control.xcconfig"; path = "Configurations/Arduino Robot Control.xcconfig"; sourceTree = ""; }; + 7BA5560A18ED087600E45020 /* Arduino Robot Motor.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "Arduino Robot Motor.xcconfig"; path = "Configurations/Arduino Robot Motor.xcconfig"; sourceTree = ""; }; + 7BA5560B18ED087600E45020 /* Arduino Uno.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "Arduino Uno.xcconfig"; path = "Configurations/Arduino Uno.xcconfig"; sourceTree = ""; }; + 7BA5560C18ED087600E45020 /* Arduino Yun.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "Arduino Yun.xcconfig"; path = "Configurations/Arduino Yun.xcconfig"; sourceTree = ""; }; + 7BA5560D18ED087600E45020 /* chipKIT Uno32.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "chipKIT Uno32.xcconfig"; path = "Configurations/chipKIT Uno32.xcconfig"; sourceTree = ""; }; + 7BA5560E18ED087600E45020 /* chipKIT Max32.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "chipKIT Max32.xcconfig"; path = "Configurations/chipKIT Max32.xcconfig"; sourceTree = ""; }; + 7BA5560F18ED087600E45020 /* chipKIT uC32.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "chipKIT uC32.xcconfig"; path = "Configurations/chipKIT uC32.xcconfig"; sourceTree = ""; }; + 7BA5561018ED087600E45020 /* DFRobot BLuno.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "DFRobot BLuno.xcconfig"; path = "Configurations/DFRobot BLuno.xcconfig"; sourceTree = ""; }; + 7BA5561118ED087600E45020 /* Digispark Tiny Core.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "Digispark Tiny Core.xcconfig"; path = "Configurations/Digispark Tiny Core.xcconfig"; sourceTree = ""; }; + 7BA5561218ED087600E45020 /* Experimeter Board with MSP430FR5739.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "Experimeter Board with MSP430FR5739.xcconfig"; path = "Configurations/Experimeter Board with MSP430FR5739.xcconfig"; sourceTree = ""; }; + 7BA5561318ED087600E45020 /* LaunchPad Stellaris with LM4F120.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "LaunchPad Stellaris with LM4F120.xcconfig"; path = "Configurations/LaunchPad Stellaris with LM4F120.xcconfig"; sourceTree = ""; }; + 7BA5561418ED087600E45020 /* LaunchPad Tiva C with TM4C123.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "LaunchPad Tiva C with TM4C123.xcconfig"; path = "Configurations/LaunchPad Tiva C with TM4C123.xcconfig"; sourceTree = ""; }; + 7BA5561518ED087600E45020 /* LaunchPad with MSP430G2553.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "LaunchPad with MSP430G2553.xcconfig"; path = "Configurations/LaunchPad with MSP430G2553.xcconfig"; sourceTree = ""; }; + 7BA5561618ED087600E45020 /* LaunchPad with MSP430G2231.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "LaunchPad with MSP430G2231.xcconfig"; path = "Configurations/LaunchPad with MSP430G2231.xcconfig"; sourceTree = ""; }; + 7BA5561718ED087600E45020 /* LaunchPad with MSP430G2452.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "LaunchPad with MSP430G2452.xcconfig"; path = "Configurations/LaunchPad with MSP430G2452.xcconfig"; sourceTree = ""; }; + 7BA5561818ED087600E45020 /* LaunchPad with MSP430F5529.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "LaunchPad with MSP430F5529.xcconfig"; path = "Configurations/LaunchPad with MSP430F5529.xcconfig"; sourceTree = ""; }; + 7BA5561918ED087600E45020 /* Maple Flash revision 3+.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "Maple Flash revision 3+.xcconfig"; path = "Configurations/Maple Flash revision 3+.xcconfig"; sourceTree = ""; }; + 7BA5561A18ED087600E45020 /* Microduino Core with ATmega328-5V.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "Microduino Core with ATmega328-5V.xcconfig"; path = "Configurations/Microduino Core with ATmega328-5V.xcconfig"; sourceTree = ""; }; + 7BA5561B18ED087600E45020 /* Microduino Core+ with ATmega644-5V.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "Microduino Core+ with ATmega644-5V.xcconfig"; path = "Configurations/Microduino Core+ with ATmega644-5V.xcconfig"; sourceTree = ""; }; + 7BA5561C18ED087600E45020 /* Sparkfun Uno.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "Sparkfun Uno.xcconfig"; path = "Configurations/Sparkfun Uno.xcconfig"; sourceTree = ""; }; + 7BA5561D18ED087600E45020 /* Teensy 2.0.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "Teensy 2.0.xcconfig"; path = "Configurations/Teensy 2.0.xcconfig"; sourceTree = ""; }; + 7BA5561E18ED087600E45020 /* Teensy 3.0.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "Teensy 3.0.xcconfig"; path = "Configurations/Teensy 3.0.xcconfig"; sourceTree = ""; }; + 7BA5561F18ED087600E45020 /* Teensy 3.1.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "Teensy 3.1.xcconfig"; path = "Configurations/Teensy 3.1.xcconfig"; sourceTree = ""; }; + 7BA5562018ED087600E45020 /* Wiring S.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "Wiring S.xcconfig"; path = "Configurations/Wiring S.xcconfig"; sourceTree = ""; }; + 7BA5562218ED087600E45020 /* Arduino.mk */ = {isa = PBXFileReference; lastKnownFileType = text; name = Arduino.mk; path = Makefiles/Arduino.mk; sourceTree = ""; }; + 7BA5562318ED087600E45020 /* Arduino1.mk */ = {isa = PBXFileReference; lastKnownFileType = text; name = Arduino1.mk; path = Makefiles/Arduino1.mk; sourceTree = ""; }; + 7BA5562418ED087600E45020 /* Arduino15avr.mk */ = {isa = PBXFileReference; lastKnownFileType = text; name = Arduino15avr.mk; path = Makefiles/Arduino15avr.mk; sourceTree = ""; }; + 7BA5562518ED087600E45020 /* Arduino15sam.mk */ = {isa = PBXFileReference; lastKnownFileType = text; name = Arduino15sam.mk; path = Makefiles/Arduino15sam.mk; sourceTree = ""; }; + 7BA5562618ED087600E45020 /* Arduino23.mk */ = {isa = PBXFileReference; lastKnownFileType = text; name = Arduino23.mk; path = Makefiles/Arduino23.mk; sourceTree = ""; }; + 7BA5562718ED087600E45020 /* Digispark.mk */ = {isa = PBXFileReference; lastKnownFileType = text; name = Digispark.mk; path = Makefiles/Digispark.mk; sourceTree = ""; }; + 7BA5562818ED087600E45020 /* Energia430.mk */ = {isa = PBXFileReference; lastKnownFileType = text; name = Energia430.mk; path = Makefiles/Energia430.mk; sourceTree = ""; }; + 7BA5562918ED087600E45020 /* EnergiaLM4F.mk */ = {isa = PBXFileReference; lastKnownFileType = text; name = EnergiaLM4F.mk; path = Makefiles/EnergiaLM4F.mk; sourceTree = ""; }; + 7BA5562A18ED087600E45020 /* MapleIDE.mk */ = {isa = PBXFileReference; lastKnownFileType = text; name = MapleIDE.mk; path = Makefiles/MapleIDE.mk; sourceTree = ""; }; + 7BA5562B18ED087600E45020 /* Microduino.mk */ = {isa = PBXFileReference; lastKnownFileType = text; name = Microduino.mk; path = Makefiles/Microduino.mk; sourceTree = ""; }; + 7BA5562C18ED087600E45020 /* Mpide.mk */ = {isa = PBXFileReference; lastKnownFileType = text; name = Mpide.mk; path = Makefiles/Mpide.mk; sourceTree = ""; }; + 7BA5562D18ED087600E45020 /* Wiring.mk */ = {isa = PBXFileReference; lastKnownFileType = text; name = Wiring.mk; path = Makefiles/Wiring.mk; sourceTree = ""; }; + 7BA5562E18ED087600E45020 /* Step1.mk */ = {isa = PBXFileReference; lastKnownFileType = text; name = Step1.mk; path = Makefiles/Step1.mk; sourceTree = ""; }; + 7BA5562F18ED087600E45020 /* Step2.mk */ = {isa = PBXFileReference; lastKnownFileType = text; name = Step2.mk; path = Makefiles/Step2.mk; sourceTree = ""; }; + 7BA5563018ED087600E45020 /* Teensy.mk */ = {isa = PBXFileReference; lastKnownFileType = text; name = Teensy.mk; path = Makefiles/Teensy.mk; sourceTree = ""; }; + 7BA5563118ED087600E45020 /* Teensy2.mk */ = {isa = PBXFileReference; lastKnownFileType = text; name = Teensy2.mk; path = Makefiles/Teensy2.mk; sourceTree = ""; }; + 7BA5563218ED087600E45020 /* Teensy3.mk */ = {isa = PBXFileReference; lastKnownFileType = text; name = Teensy3.mk; path = Makefiles/Teensy3.mk; sourceTree = ""; }; + 7BA5563318ED087600E45020 /* Avrdude.mk */ = {isa = PBXFileReference; lastKnownFileType = text; name = Avrdude.mk; path = Makefiles/Avrdude.mk; sourceTree = ""; }; + 7BA5563418ED087600E45020 /* ReadMe.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = ReadMe.txt; sourceTree = ""; }; + 7BA5563618ED087600E45020 /* About.txt */ = {isa = PBXFileReference; lastKnownFileType = text; name = About.txt; path = About/About.txt; sourceTree = ""; }; + 7BA5563818ED087600E45020 /* reset.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; name = reset.py; path = Utilities/reset.py; sourceTree = ""; }; + 7BA5563918ED087600E45020 /* serial1200.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; name = serial1200.py; path = Utilities/serial1200.py; sourceTree = ""; }; + 7BA5563A18ED087600E45020 /* embedXcode_prepare */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.executable"; name = embedXcode_prepare; path = Utilities/embedXcode_prepare; sourceTree = ""; }; + 7BA5563B18ED087600E45020 /* embedXcode_check */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.executable"; name = embedXcode_check; path = Utilities/embedXcode_check; sourceTree = ""; }; + 7BA5563C18ED087600E45020 /* embedXcode_chrono */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.executable"; name = embedXcode_chrono; path = Utilities/embedXcode_chrono; sourceTree = ""; }; + 7BA5563D18ED087600E45020 /* TemplateIcon.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; name = TemplateIcon.icns; path = Utilities/TemplateIcon.icns; sourceTree = ""; }; + 7BA5563E18ED087600E45020 /* FastLED.ino */ = {isa = PBXFileReference; lastKnownFileType = text; path = FastLED.ino; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXGroup section */ + 7BA555EB18ED087600E45020 = { + isa = PBXGroup; + children = ( + 7BA555F818ED087600E45020 /* FastLED */, + 7BA555F718ED087600E45020 /* Products */, + ); + sourceTree = ""; + }; + 7BA555F718ED087600E45020 /* Products */ = { + isa = PBXGroup; + children = ( + 7BA555F618ED087600E45020 /* Index */, + ); + name = Products; + sourceTree = ""; + }; + 7BA555F818ED087600E45020 /* FastLED */ = { + isa = PBXGroup; + children = ( + 7BA555F918ED087600E45020 /* main.cpp */, + 7BA555FB18ED087600E45020 /* LocalLibrary.cpp */, + 7BA555FD18ED087600E45020 /* LocalLibrary.h */, + 7BA555FE18ED087600E45020 /* Makefile */, + 7BA5563418ED087600E45020 /* ReadMe.txt */, + 7BA5563E18ED087600E45020 /* FastLED.ino */, + 7BA5560018ED087600E45020 /* Sketchbook */, + 7BA5560218ED087600E45020 /* Configurations */, + 7BA5562118ED087600E45020 /* Makefiles */, + 7BA5563518ED087600E45020 /* About */, + 7BA5563718ED087600E45020 /* Utilities */, + ); + path = FastLED; + sourceTree = ""; + }; + 7BA5560018ED087600E45020 /* Sketchbook */ = { + isa = PBXGroup; + children = ( + 7BA5560118ED087600E45020 /* Sketchbook.txt */, + ); + name = Sketchbook; + sourceTree = ""; + }; + 7BA5560218ED087600E45020 /* Configurations */ = { + isa = PBXGroup; + children = ( + 7BA5560318ED087600E45020 /* Arduino Due.xcconfig */, + 7BA5560418ED087600E45020 /* Arduino Duemilanove.xcconfig */, + 7BA5560518ED087600E45020 /* Arduino Leonardo.xcconfig */, + 7BA5560618ED087600E45020 /* Arduino Mega 2560.xcconfig */, + 7BA5560718ED087600E45020 /* Arduino Mini with ATmega328-3.3V.xcconfig */, + 7BA5560818ED087600E45020 /* Arduino Mini with ATmega328-5V.xcconfig */, + 7BA5560918ED087600E45020 /* Arduino Robot Control.xcconfig */, + 7BA5560A18ED087600E45020 /* Arduino Robot Motor.xcconfig */, + 7BA5560B18ED087600E45020 /* Arduino Uno.xcconfig */, + 7BA5560C18ED087600E45020 /* Arduino Yun.xcconfig */, + 7BA5560D18ED087600E45020 /* chipKIT Uno32.xcconfig */, + 7BA5560E18ED087600E45020 /* chipKIT Max32.xcconfig */, + 7BA5560F18ED087600E45020 /* chipKIT uC32.xcconfig */, + 7BA5561018ED087600E45020 /* DFRobot BLuno.xcconfig */, + 7BA5561118ED087600E45020 /* Digispark Tiny Core.xcconfig */, + 7BA5561218ED087600E45020 /* Experimeter Board with MSP430FR5739.xcconfig */, + 7BA5561318ED087600E45020 /* LaunchPad Stellaris with LM4F120.xcconfig */, + 7BA5561418ED087600E45020 /* LaunchPad Tiva C with TM4C123.xcconfig */, + 7BA5561518ED087600E45020 /* LaunchPad with MSP430G2553.xcconfig */, + 7BA5561618ED087600E45020 /* LaunchPad with MSP430G2231.xcconfig */, + 7BA5561718ED087600E45020 /* LaunchPad with MSP430G2452.xcconfig */, + 7BA5561818ED087600E45020 /* LaunchPad with MSP430F5529.xcconfig */, + 7BA5561918ED087600E45020 /* Maple Flash revision 3+.xcconfig */, + 7BA5561A18ED087600E45020 /* Microduino Core with ATmega328-5V.xcconfig */, + 7BA5561B18ED087600E45020 /* Microduino Core+ with ATmega644-5V.xcconfig */, + 7BA5561C18ED087600E45020 /* Sparkfun Uno.xcconfig */, + 7BA5561D18ED087600E45020 /* Teensy 2.0.xcconfig */, + 7BA5561E18ED087600E45020 /* Teensy 3.0.xcconfig */, + 7BA5561F18ED087600E45020 /* Teensy 3.1.xcconfig */, + 7BA5562018ED087600E45020 /* Wiring S.xcconfig */, + ); + name = Configurations; + sourceTree = ""; + }; + 7BA5562118ED087600E45020 /* Makefiles */ = { + isa = PBXGroup; + children = ( + 7BA5562218ED087600E45020 /* Arduino.mk */, + 7BA5562318ED087600E45020 /* Arduino1.mk */, + 7BA5562418ED087600E45020 /* Arduino15avr.mk */, + 7BA5562518ED087600E45020 /* Arduino15sam.mk */, + 7BA5562618ED087600E45020 /* Arduino23.mk */, + 7BA5562718ED087600E45020 /* Digispark.mk */, + 7BA5562818ED087600E45020 /* Energia430.mk */, + 7BA5562918ED087600E45020 /* EnergiaLM4F.mk */, + 7BA5562A18ED087600E45020 /* MapleIDE.mk */, + 7BA5562B18ED087600E45020 /* Microduino.mk */, + 7BA5562C18ED087600E45020 /* Mpide.mk */, + 7BA5562D18ED087600E45020 /* Wiring.mk */, + 7BA5562E18ED087600E45020 /* Step1.mk */, + 7BA5562F18ED087600E45020 /* Step2.mk */, + 7BA5563018ED087600E45020 /* Teensy.mk */, + 7BA5563118ED087600E45020 /* Teensy2.mk */, + 7BA5563218ED087600E45020 /* Teensy3.mk */, + 7BA5563318ED087600E45020 /* Avrdude.mk */, + ); + name = Makefiles; + sourceTree = ""; + }; + 7BA5563518ED087600E45020 /* About */ = { + isa = PBXGroup; + children = ( + 7BA5563618ED087600E45020 /* About.txt */, + ); + name = About; + sourceTree = ""; + }; + 7BA5563718ED087600E45020 /* Utilities */ = { + isa = PBXGroup; + children = ( + 7BA5563818ED087600E45020 /* reset.py */, + 7BA5563918ED087600E45020 /* serial1200.py */, + 7BA5563A18ED087600E45020 /* embedXcode_prepare */, + 7BA5563B18ED087600E45020 /* embedXcode_check */, + 7BA5563C18ED087600E45020 /* embedXcode_chrono */, + 7BA5563D18ED087600E45020 /* TemplateIcon.icns */, + ); + name = Utilities; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXLegacyTarget section */ + 7BA555F018ED087600E45020 /* All */ = { + isa = PBXLegacyTarget; + buildArgumentsString = "all -C \"$(PROJECT)\""; + buildConfigurationList = 7BA5564118ED087600E45020 /* Build configuration list for PBXLegacyTarget "All" */; + buildPhases = ( + ); + buildToolPath = make; + dependencies = ( + ); + name = All; + passBuildSettingsInEnvironment = 1; + productName = All; + }; + 7BA555F118ED087600E45020 /* Build */ = { + isa = PBXLegacyTarget; + buildArgumentsString = "build -C \"$(PROJECT)\""; + buildConfigurationList = 7BA5564418ED087600E45020 /* Build configuration list for PBXLegacyTarget "Build" */; + buildPhases = ( + ); + buildToolPath = make; + dependencies = ( + ); + name = Build; + passBuildSettingsInEnvironment = 1; + productName = Build; + }; + 7BA555F218ED087600E45020 /* Serial */ = { + isa = PBXLegacyTarget; + buildArgumentsString = "serial -C \"$(PROJECT)\""; + buildConfigurationList = 7BA5564718ED087600E45020 /* Build configuration list for PBXLegacyTarget "Serial" */; + buildPhases = ( + ); + buildToolPath = make; + dependencies = ( + ); + name = Serial; + passBuildSettingsInEnvironment = 1; + productName = Serial; + }; + 7BA555F318ED087600E45020 /* Upload */ = { + isa = PBXLegacyTarget; + buildArgumentsString = "upload -C \"$(PROJECT)\""; + buildConfigurationList = 7BA5564A18ED087600E45020 /* Build configuration list for PBXLegacyTarget "Upload" */; + buildPhases = ( + ); + buildToolPath = make; + dependencies = ( + ); + name = Upload; + passBuildSettingsInEnvironment = 1; + productName = Upload; + }; +/* End PBXLegacyTarget section */ + +/* Begin PBXNativeTarget section */ + 7BA555F518ED087600E45020 /* Index */ = { + isa = PBXNativeTarget; + buildConfigurationList = 7BA5564D18ED087600E45020 /* Build configuration list for PBXNativeTarget "Index" */; + buildPhases = ( + 7BA555F418ED087600E45020 /* Sources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Index; + productName = Index; + productReference = 7BA555F618ED087600E45020 /* Index */; + productType = "com.apple.product-type.tool"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 7BA555EC18ED087600E45020 /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0510; + ORGANIZATIONNAME = "Daniel Garcia"; + }; + buildConfigurationList = 7BA555EF18ED087600E45020 /* Build configuration list for PBXProject "FastLED" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + ); + mainGroup = 7BA555EB18ED087600E45020; + productRefGroup = 7BA555F718ED087600E45020 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 7BA555F018ED087600E45020 /* All */, + 7BA555F118ED087600E45020 /* Build */, + 7BA555F218ED087600E45020 /* Serial */, + 7BA555F318ED087600E45020 /* Upload */, + 7BA555F518ED087600E45020 /* Index */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXSourcesBuildPhase section */ + 7BA555F418ED087600E45020 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 7BA555FF18ED087600E45020 /* Makefile in Sources */, + 7BA555FA18ED087600E45020 /* main.cpp in Sources */, + 7BA555FC18ED087600E45020 /* LocalLibrary.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + 7BA5563F18ED087600E45020 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7BA5560B18ED087600E45020 /* Arduino Uno.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + HEADER_SEARCH_PATHS = "$(inherited)"; + PATH = "$(PATH):$(PROJECT_DIR)"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKETCHBOOK_DIR = ""; + SKETCH_EXTENSION = ino; + }; + name = Debug; + }; + 7BA5564018ED087600E45020 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = YES; + ENABLE_NS_ASSERTIONS = NO; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + HEADER_SEARCH_PATHS = "$(inherited)"; + PATH = "$(PATH):$(PROJECT_DIR)"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKETCHBOOK_DIR = ""; + SKETCH_EXTENSION = ino; + }; + name = Release; + }; + 7BA5564218ED087600E45020 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + 7BA5564318ED087600E45020 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; + 7BA5564518ED087600E45020 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + }; + name = Debug; + }; + 7BA5564618ED087600E45020 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + }; + name = Release; + }; + 7BA5564818ED087600E45020 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + }; + name = Debug; + }; + 7BA5564918ED087600E45020 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + }; + name = Release; + }; + 7BA5564B18ED087600E45020 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + }; + name = Debug; + }; + 7BA5564C18ED087600E45020 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + }; + name = Release; + }; + 7BA5564E18ED087600E45020 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + }; + name = Debug; + }; + 7BA5564F18ED087600E45020 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 7BA555EF18ED087600E45020 /* Build configuration list for PBXProject "FastLED" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 7BA5563F18ED087600E45020 /* Debug */, + 7BA5564018ED087600E45020 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 7BA5564118ED087600E45020 /* Build configuration list for PBXLegacyTarget "All" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 7BA5564218ED087600E45020 /* Debug */, + 7BA5564318ED087600E45020 /* Release */, + ); + defaultConfigurationIsVisible = 0; + }; + 7BA5564418ED087600E45020 /* Build configuration list for PBXLegacyTarget "Build" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 7BA5564518ED087600E45020 /* Debug */, + 7BA5564618ED087600E45020 /* Release */, + ); + defaultConfigurationIsVisible = 0; + }; + 7BA5564718ED087600E45020 /* Build configuration list for PBXLegacyTarget "Serial" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 7BA5564818ED087600E45020 /* Debug */, + 7BA5564918ED087600E45020 /* Release */, + ); + defaultConfigurationIsVisible = 0; + }; + 7BA5564A18ED087600E45020 /* Build configuration list for PBXLegacyTarget "Upload" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 7BA5564B18ED087600E45020 /* Debug */, + 7BA5564C18ED087600E45020 /* Release */, + ); + defaultConfigurationIsVisible = 0; + }; + 7BA5564D18ED087600E45020 /* Build configuration list for PBXNativeTarget "Index" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 7BA5564E18ED087600E45020 /* Debug */, + 7BA5564F18ED087600E45020 /* Release */, + ); + defaultConfigurationIsVisible = 0; + }; +/* End XCConfigurationList section */ + }; + rootObject = 7BA555EC18ED087600E45020 /* Project object */; +} diff --git a/FastLED/FastLED.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/FastLED/FastLED.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000..203db588 --- /dev/null +++ b/FastLED/FastLED.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/FastLED/FastLED.xcodeproj/project.xcworkspace/xcuserdata/dgarcia.xcuserdatad/UserInterfaceState.xcuserstate b/FastLED/FastLED.xcodeproj/project.xcworkspace/xcuserdata/dgarcia.xcuserdatad/UserInterfaceState.xcuserstate new file mode 100644 index 00000000..8685299f Binary files /dev/null and b/FastLED/FastLED.xcodeproj/project.xcworkspace/xcuserdata/dgarcia.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/FastLED/FastLED.xcodeproj/xcuserdata/dgarcia.xcuserdatad/xcschemes/All.xcscheme b/FastLED/FastLED.xcodeproj/xcuserdata/dgarcia.xcuserdatad/xcschemes/All.xcscheme new file mode 100644 index 00000000..6ff2b50f --- /dev/null +++ b/FastLED/FastLED.xcodeproj/xcuserdata/dgarcia.xcuserdatad/xcschemes/All.xcscheme @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/FastLED/FastLED.xcodeproj/xcuserdata/dgarcia.xcuserdatad/xcschemes/Build.xcscheme b/FastLED/FastLED.xcodeproj/xcuserdata/dgarcia.xcuserdatad/xcschemes/Build.xcscheme new file mode 100644 index 00000000..c5853b74 --- /dev/null +++ b/FastLED/FastLED.xcodeproj/xcuserdata/dgarcia.xcuserdatad/xcschemes/Build.xcscheme @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/FastLED/FastLED.xcodeproj/xcuserdata/dgarcia.xcuserdatad/xcschemes/Index.xcscheme b/FastLED/FastLED.xcodeproj/xcuserdata/dgarcia.xcuserdatad/xcschemes/Index.xcscheme new file mode 100644 index 00000000..0ee62c4a --- /dev/null +++ b/FastLED/FastLED.xcodeproj/xcuserdata/dgarcia.xcuserdatad/xcschemes/Index.xcscheme @@ -0,0 +1,86 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/FastLED/FastLED.xcodeproj/xcuserdata/dgarcia.xcuserdatad/xcschemes/Serial.xcscheme b/FastLED/FastLED.xcodeproj/xcuserdata/dgarcia.xcuserdatad/xcschemes/Serial.xcscheme new file mode 100644 index 00000000..47d41b70 --- /dev/null +++ b/FastLED/FastLED.xcodeproj/xcuserdata/dgarcia.xcuserdatad/xcschemes/Serial.xcscheme @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/FastLED/FastLED.xcodeproj/xcuserdata/dgarcia.xcuserdatad/xcschemes/Upload.xcscheme b/FastLED/FastLED.xcodeproj/xcuserdata/dgarcia.xcuserdatad/xcschemes/Upload.xcscheme new file mode 100644 index 00000000..e9440d31 --- /dev/null +++ b/FastLED/FastLED.xcodeproj/xcuserdata/dgarcia.xcuserdatad/xcschemes/Upload.xcscheme @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/FastLED/FastLED.xcodeproj/xcuserdata/dgarcia.xcuserdatad/xcschemes/xcschememanagement.plist b/FastLED/FastLED.xcodeproj/xcuserdata/dgarcia.xcuserdatad/xcschemes/xcschememanagement.plist new file mode 100644 index 00000000..16c50ac3 --- /dev/null +++ b/FastLED/FastLED.xcodeproj/xcuserdata/dgarcia.xcuserdatad/xcschemes/xcschememanagement.plist @@ -0,0 +1,62 @@ + + + + + SchemeUserState + + All.xcscheme + + orderHint + 0 + + Build.xcscheme + + orderHint + 1 + + Index.xcscheme + + orderHint + 4 + + Serial.xcscheme + + orderHint + 2 + + Upload.xcscheme + + orderHint + 3 + + + SuppressBuildableAutocreation + + 7BA555F018ED087600E45020 + + primary + + + 7BA555F118ED087600E45020 + + primary + + + 7BA555F218ED087600E45020 + + primary + + + 7BA555F318ED087600E45020 + + primary + + + 7BA555F518ED087600E45020 + + primary + + + + + diff --git a/FastLED/FastLED/About/About.txt b/FastLED/FastLED/About/About.txt new file mode 100644 index 00000000..d3d57cc8 --- /dev/null +++ b/FastLED/FastLED/About/About.txt @@ -0,0 +1,15 @@ + + embedXcode + embedXcode+ + ---------------------------------- + Embedded Computing on Xcode + + + © Rei VILO, 2010-2014 + All rights reserved + http://embedXcode.weebly.com/ + + +embedXcode • Mar 26, 2014 release 143 • Improved code sense for libraries +embedXcode+ • Mar 26, 2014 release 143 • Improved code sense for libraries + \ No newline at end of file diff --git a/FastLED/FastLED/Configurations/Arduino Due.xcconfig b/FastLED/FastLED/Configurations/Arduino Due.xcconfig new file mode 100755 index 00000000..1fdfe498 --- /dev/null +++ b/FastLED/FastLED/Configurations/Arduino Due.xcconfig @@ -0,0 +1,45 @@ +// +// Arduino Due.xcconfig +// Board configuration file +// ---------------------------------- +// Developed with embedXcode +// +// Part of embedXcode +// Embedded Computing on Xcode +// +// Created by Rei Vilo on Oct 23, 2012 +// Copyright (c) 2012-2014 http://embedxcode.weebly.com +// License All rigths reserved +// +// Last update: Feb 06, 2014 release 131 + +// Board identifier +// See Boards.txt for .name=Arduino Uno (16 MHz) +// +BOARD_TAG = arduino_due_x + +// Port (optionnal) +// most common are /dev/tty.usbserial*, /dev/tty.usbmodem* or /dev/tty.uart* +// Note: if /dev/tty.usbserial* doesn't work, try /dev/tty.usbmodem* +// +BOARD_PORT = /dev/tty.usbserial* +//BOARD_PORT = /dev/tty.usbmodem* + +// Warning: some users have reported /dev/cu.usb* + +// References for Xcode code-sense +// See Boards.txt for .build.mcu= +// +GCC_PREPROCESSOR_DEFINITIONS = __SAM3X8E__ ARDUINO + +// Specify the full path and name of the application +// with /Contents/Resources/Java/** after +// +HEADER_SEARCH_PATHS = /Applications/Arduino.app/Contents/Resources/Java/** + +// Maximum RAM size in bytes +// given by .upload.maximum_ram_size in boards.txt for Maple and Teensy +// given by .upload.maximum_data_size in boards.txt for Arduino 1.5.x +// +MAX_RAM_SIZE = 98304 + diff --git a/FastLED/FastLED/Configurations/Arduino Duemilanove.xcconfig b/FastLED/FastLED/Configurations/Arduino Duemilanove.xcconfig new file mode 100644 index 00000000..7aaea12e --- /dev/null +++ b/FastLED/FastLED/Configurations/Arduino Duemilanove.xcconfig @@ -0,0 +1,46 @@ +// +// Duemilanove.xcconfig +// Board configuration file +// ---------------------------------- +// Developed with embedXcode +// +// Part of embedXcode +// Embedded Computing on Xcode +// +// Created by Joel Saltzman on 4/12/13 +// Copyright (c) 2013 joelsaltzman.com +// License All rigths reserved +// +// Maintained by Rei VILO on Mar 12, 2012 +// Copyright (c) 2012-2014 http://embedxcode.weebly.com +// License All rights reserved +// +// Last update: Feb 06, 2014 release 131 + +// Board identifier +// See Boards.txt for .name=Arduino Uno (16 MHz) +// +BOARD_TAG = uno + +// Port (optionnal) +// most common are /dev/tty.usbserial*, /dev/tty.usbmodem* or /dev/tty.uart* +// +BOARD_PORT = /dev/tty.usbserial* +AVRDUDE_BAUDRATE = 57600 + +// References for Xcode code-sense +// See Boards.txt for .build.mcu= +// +GCC_PREPROCESSOR_DEFINITIONS = AVR_ATmega328P ARDUINO + +// Specify the full path and name of the application +// with /Contents/Resources/Java/** after +// +HEADER_SEARCH_PATHS = /Applications/Arduino.app/Contents/Resources/Java/** + +// Maximum RAM size in bytes +// given by .upload.maximum_ram_size in boards.txt for Maple and Teensy +// given by .upload.maximum_data_size in boards.txt for Arduino 1.5.x +// +MAX_RAM_SIZE = 2048 + diff --git a/FastLED/FastLED/Configurations/Arduino Leonardo.xcconfig b/FastLED/FastLED/Configurations/Arduino Leonardo.xcconfig new file mode 100755 index 00000000..251be856 --- /dev/null +++ b/FastLED/FastLED/Configurations/Arduino Leonardo.xcconfig @@ -0,0 +1,41 @@ +// +// Arduino Leonardo.xcconfig +// Board configuration file +// ---------------------------------- +// Developed with embedXcode +// +// Part of embedXcode +// Embedded Computing on Xcode +// +// Created by Rei Vilo on Aug 29, 2012 +// Copyright (c) 2012-2014 http://embedxcode.weebly.com +// License All rigths reserved +// +// Last update: Feb 06, 2014 release 131 + +// Board identifier +// See Boards.txt for .name=Arduino Uno (16 MHz) +// +BOARD_TAG = leonardo + +// Port (optionnal) +// most common are /dev/tty.usbserial*, /dev/tty.usbmodem* or /dev/tty.uart* +// +BOARD_PORT = /dev/tty.usbmodem* + +// References for Xcode code-sense +// See Boards.txt for .build.mcu= +// +GCC_PREPROCESSOR_DEFINITIONS = __AVR_ATmega32U4__ ARDUINO + +// Specify the full path and name of the application +// with /Contents/Resources/Java/** after +// +HEADER_SEARCH_PATHS = /Applications/Arduino.app/Contents/Resources/Java/** + +// Maximum RAM size in bytes +// given by .upload.maximum_ram_size in boards.txt for Maple and Teensy +// given by .upload.maximum_data_size in boards.txt for Arduino 1.5.x +// +MAX_RAM_SIZE = 2560 + diff --git a/FastLED/FastLED/Configurations/Arduino Mega 2560.xcconfig b/FastLED/FastLED/Configurations/Arduino Mega 2560.xcconfig new file mode 100755 index 00000000..29a59417 --- /dev/null +++ b/FastLED/FastLED/Configurations/Arduino Mega 2560.xcconfig @@ -0,0 +1,46 @@ +// +// Arduino Mega 2560.xcconfig +// Board configuration file +// ---------------------------------- +// Developed with embedXcode +// +// Part of embedXcode +// Embedded Computing on Xcode +// +// Created by Rei VILO on Mar 12, 2012 +// Copyright (c) 2012-2014 http://embedxcode.weebly.com +// License All rigths reserved +// +// Last update: Feb 06, 2014 release 131 + +// Board identifier +// See Boards.txt for .name=Arduino Uno (16 MHz) +// +BOARD_TAG = mega2560 + +// For Arduino 1.5.x, if different from Arduino 1.0.x +// +BOARD_TAG1 = mega +BOARD_TAG2 = mega.menu.cpu.atmega2560 + +// Port (optionnal) +// most common are /dev/tty.usbserial*, /dev/tty.usbmodem* or /dev/tty.uart* +// +BOARD_PORT = /dev/tty.usbmodem* + +// References for Xcode code-sense +// See Boards.txt for .build.mcu= +// +GCC_PREPROCESSOR_DEFINITIONS = __AVR_ATmega2560__ ARDUINO + +// Specify the full path and name of the application +// with /Contents/Resources/Java/** after +// +HEADER_SEARCH_PATHS = /Applications/Arduino.app/Contents/Resources/Java/** + +// Maximum RAM size in bytes +// given by .upload.maximum_ram_size in boards.txt for Maple and Teensy +// given by .upload.maximum_data_size in boards.txt for Arduino 1.5.x +// +MAX_RAM_SIZE = 8196 + diff --git a/FastLED/FastLED/Configurations/Arduino Mini with ATmega328-3.3V.xcconfig b/FastLED/FastLED/Configurations/Arduino Mini with ATmega328-3.3V.xcconfig new file mode 100644 index 00000000..c04f74a4 --- /dev/null +++ b/FastLED/FastLED/Configurations/Arduino Mini with ATmega328-3.3V.xcconfig @@ -0,0 +1,45 @@ +// +// Arduino Mini with ATmega328-3.3V.xcconfig +// Board configuration file +// ---------------------------------- +// Developed with embedXcode +// +// Part of embedXcode +// Embedded Computing on Xcode +// +// Created by Rei VILO on Mar 05, 2014 +// Copyright (c) 2014 http://embeddedcomputing.weebly.com +// License All rigths reserved +// +// Last update: Mar 06, 2014 release 138 + +// Board identifier +// See Boards.txt for .name=Arduino Uno (16 MHz) +// +BOARD_TAG = pro328 + +// For Arduino 1.5.x, if different from Arduino 1.0.x +// +BOARD_TAG1 = pro +BOARD_TAG2 = pro.menu.cpu.8MHzatmega328 + +// Port (optionnal) +// most common are /dev/tty.usbserial*, /dev/tty.usbmodem* or /dev/tty.uart* +// +BOARD_PORT = /dev/tty.usbmodem* + +// References for Xcode code-sense +// See Boards.txt for .build.mcu= +// +GCC_PREPROCESSOR_DEFINITIONS = __AVR_ATmega328P__ ARDUINO + +// Specify the full path and name of the application +// with /Contents/Resources/Java/** after +// +HEADER_SEARCH_PATHS = /Applications/Arduino.app/Contents/Resources/Java/** + +// Maximum RAM size in bytes +// given by .upload.maximum_ram_size in boards.txt for Maple and Teensy +// given by .upload.maximum_data_size in boards.txt for Arduino 1.5.x +// +MAX_RAM_SIZE = 2048 diff --git a/FastLED/FastLED/Configurations/Arduino Mini with ATmega328-5V.xcconfig b/FastLED/FastLED/Configurations/Arduino Mini with ATmega328-5V.xcconfig new file mode 100755 index 00000000..7d658cdb --- /dev/null +++ b/FastLED/FastLED/Configurations/Arduino Mini with ATmega328-5V.xcconfig @@ -0,0 +1,46 @@ +// +// Arduino Mini with ATmega328-5V.xcconfig +// Board configuration file +// ---------------------------------- +// Developed with embedXcode +// +// Part of embedXcode +// Embedded Computing on Xcode +// +// Created by Rei VILO on Mar 12, 2012 +// Copyright (c) 2012-2014 http://embedxcode.weebly.com +// License All rigths reserved +// +// Last update: Mar 06, 2014 release 138 + +// Board identifier +// See Boards.txt for .name=Arduino Uno (16 MHz) +// +BOARD_TAG = pro5v328 + +// For Arduino 1.5.x, if different from Arduino 1.0.x +// +BOARD_TAG1 = pro +BOARD_TAG2 = menu.cpu.pro.16MHzatmega328 + +// Port (optionnal) +// most common are /dev/tty.usbserial*, /dev/tty.usbmodem* or /dev/tty.uart* +// +BOARD_PORT = /dev/tty.usbmodem* + +// References for Xcode code-sense +// See Boards.txt for .build.mcu= +// +GCC_PREPROCESSOR_DEFINITIONS = __AVR_ATmega328P__ ARDUINO + +// Specify the full path and name of the application +// with /Contents/Resources/Java/** after +// +HEADER_SEARCH_PATHS = /Applications/Arduino.app/Contents/Resources/Java/** + +// Maximum RAM size in bytes +// given by .upload.maximum_ram_size in boards.txt for Maple and Teensy +// given by .upload.maximum_data_size in boards.txt for Arduino 1.5.x +// +MAX_RAM_SIZE = 2048 + diff --git a/FastLED/FastLED/Configurations/Arduino Robot Control.xcconfig b/FastLED/FastLED/Configurations/Arduino Robot Control.xcconfig new file mode 100644 index 00000000..946cf0f8 --- /dev/null +++ b/FastLED/FastLED/Configurations/Arduino Robot Control.xcconfig @@ -0,0 +1,40 @@ +// +// Arduino Robot Control.xcconfig +// Board configuration file +// ---------------------------------- +// Developed with embedXcode +// +// Part of embedXcode +// Embedded Computing on Xcode +// +// Created by Rei VILO on Jun 21, 2013 +// Copyright (c) 2012-2014 http://embedxcode.weebly.com +// License All rigths reserved +// +// Last update: Feb 06, 2014 release 131 + +// Board identifier +// See Boards.txt for .name=Arduino Uno (16 MHz) +// +BOARD_TAG = robotControl + +// Port (optionnal) +// most common are /dev/tty.usbserial*, /dev/tty.usbmodem* or /dev/tty.uart* +// +BOARD_PORT = /dev/tty.usbmodem* + +// References for Xcode code-sense +// See Boards.txt for .build.mcu= +// +GCC_PREPROCESSOR_DEFINITIONS = __AVR_ATmega328P__ ARDUINO + +// Specify the full path and name of the application +// with /Contents/Resources/Java/** after +// +HEADER_SEARCH_PATHS = /Applications/Arduino.app/Contents/Resources/Java/** + +// Maximum RAM size in bytes +// given by .upload.maximum_ram_size in boards.txt for Maple and Teensy +// given by .upload.maximum_data_size in boards.txt for Arduino 1.5.x +// +MAX_RAM_SIZE = 2048 diff --git a/FastLED/FastLED/Configurations/Arduino Robot Motor.xcconfig b/FastLED/FastLED/Configurations/Arduino Robot Motor.xcconfig new file mode 100644 index 00000000..dbc5d3f6 --- /dev/null +++ b/FastLED/FastLED/Configurations/Arduino Robot Motor.xcconfig @@ -0,0 +1,40 @@ +// +// Arduino Robot Control.xcconfig +// Board configuration file +// ---------------------------------- +// Developed with embedXcode +// +// Part of embedXcode +// Embedded Computing on Xcode +// +// Created by Rei VILO on Jun 21, 2013 +// Copyright (c) 2012-2014 http://embedxcode.weebly.com +// License All rigths reserved +// +// Last update: Feb 06, 2014 release 131 + +// Board identifier +// See Boards.txt for .name=Arduino Uno (16 MHz) +// +BOARD_TAG = robotMotor + +// Port (optionnal) +// most common are /dev/tty.usbserial*, /dev/tty.usbmodem* or /dev/tty.uart* +// +BOARD_PORT = /dev/tty.usbmodem* + +// References for Xcode code-sense +// See Boards.txt for .build.mcu= +// +GCC_PREPROCESSOR_DEFINITIONS = __AVR_ATmega328P__ ARDUINO + +// Specify the full path and name of the application +// with /Contents/Resources/Java/** after +// +HEADER_SEARCH_PATHS = /Applications/Arduino.app/Contents/Resources/Java/** + +// Maximum RAM size in bytes +// given by .upload.maximum_ram_size in boards.txt for Maple and Teensy +// given by .upload.maximum_data_size in boards.txt for Arduino 1.5.x +// +MAX_RAM_SIZE = 2048 diff --git a/FastLED/FastLED/Configurations/Arduino Uno.xcconfig b/FastLED/FastLED/Configurations/Arduino Uno.xcconfig new file mode 100755 index 00000000..ac4cb60e --- /dev/null +++ b/FastLED/FastLED/Configurations/Arduino Uno.xcconfig @@ -0,0 +1,40 @@ +// +// Arduino Uno.xcconfig +// Board configuration file +// ---------------------------------- +// Developed with embedXcode +// +// Part of embedXcode +// Embedded Computing on Xcode +// +// Created by Rei VILO on Mar 12, 2012 +// Copyright (c) 2012-2014 http://embedxcode.weebly.com +// License All rigths reserved +// +// Last update: Feb 06, 2014 release 131 + +// Board identifier +// See Boards.txt for .name=Arduino Uno (16 MHz) +// +BOARD_TAG = uno + +// Port (optionnal) +// most common are /dev/tty.usbserial*, /dev/tty.usbmodem* or /dev/tty.uart* +// +BOARD_PORT = /dev/tty.usbmodem* + +// References for Xcode code-sense +// See Boards.txt for .build.mcu= +// +GCC_PREPROCESSOR_DEFINITIONS = __AVR_ATmega328P__ ARDUINO + +// Specify the full path and name of the application +// with /Contents/Resources/Java/** after +// +HEADER_SEARCH_PATHS = /Applications/Arduino.app/Contents/Resources/Java/** + +// Maximum RAM size in bytes +// given by .upload.maximum_ram_size in boards.txt for Maple and Teensy +// given by .upload.maximum_data_size in boards.txt for Arduino 1.5.x +// +MAX_RAM_SIZE = 2048 diff --git a/FastLED/FastLED/Configurations/Arduino Yun.xcconfig b/FastLED/FastLED/Configurations/Arduino Yun.xcconfig new file mode 100755 index 00000000..88aa8393 --- /dev/null +++ b/FastLED/FastLED/Configurations/Arduino Yun.xcconfig @@ -0,0 +1,40 @@ +// +// Arduino Yun.xcconfig +// Board configuration file +// ---------------------------------- +// Developed with embedXcode +// +// Part of embedXcode +// Embedded Computing on Xcode +// +// Created by Rei VILO on Jan 22, 2014 +// Copyright (c) 2012-2014 http://embedxcode.weebly.com +// License All rigths reserved +// +// Last update: Feb 06, 2014 release 131 + +// Board identifier +// See Boards.txt for .name=Arduino Uno (16 MHz) +// +BOARD_TAG = yun + +// Port (optionnal) +// most common are /dev/tty.usbserial*, /dev/tty.usbmodem* or /dev/tty.uart* +// +BOARD_PORT = /dev/tty.usbmodem* + +// References for Xcode code-sense +// See Boards.txt for .build.mcu= +// +GCC_PREPROCESSOR_DEFINITIONS = __AVR_ATmega32U4__ ARDUINO + +// Specify the full path and name of the application +// with /Contents/Resources/Java/** after +// +HEADER_SEARCH_PATHS = /Applications/Arduino.app/Contents/Resources/Java/** + +// Maximum RAM size in bytes +// given by .upload.maximum_ram_size in boards.txt for Maple and Teensy +// given by .upload.maximum_data_size in boards.txt for Arduino 1.5.x +// + diff --git a/FastLED/FastLED/Configurations/DFRobot BLuno.xcconfig b/FastLED/FastLED/Configurations/DFRobot BLuno.xcconfig new file mode 100755 index 00000000..11db8186 --- /dev/null +++ b/FastLED/FastLED/Configurations/DFRobot BLuno.xcconfig @@ -0,0 +1,40 @@ +// +// DFRobot BLuno.xcconfig +// Board configuration file +// ---------------------------------- +// Developed with embedXcode +// +// Part of embedXcode +// Embedded Computing on Xcode +// +// Created by Rei VILO on Mar 12, 2012 +// Copyright (c) 2012-2014 http://embedxcode.weebly.com +// License All rigths reserved +// +// Last update: Feb 06, 2014 release 131 + +// Board identifier +// See Boards.txt for .name=Arduino Uno (16 MHz) +// +BOARD_TAG = uno + +// Port (optionnal) +// most common are /dev/tty.usbserial*, /dev/tty.usbmodem* or /dev/tty.uart* +// +BOARD_PORT = /dev/tty.usbmodem* + +// References for Xcode code-sense +// See Boards.txt for .build.mcu= +// +GCC_PREPROCESSOR_DEFINITIONS = __AVR_ATmega328P__ ARDUINO + +// Specify the full path and name of the application +// with /Contents/Resources/Java/** after +// +HEADER_SEARCH_PATHS = /Applications/Arduino.app/Contents/Resources/Java/** + +// Maximum RAM size in bytes +// given by .upload.maximum_ram_size in boards.txt for Maple and Teensy +// given by .upload.maximum_data_size in boards.txt for Arduino 1.5.x +// +MAX_RAM_SIZE = 2048 diff --git a/FastLED/FastLED/Configurations/Digispark Tiny Core.xcconfig b/FastLED/FastLED/Configurations/Digispark Tiny Core.xcconfig new file mode 100644 index 00000000..f1aa6f76 --- /dev/null +++ b/FastLED/FastLED/Configurations/Digispark Tiny Core.xcconfig @@ -0,0 +1,44 @@ +// +// Digispark Tiny Core.xcconfig +// Board configuration file +// ---------------------------------- +// Developed with embedXcode +// +// Part of embedXcode +// Embedded Computing on Xcode +// +// Created by Rei VILO on Feb 14, 2013 +// Copyright (c) 2012-2014 http://embedxcode.weebly.com +// License All rigths reserved +// +// Last update: Feb 06, 2014 release 131 + +// Board identifier +// See Boards.txt for .name=Arduino Uno (16 MHz) +// +BOARD_TAG = digispark-tiny + +// Port (optionnal) +// most common are /dev/tty.usbserial*, /dev/tty.usbmodem* or /dev/tty.uart* +// +BOARD_PORT = /dev/tty.* + +// References for Xcode code-sense +// See Boards.txt for .build.mcu= +// +GCC_PREPROCESSOR_DEFINITIONS = __AVR_ATtinyX5__ DIGISPARK + +// Specify the full path and name of the application +// with /Contents/Resources/Java/** after +// +HEADER_SEARCH_PATHS = /Applications/DigisparkArduino.app/Contents/Resources/Java/** /Applications/Arduino.app/Contents/Resources/Java/** + +// Maximum RAM size in bytes +// given by .upload.maximum_ram_size in boards.txt for Maple and Teensy +// +MAX_RAM_SIZE = 512 + +// If the programmer provides no serial port, set AVRDUDE_NO_SERIAL_PORT = 1 +// Otherwise, comment or set AVRDUDE_NO_SERIAL_PORT = 0 with BOARD_PORT as serial port +// +AVRDUDE_NO_SERIAL_PORT = 1 diff --git a/FastLED/FastLED/Configurations/Experimeter Board with MSP430FR5739.xcconfig b/FastLED/FastLED/Configurations/Experimeter Board with MSP430FR5739.xcconfig new file mode 100755 index 00000000..911648b6 --- /dev/null +++ b/FastLED/FastLED/Configurations/Experimeter Board with MSP430FR5739.xcconfig @@ -0,0 +1,40 @@ +// +// Experimeter Board with MSP430FR5739.xcconfig +// Board configuration file +// ---------------------------------- +// Developed with embedXcode +// +// Part of embedXcode +// Embedded Computing on Xcode +// +// Created by Rei Vilo on Sep 20, 2012 +// Copyright (c) 2012-2014 http://embedxcode.weebly.com +// License All rigths reserved +// +// Last update: Feb 06, 2014 release 131 + +// Board identifier +// See Boards.txt for .name=Arduino Uno (16 MHz) +// +BOARD_TAG = lpmsp430fr5739 + +// Port (optionnal) +// most common are /dev/tty.usbserial*, /dev/tty.usbmodem* or /dev/tty.uart* +// +BOARD_PORT = /dev/tty.uart* + +// References for Xcode code-sense +// See Boards.txt for .build.mcu= +// +GCC_PREPROCESSOR_DEFINITIONS = __MSP430FR5739__ ENERGIA + +// Specify the full path and name of the application +// with /Contents/Resources/Java/** after +// +HEADER_SEARCH_PATHS = /Applications/Energia.app/Contents/Resources/Java/hardware/msp430/** + +// Maximum RAM size in bytes +// given by .upload.maximum_ram_size in boards.txt for Maple and Teensy +// +//MAX_RAM_SIZE = 1024 + diff --git a/FastLED/FastLED/Configurations/LaunchPad Stellaris with LM4F120.xcconfig b/FastLED/FastLED/Configurations/LaunchPad Stellaris with LM4F120.xcconfig new file mode 100755 index 00000000..e59dfb4c --- /dev/null +++ b/FastLED/FastLED/Configurations/LaunchPad Stellaris with LM4F120.xcconfig @@ -0,0 +1,40 @@ +// +// LaunchPad Stellaris with LM4F120.xcconfig +// Board configuration file +// ---------------------------------- +// Developed with embedXcode +// +// Part of embedXcode +// Embedded Computing on Xcode +// +// Created by Rei VILO on Oct 24, 2012 +// Copyright (c) 2012-2014 http://embedxcode.weebly.com +// License All rigths reserved +// +// Last update: Feb 06, 2014 release 131 + +// Board identifier +// See Boards.txt for .name=Arduino Uno (16 MHz) +// +BOARD_TAG = lplm4f120h5qr + +// Port (optionnal) +// most common are /dev/tty.usbserial*, /dev/tty.usbmodem* or /dev/tty.uart* +// +BOARD_PORT = /dev/tty.usbmodem0E* + +// References for Xcode code-sense +// See Boards.txt for .build.mcu= +// +GCC_PREPROCESSOR_DEFINITIONS = __LM4F120H5QR__ ENERGIA + +// Specify the full path and name of the application +// with /Contents/Resources/Java/** after +// +HEADER_SEARCH_PATHS = /Applications/Energia.app/Contents/Resources/Java/hardware/lm4f/** + +// Maximum RAM size in bytes +// given by .upload.maximum_ram_size in boards.txt for Maple and Teensy +// +//MAX_RAM_SIZE = 32768 + diff --git a/FastLED/FastLED/Configurations/LaunchPad Tiva C with TM4C123.xcconfig b/FastLED/FastLED/Configurations/LaunchPad Tiva C with TM4C123.xcconfig new file mode 100644 index 00000000..f4a1c783 --- /dev/null +++ b/FastLED/FastLED/Configurations/LaunchPad Tiva C with TM4C123.xcconfig @@ -0,0 +1,44 @@ +// +// LaunchPad Tiva C with TM4C123.xcconfig +// Board configuration file +// ---------------------------------- +// Developed with embedXcode +// +// Part of embedXcode +// Embedded Computing on Xcode +// +// Created by Rei VILO on 24/10/12 +// Copyright (c) 2012-2014 http://embedxcode.weebly.com +// License All rigths reserved +// +// Last update: Feb 06, 2014 release 131 + +// Board identifier +// See Boards.txt for .name=Arduino Uno (16 MHz) +// +BOARD_TAG = lptm4c1230c3pm + +// TM4C123GH6PM as http://www.ti.com/ww/en/launchpad/launchpads-tivac.html#tabs +// lptm4c1233h6pm +// lptm4c1230c3pm as boards.txt + +// Port (optionnal) +// most common are /dev/tty.usbserial*, /dev/tty.usbmodem* or /dev/tty.uart* +// +BOARD_PORT = /dev/tty.usbmodem0E* + +// References for Xcode code-sense +// See Boards.txt for .build.mcu= +// +GCC_PREPROCESSOR_DEFINITIONS = __TM4C123GH6PM__ ENERGIA + +// Specify the full path and name of the application +// with /Contents/Resources/Java/** after +// +HEADER_SEARCH_PATHS = /Applications/Energia.app/Contents/Resources/Java/hardware/lm4f/** + +// Maximum RAM size in bytes +// given by .upload.maximum_ram_size in boards.txt for Maple and Teensy +// +//MAX_RAM_SIZE = 32768 + diff --git a/FastLED/FastLED/Configurations/LaunchPad with MSP430F5529.xcconfig b/FastLED/FastLED/Configurations/LaunchPad with MSP430F5529.xcconfig new file mode 100644 index 00000000..580b1de6 --- /dev/null +++ b/FastLED/FastLED/Configurations/LaunchPad with MSP430F5529.xcconfig @@ -0,0 +1,39 @@ +// +// LaunchPad with MSP430F5529.xcconfig +// Board configuration file +// ---------------------------------- +// Developed with embedXcode +// +// Part of embedXcode +// Embedded Computing on Xcode +// +// Created by Rei VILO on Sep 05, 2013 +// Copyright (c) 2012-2014 http://embedxcode.weebly.com +// License All rigths reserved +// +// Last update: Feb 06, 2014 release 131 + +// Board identifier +// See Boards.txt for .name=Arduino Uno (16 MHz) +// +BOARD_TAG = lpmsp430f5529_25 + +// Port (optionnal) +// most common are /dev/tty.usbserial*, /dev/tty.usbmodem* or /dev/tty.uart* +// +BOARD_PORT = /dev/tty.usbmodem* + +// References for Xcode code-sense +// See Boards.txt for .build.mcu= +// +GCC_PREPROCESSOR_DEFINITIONS = __MSP430F5529__ ENERGIA + +// Specify the full path and name of the application +// with /Contents/Resources/Java/** after +// +HEADER_SEARCH_PATHS = /Applications/Energia.app/Contents/Resources/Java/hardware/msp430/** + +// Maximum RAM size in bytes +// given by .upload.maximum_ram_size in boards.txt for Maple and Teensy +// +//MAX_RAM_SIZE = 8096 diff --git a/FastLED/FastLED/Configurations/LaunchPad with MSP430G2231.xcconfig b/FastLED/FastLED/Configurations/LaunchPad with MSP430G2231.xcconfig new file mode 100755 index 00000000..aa0ff285 --- /dev/null +++ b/FastLED/FastLED/Configurations/LaunchPad with MSP430G2231.xcconfig @@ -0,0 +1,40 @@ +// +// LaunchPad with MSP430G2231.xcconfig +// Board configuration file +// ---------------------------------- +// Developed with embedXcode +// +// Part of embedXcode +// Embedded Computing on Xcode +// +// Created by Rei VILO on Apr 05, 2012 +// Copyright (c) 2012-2014 http://embedxcode.weebly.com +// License All rigths reserved +// +// Last update: Feb 06, 2014 release 131 + +// Board identifier +// See Boards.txt for .name=Arduino Uno (16 MHz) +// +BOARD_TAG = lpmsp430g2231 + +// Port (optionnal) +// most common are /dev/tty.usbserial*, /dev/tty.usbmodem* or /dev/tty.uart* +// +BOARD_PORT = /dev/tty.uart* + +// References for Xcode code-sense +// See Boards.txt for .build.mcu= +// +GCC_PREPROCESSOR_DEFINITIONS = __MSP430G2231__ ENERGIA + +// Specify the full path and name of the application +// with /Contents/Resources/Java/** after +// +HEADER_SEARCH_PATHS = /Applications/Energia.app/Contents/Resources/Java/hardware/msp430/** + +// Maximum RAM size in bytes +// given by .upload.maximum_ram_size in boards.txt for Maple and Teensy +// +//MAX_RAM_SIZE = 128 + diff --git a/FastLED/FastLED/Configurations/LaunchPad with MSP430G2452.xcconfig b/FastLED/FastLED/Configurations/LaunchPad with MSP430G2452.xcconfig new file mode 100755 index 00000000..2e68e278 --- /dev/null +++ b/FastLED/FastLED/Configurations/LaunchPad with MSP430G2452.xcconfig @@ -0,0 +1,40 @@ +// +// LaunchPad with MSP430G2452.xcconfig +// Board configuration file +// ---------------------------------- +// Developed with embedXcode +// +// Part of embedXcode +// Embedded Computing on Xcode +// +// Created by Rei VILO on Apr 05, 2012 +// Copyright (c) 2012-2014 http://embedxcode.weebly.com +// License All rigths reserved +// +// Last update: Feb 06, 2014 release 131 + +// Board identifier +// See Boards.txt for .name=Arduino Uno (16 MHz) +// +BOARD_TAG = lpmsp430g2452 + +// Port (optionnal) +// most common are /dev/tty.usbserial*, /dev/tty.usbmodem* or /dev/tty.uart* +// +BOARD_PORT = /dev/tty.uart* + +// References for Xcode code-sense +// See Boards.txt for .build.mcu= +// +GCC_PREPROCESSOR_DEFINITIONS = __MSP430G2452__ ENERGIA + +// Specify the full path and name of the application +// with /Contents/Resources/Java/** after +// +HEADER_SEARCH_PATHS = /Applications/Energia.app/Contents/Resources/Java/hardware/msp430/** + +// Maximum RAM size in bytes +// given by .upload.maximum_ram_size in boards.txt for Maple and Teensy +// +//MAX_RAM_SIZE = 256 + diff --git a/FastLED/FastLED/Configurations/LaunchPad with MSP430G2553.xcconfig b/FastLED/FastLED/Configurations/LaunchPad with MSP430G2553.xcconfig new file mode 100755 index 00000000..c080ff1b --- /dev/null +++ b/FastLED/FastLED/Configurations/LaunchPad with MSP430G2553.xcconfig @@ -0,0 +1,40 @@ +// +// LaunchPad with MSP430G2553.xcconfig +// Board configuration file +// ---------------------------------- +// Developed with embedXcode +// +// Part of embedXcode +// Embedded Computing on Xcode +// +// Created by Rei VILO on Apr 05, 2012 +// Copyright (c) 2012-2014 http://embedxcode.weebly.com +// License All rigths reserved +// +// Last update: Feb 06, 2014 release 131 + +// Board identifier +// See Boards.txt for .name=Arduino Uno (16 MHz) +// +BOARD_TAG = lpmsp430g2553 + +// Port (optionnal) +// most common are /dev/tty.usbserial*, /dev/tty.usbmodem* or /dev/tty.uart* +// +BOARD_PORT = /dev/tty.uart* + +// References for Xcode code-sense +// See Boards.txt for .build.mcu= +// +GCC_PREPROCESSOR_DEFINITIONS = __MSP430G2553__ ENERGIA + +// Specify the full path and name of the application +// with /Contents/Resources/Java/** after +// +HEADER_SEARCH_PATHS = /Applications/Energia.app/Contents/Resources/Java/hardware/msp430/** + +// Maximum RAM size in bytes +// given by .upload.maximum_ram_size in boards.txt for Maple and Teensy +// +//MAX_RAM_SIZE = 512 + diff --git a/FastLED/FastLED/Configurations/Maple Flash revision 3+.xcconfig b/FastLED/FastLED/Configurations/Maple Flash revision 3+.xcconfig new file mode 100755 index 00000000..9edd3186 --- /dev/null +++ b/FastLED/FastLED/Configurations/Maple Flash revision 3+.xcconfig @@ -0,0 +1,39 @@ +// +// Maple Flash revision 3+.xcconfig +// Board configuration file +// ---------------------------------- +// Developed with embedXcode +// +// Part of embedXcode +// Embedded Computing on Xcode +// +// Created by Rei VILO on May 23, 2012 +// Copyright (c) 2012-2014 http://embedxcode.weebly.com +// License All rigths reserved +// +// Last update: Feb 06, 2014 release 131 + +// Board identifier +// See Boards.txt for .name=Arduino Uno (16 MHz) +// +BOARD_TAG = maple + +// Port (optionnal) +// most common are /dev/tty.usbserial*, /dev/tty.usbmodem* or /dev/tty.uart* +// +BOARD_PORT = /dev/tty.usbmodem* + +// References for Xcode code-sense +// See Boards.txt for .build.mcu= +// +GCC_PREPROCESSOR_DEFINITIONS = MCU_STM32F103RB MAPLE_IDE + +// Specify the full path and name of the application +// with /Contents/Resources/Java/** after +// +HEADER_SEARCH_PATHS = /Applications/MapleIDE.app/Contents/Resources/Java/** + +// Maximum RAM size in bytes +// given by .upload.maximum_ram_size in boards.txt for Maple and Teensy +// +//MAX_RAM_SIZE = diff --git a/FastLED/FastLED/Configurations/Microduino Core with ATmega328-5V.xcconfig b/FastLED/FastLED/Configurations/Microduino Core with ATmega328-5V.xcconfig new file mode 100644 index 00000000..196a49a6 --- /dev/null +++ b/FastLED/FastLED/Configurations/Microduino Core with ATmega328-5V.xcconfig @@ -0,0 +1,39 @@ +// +// Microduino Core with ATmega328-5V.xcconfig +// Board configuration file +// ---------------------------------- +// Developed with embedXcode +// +// Part of embedXcode +// Embedded Computing on Xcode +// +// Created by Rei VILO on Jan 04, 2014 +// Copyright (c) 2012-2014 http://embedxcode.weebly.com +// License All rigths reserved +// +// Last update: Feb 06, 2014 release 131 + +// Board identifier +// See Boards.txt for .name=Arduino Uno (16 MHz) +// +BOARD_TAG = 328p16m + +// Port (optionnal) +// most common are /dev/tty.usbserial*, /dev/tty.usbmodem* or /dev/tty.uart* +// +BOARD_PORT = /dev/tty.usbserial-* + +// References for Xcode code-sense +// See Boards.txt for .build.mcu= +// +GCC_PREPROCESSOR_DEFINITIONS = __AVR_ATmega328P__ MICRODUINO + +// Specify the full path and name of the application +// with /Contents/Resources/Java/** after +// +HEADER_SEARCH_PATHS = /Applications/Arduino.app/Contents/Resources/Java/** /Applications/Microduino.app/Contents/Resources/Java/** + +// Maximum RAM size in bytes +// given by .upload.maximum_ram_size in boards.txt for Maple and Teensy +// +MAX_RAM_SIZE = 2048 diff --git a/FastLED/FastLED/Configurations/Microduino Core+ with ATmega644-5V.xcconfig b/FastLED/FastLED/Configurations/Microduino Core+ with ATmega644-5V.xcconfig new file mode 100644 index 00000000..79054d3a --- /dev/null +++ b/FastLED/FastLED/Configurations/Microduino Core+ with ATmega644-5V.xcconfig @@ -0,0 +1,39 @@ +// +// Microduino Core+ with ATmega644-5V.xcconfig +// Board configuration file +// ---------------------------------- +// Developed with embedXcode +// +// Part of embedXcode +// Embedded Computing on Xcode +// +// Created by Rei VILO on Jan 04, 2014 +// Copyright (c) 2012-2014 http://embedxcode.weebly.com +// License All rigths reserved +// +// Last update: Feb 06, 2014 release 131 + +// Board identifier +// See Boards.txt for .name=Arduino Uno (16 MHz) +// +BOARD_TAG = 644pa16m + +// Port (optionnal) +// most common are /dev/tty.usbserial*, /dev/tty.usbmodem* or /dev/tty.uart* +// +BOARD_PORT = /dev/tty.usbserial-* + +// References for Xcode code-sense +// See Boards.txt for .build.mcu= +// +GCC_PREPROCESSOR_DEFINITIONS = __AVR_ATmega644P__ MICRODUINO + +// Specify the full path and name of the application +// with /Contents/Resources/Java/** after +// +HEADER_SEARCH_PATHS = /Applications/Arduino.app/Contents/Resources/Java/** /Applications/Microduino.app/Contents/Resources/Java/** + +// Maximum RAM size in bytes +// given by .upload.maximum_ram_size in boards.txt for Maple and Teensy +// +MAX_RAM_SIZE = 4096 diff --git a/FastLED/FastLED/Configurations/Sparkfun Uno.xcconfig b/FastLED/FastLED/Configurations/Sparkfun Uno.xcconfig new file mode 100755 index 00000000..e397bd72 --- /dev/null +++ b/FastLED/FastLED/Configurations/Sparkfun Uno.xcconfig @@ -0,0 +1,45 @@ +// +// Sparkfun Uno.xcconfig +// Board configuration file +// ---------------------------------- +// Developed with embedXcode +// +// Part of embedXcode +// Embedded Computing on Xcode +// +// Created by Rei VILO on Mar 12, 2012 +// Copyright (c) 2012-2014 http://embedxcode.weebly.com +// License All rigths reserved +// +// Last update: Feb 06, 2014 release 131 + +// Board identifier +// See Boards.txt for .name=Arduino Uno (16 MHz) +// +BOARD_TAG = pro5v328 + +// For Arduino 1.5, if different from Arduino 1.0 +// +BOARD_TAG1 = pro +BOARD_TAG2 = menu.cpu.pro.16MHzatmega328 + +// Port (optionnal) +// most common are /dev/tty.usbserial*, /dev/tty.usbmodem* or /dev/tty.uart* +// +BOARD_PORT = /dev/tty.usbserial-* + +// References for Xcode code-sense +// See Boards.txt for .build.mcu= +// +GCC_PREPROCESSOR_DEFINITIONS = __AVR_ATmega328P__ ARDUINO + +// Specify the full path and name of the application +// with /Contents/Resources/Java/** after +// +HEADER_SEARCH_PATHS = /Applications/Arduino.app/Contents/Resources/Java/** + +// Maximum RAM size in bytes +// given by .upload.maximum_ram_size in boards.txt for Maple and Teensy +// +MAX_RAM_SIZE = 2048 + diff --git a/FastLED/FastLED/Configurations/Teensy 2.0.xcconfig b/FastLED/FastLED/Configurations/Teensy 2.0.xcconfig new file mode 100755 index 00000000..b89e07c1 --- /dev/null +++ b/FastLED/FastLED/Configurations/Teensy 2.0.xcconfig @@ -0,0 +1,39 @@ +// +// Teensy 2.0.xcconfig +// Board configuration file +// ---------------------------------- +// Developed with embedXcode +// +// Part of embedXcode +// Embedded Computing on Xcode +// +// Created by Rei VILO on Nov 04, 2012 +// Copyright (c) 2012-2014 http://embedxcode.weebly.com +// License All rigths reserved +// +// Last update: Feb 06, 2014 release 131 + +// Board identifier +// See Boards.txt for .name=Arduino Uno (16 MHz) +// +BOARD_TAG = teensy2 + +// Port (optionnal) +// most common are /dev/tty.usbserial*, /dev/tty.usbmodem* or /dev/tty.uart* +// +BOARD_PORT = /dev/tty.usbserial* + +// References for Xcode code-sense +// See Boards.txt for .build.mcu= +// +GCC_PREPROCESSOR_DEFINITIONS = __AVR_ATmega32U4__ TEENSYDUINO + +// Specify the full path and name of the application +// with /Contents/Resources/Java/** after +// +HEADER_SEARCH_PATHS = /Applications/Teensyduino.app/Contents/Resources/Java/** /Applications/Arduino.app/Contents/Resources/Java/** + +// Maximum RAM size in bytes +// given by .upload.maximum_ram_size in boards.txt for Maple and Teensy +// +//MAX_RAM_SIZE = diff --git a/FastLED/FastLED/Configurations/Teensy 3.0.xcconfig b/FastLED/FastLED/Configurations/Teensy 3.0.xcconfig new file mode 100755 index 00000000..cc13111a --- /dev/null +++ b/FastLED/FastLED/Configurations/Teensy 3.0.xcconfig @@ -0,0 +1,39 @@ +// +// Teensy 3.0.xcconfig +// Board configuration file +// ---------------------------------- +// Developed with embedXcode +// +// Part of embedXcode +// Embedded Computing on Xcode +// +// Created by Rei VILO on Nov 04, 2012 +// Copyright (c) 2012-2014 http://embedxcode.weebly.com +// License All rigths reserved +// +// Last update: Feb 06, 2014 release 131 + +// Board identifier +// See Boards.txt for .name=Arduino Uno (16 MHz) +// +BOARD_TAG = teensy3 + +// Port (optionnal) +// most common are /dev/tty.usbserial*, /dev/tty.usbmodem* or /dev/tty.uart* +// +BOARD_PORT = /dev/tty.usbmodem* + +// References for Xcode code-sense +// See Boards.txt for .build.mcu= +// +GCC_PREPROCESSOR_DEFINITIONS = __MK20DX128__ TEENSYDUINO + +// Specify the full path and name of the application +// with /Contents/Resources/Java/** after +// +HEADER_SEARCH_PATHS = /Applications/Teensyduino.app/Contents/Resources/Java/** /Applications/Arduino.app/Contents/Resources/Java/** + +// Maximum RAM size in bytes +// given by .upload.maximum_ram_size in boards.txt for Maple and Teensy +// +//MAX_RAM_SIZE = diff --git a/FastLED/FastLED/Configurations/Teensy 3.1.xcconfig b/FastLED/FastLED/Configurations/Teensy 3.1.xcconfig new file mode 100755 index 00000000..9396ecb3 --- /dev/null +++ b/FastLED/FastLED/Configurations/Teensy 3.1.xcconfig @@ -0,0 +1,39 @@ +// +// Teensy 3.1.xcconfig +// Board configuration file +// ---------------------------------- +// Developed with embedXcode +// +// Part of embedXcode +// Embedded Computing on Xcode +// +// Created by Rei VILO on Nov 04, 2012 +// Copyright (c) 2012-2014 http://embedxcode.weebly.com +// License All rigths reserved +// +// Last update: Feb 06, 2014 release 131 + +// Board identifier +// See Boards.txt for .name=Arduino Uno (16 MHz) +// +BOARD_TAG = teensy31 + +// Port (optionnal) +// most common are /dev/tty.usbserial*, /dev/tty.usbmodem* or /dev/tty.uart* +// +BOARD_PORT = /dev/tty.usbmodem* + +// References for Xcode code-sense +// See Boards.txt for .build.mcu= +// +GCC_PREPROCESSOR_DEFINITIONS = __MK20DX256__ TEENSYDUINO + +// Specify the full path and name of the application +// with /Contents/Resources/Java/** after +// +HEADER_SEARCH_PATHS = /Applications/Teensyduino.app/Contents/Resources/Java/** /Applications/Arduino.app/Contents/Resources/Java/** + +// Maximum RAM size in bytes +// given by .upload.maximum_ram_size in boards.txt for Maple and Teensy +// +//MAX_RAM_SIZE = diff --git a/FastLED/FastLED/Configurations/Wiring S.xcconfig b/FastLED/FastLED/Configurations/Wiring S.xcconfig new file mode 100755 index 00000000..17e892f3 --- /dev/null +++ b/FastLED/FastLED/Configurations/Wiring S.xcconfig @@ -0,0 +1,40 @@ +// +// Wiring S.xcconfig +// Board configuration file +// ---------------------------------- +// Developed with embedXcode +// +// Part of embedXcode +// Embedded Computing on Xcode +// +// Created by Rei VILO on Apr 05, 2012 +// Copyright (c) 2012-2014 http://embedxcode.weebly.com +// License All rights reserved +// +// Last update: Feb 06, 2014 release 131 + +// Board identifier +// See Boards.txt for .name=Arduino Uno (16 MHz) +// +BOARD_TAG = WiringS + +// Port (optionnal) +// most common are /dev/tty.usbserial*, /dev/tty.usbmodem* or /dev/tty.uart* +// +BOARD_PORT = /dev/tty.usbserial* + +// References for Xcode code-sense +// See Boards.txt for .build.mcu= +// +GCC_PREPROCESSOR_DEFINITIONS = __AVR_ATmega644P__ WIRING + +// Specify the full path and name of the application +// with /Contents/Resources/Java/** after +// +HEADER_SEARCH_PATHS = /Applications/Wiring.app/Contents/Resources/Java/** + +// Maximum RAM size in bytes +// given by .upload.maximum_ram_size in boards.txt for Maple and Teensy +// +MAX_RAM_SIZE = 4096 + diff --git a/FastLED/FastLED/Configurations/chipKIT Max32.xcconfig b/FastLED/FastLED/Configurations/chipKIT Max32.xcconfig new file mode 100644 index 00000000..abef05a1 --- /dev/null +++ b/FastLED/FastLED/Configurations/chipKIT Max32.xcconfig @@ -0,0 +1,40 @@ +// +// chipKIT Max32.xcconfig +// Board configuration file +// ---------------------------------- +// Developed with embedXcode +// +// Part of embedXcode +// Embedded Computing on Xcode +// +// Created by Rei VILO on Apr 21, 2013 +// Copyright (c) 2012-2014 http://embedxcode.weebly.com +// License All rigths reserved +// +// Last update: Feb 06, 2014 release 131 + +// Board identifier +// See Boards.txt for .name=Arduino Uno (16 MHz) +// +BOARD_TAG = mega_pic32 + +// Port (optionnal) +// most common are /dev/tty.usbserial*, /dev/tty.usbmodem* or /dev/tty.uart* +// +BOARD_PORT = /dev/tty.usbserial* + +// References for Xcode code-sense +// See Boards.txt for .build.mcu= +// +GCC_PREPROCESSOR_DEFINITIONS = __32MX795F512L__ MPIDE + +// Specify the full path and name of the application +// with /Contents/Resources/Java/** after +// +HEADER_SEARCH_PATHS = /Applications/Mpide.app/Contents/Resources/Java/** + +// Maximum RAM size in bytes +// given by .upload.maximum_ram_size in boards.txt for Maple and Teensy +// +MAX_RAM_SIZE = 131072 + diff --git a/FastLED/FastLED/Configurations/chipKIT Uno32.xcconfig b/FastLED/FastLED/Configurations/chipKIT Uno32.xcconfig new file mode 100755 index 00000000..a2664d9c --- /dev/null +++ b/FastLED/FastLED/Configurations/chipKIT Uno32.xcconfig @@ -0,0 +1,40 @@ +// +// chipKIT Uno32.xcconfig +// Board configuration file +// ---------------------------------- +// Developed with embedXcode +// +// Part of embedXcode +// Embedded Computing on Xcode +// +// Created by Rei VILO on Apr 08, 2012 +// Copyright (c) 2012-2014 http://embedxcode.weebly.com +// License All rigths reserved +// +// Last update: Feb 06, 2014 release 131 + +// Board identifier +// See Boards.txt for .name=Arduino Uno (16 MHz) +// +BOARD_TAG = uno_pic32 + +// Port (optionnal) +// most common are /dev/tty.usbserial*, /dev/tty.usbmodem* or /dev/tty.uart* +// +BOARD_PORT = /dev/tty.usbserial* + +// References for Xcode code-sense +// See Boards.txt for .build.mcu= +// +GCC_PREPROCESSOR_DEFINITIONS = __32MX320F128H__ MPIDE + +// Specify the full path and name of the application +// with /Contents/Resources/Java/** after +// +HEADER_SEARCH_PATHS = /Applications/Mpide.app/Contents/Resources/Java/** + +// Maximum RAM size in bytes +// given by .upload.maximum_ram_size in boards.txt for Maple and Teensy +// +MAX_RAM_SIZE = 16384 + diff --git a/FastLED/FastLED/Configurations/chipKIT uC32.xcconfig b/FastLED/FastLED/Configurations/chipKIT uC32.xcconfig new file mode 100644 index 00000000..4637a0bc --- /dev/null +++ b/FastLED/FastLED/Configurations/chipKIT uC32.xcconfig @@ -0,0 +1,45 @@ +// +// chipKIT Uno32.xcconfig +// Board configuration file +// ---------------------------------- +// Developed with embedXcode +// +// Part of embedXcode +// Embedded Computing on Xcode +// +// Created by John James on Apr 20, 2013 +// License All rigths reserved +// +// Maintained by Rei VILO on May 10, 2013 +// Copyright (c) 2012-2014 http://embedxcode.weebly.com +// License All rigths reserved +// +// Last update: Feb 06, 2014 release 131 + +// Board identifier +// See Boards.txt for .name=Arduino Uno (16 MHz) +// +BOARD_TAG = chipkit_uc32 + +// Port (optionnal) +// most common are /dev/tty.usbserial*, /dev/tty.usbmodem* or /dev/tty.uart* +// +BOARD_PORT = /dev/tty.usbserial* + +// References for Xcode code-sense +// See Boards.txt for .build.mcu= +// +GCC_PREPROCESSOR_DEFINITIONS = __32MX340F512H__ MPIDE + +// Specify the full path and name of the application +// with /Contents/Resources/Java/** after +// +HEADER_SEARCH_PATHS = /Applications/Mpide.app/Contents/Resources/Java/** + +// Maximum RAM size in bytes +// given by .upload.maximum_ram_size in boards.txt for Maple and Teensy +// +// Thanks Sinus! http://chipkit.net/forum/viewtopic.php?p=10932#p10932 +// +MAX_RAM_SIZE = 32768 + diff --git a/FastLED/FastLED/FastLED.ino b/FastLED/FastLED/FastLED.ino new file mode 100644 index 00000000..137eed39 --- /dev/null +++ b/FastLED/FastLED/FastLED.ino @@ -0,0 +1,91 @@ +// +// FastLED +// +// FastLED library drivers +// Developed with [embedXcode](http://embedXcode.weebly.com) +// +// Author Daniel Garcia +// Daniel Garcia +// +// Date 4/2/14 8:09 PM +// Version <#version#> +// +// Copyright © Daniel Garcia, 2014 +// License <#license#> +// +// See ReadMe.txt for references +// + +// Core library for code-sense +#if defined(WIRING) // Wiring specific +#include "Wiring.h" +#elif defined(MAPLE_IDE) // Maple specific +#include "WProgram.h" +#elif defined(MICRODUINO) // Microduino specific +#include "Arduino.h" +#elif defined(MPIDE) // chipKIT specific +#include "WProgram.h" +#elif defined(DIGISPARK) // Digispark specific +#include "Arduino.h" +#elif defined(ENERGIA) // LaunchPad MSP430, Stellaris and Tiva, Experimeter Board FR5739 specific +#include "Energia.h" +#elif defined(TEENSYDUINO) // Teensy specific +#include "Arduino.h" +#elif defined(ARDUINO) // Arduino 1.0 and 1.5 specific +#include "Arduino.h" +#else // error +#error Platform not defined +#endif + +// Include application, user and local libraries +#include "LocalLibrary.h" + + +// Prototypes + + +// Define variables and constants +// +// Brief Name of the LED +// Details Each board has a LED but connected to a different pin +// +uint8_t myLED; + + +// +// Brief Setup +// Details Define the pin the LED is connected to +// +// Add setup code +void setup() { + // myLED pin number +#if defined(__AVR_ATmega328P__) || defined(__AVR_ATmega2560__) || defined(__AVR_ATmega32U4__) || defined(__SAM3X8E__) // Arduino specific + myLED = 13; +#elif defined(__PIC32MX__) // chipKIT specific + myLED = 13; +#elif defined(__AVR_ATtinyX5__) // Digispark specific + myLED = 1; // assuming model A +#elif defined(__AVR_ATmega644P__) // Wiring specific + myLED = 15; +#elif defined(__MSP430G2452__) || defined(__MSP430G2553__) || defined(__MSP430G2231__) || defined(__MSP430F5529__) || defined(__MSP430FR5739__) // LaunchPad MSP430 and Experimeter Board FR5739 specific + myLED = RED_LED; +#elif defined(__LM4F120H5QR__) || defined(__TM4C1230C3PM__) // LaunchPad Stellaris and Tiva specific + myLED = RED_LED; +#elif defined(MCU_STM32F103RB) || defined(MCU_STM32F103ZE) || defined(MCU_STM32F103CB) || defined(MCU_STM32F103RE) // Maple specific + myLED = BOARD_LED_PIN; +#elif defined(__MK20DX128__) // Teensy 3.0 specific + myLED = 13; +#endif + + pinMode(myLED, OUTPUT); +} + +// +// Brief Loop +// Details Call blink +// +// Add loop code +void loop() { + blink(myLED, 3, 333); + delay(1000); +} diff --git a/FastLED/FastLED/LocalLibrary.cpp b/FastLED/FastLED/LocalLibrary.cpp new file mode 100644 index 00000000..d2b89b65 --- /dev/null +++ b/FastLED/FastLED/LocalLibrary.cpp @@ -0,0 +1,29 @@ +// +// LocalLibrary.cpp +// Library C++ code +// ---------------------------------- +// Developed with embedXcode +// http://embedXcode.weebly.com +// +// Project FastLED +// +// Created by Daniel Garcia, 4/2/14 8:09 PM +// Daniel Garcia +// +// Copyright © Daniel Garcia, 2014 +// License <#license#> +// +// See LocalLibrary.cpp.h and ReadMe.txt for references +// + + +#include "LocalLibrary.h" + +void blink(uint8_t pin, uint8_t times, uint16_t ms) { + for (uint8_t i=0; i> 1); + digitalWrite(pin, LOW); + delay(ms >> 1); + } +} diff --git a/FastLED/FastLED/LocalLibrary.h b/FastLED/FastLED/LocalLibrary.h new file mode 100644 index 00000000..ed0dc614 --- /dev/null +++ b/FastLED/FastLED/LocalLibrary.h @@ -0,0 +1,55 @@ +// +// File LocalLibrary.h +// Brief Library header +// +// Project FastLED +// Developed with [embedXcode](http://embedXcode.weebly.com) +// +// Author Daniel Garcia +// Daniel Garcia +// Date 4/2/14 8:09 PM +// Version <#version#> +// +// Copyright © Daniel Garcia, 2014 +// License <#license#> +// +// See ReadMe.txt for references +// + + +// Core library - IDE-based +#if defined(WIRING) // Wiring specific +#include "Wiring.h" +#elif defined(MAPLE_IDE) // Maple specific +#include "WProgram.h" +#elif defined(MPIDE) // chipKIT specific +#include "WProgram.h" +#elif defined(DIGISPARK) // Digispark specific +#include "Arduino.h" +#elif defined(ENERGIA) // LaunchPad MSP430 G2 and F5529, Stellaris and Tiva, Experimeter Board FR5739 specific +#include "Energia.h" +#elif defined(MICRODUINO) // Microduino specific +#include "Arduino.h" +#elif defined(TEENSYDUINO) // Teensy specific +#include "Arduino.h" +#elif defined(ARDUINO) // Arduino 1.0 and 1.5 specific +#include "Arduino.h" +#else // error +#error Platform not defined +#endif // end IDE + +#ifndef FastLED_LocalLibrary_h +#define FastLED_LocalLibrary_h + +// +// Brief Blink a LED +// Details LED attached to pin is light on then light off +// Total cycle duration = ms +// Parameters: +// pin pin to which the LED is attached +// times number of times +// ms cycle duration in ms +// +void blink(uint8_t pin, uint8_t times, uint16_t ms); + +#endif diff --git a/FastLED/FastLED/Makefile b/FastLED/FastLED/Makefile new file mode 100644 index 00000000..355c5d17 --- /dev/null +++ b/FastLED/FastLED/Makefile @@ -0,0 +1,80 @@ +# +# embedXcode +# ---------------------------------- +# Embedded Computing on Xcode +# +# Copyright © Rei VILO, 2010-2014 +# All rights reserved +# http://embedxcode.weebly.com +# +# Last update: Mar 01, 2014 release 136 + + +# Libraries +# ---------------------------------- +# Declare application Arduino/chipKIT/Digispark/Energia/Maple/Microduino/Teensy/Wiring +# and user's libraries used +# Short-listing libraries speeds-up building +# Typing = 0 takes none (default for application and user) +# Otherwise, leaving empty considers all + +# List application Arduino/chipKIT/Digispark/Energia/Maple/Microduino/Teensy/Wiring libraries here +# default = 0 = none +# +APP_LIBS_LIST = 0 + +# List user's libraries here +# default = 0 = none +# +USER_LIBS_LIST = 0 + +# List core, application and user's libraries to be excluded +# For example, WiFi may crash on Arduino 1.0.2, Esplora on Arduino 1.0.3, Firmata on Teensy 3.0, +# OneWire on MPIDE 0023, HardwareSerial may conflict with MarlinSerial +# +#EXCLUDE_LIBS = Firmata WiFi Esplora OneWire Robot_Control Robot_Control/utility Robot_Motor + + +# Parameters +# ---------------------------------- +# Xcode takes BOARD_TAG and BOARD_PORT from the .xcconfig file +# For other IDEs than Xcode, + +# BOARD_TAG is required +# If not defined, error BOARD_TAG not defined +# +#BOARD_TAG = mega2560 + +# BOARD_PORT is optional +# If not defined, BOARD_PORT = /dev/tty.usb* (default) +# +#BOARD_PORT = /dev/tty.usbmodem* + +# Xcode takes SKETCHBOOK_DIR from preferences.txt +# If not defined, each IDE has its own SKETCHBOOK_DIR (default) +# To share the same SKETCHBOOK_DIR along all IDEs, define +# +#SKETCHBOOK_DIR = + +# SERIAL_BAUDRATE for the serial console, 9600 by default +# Uncomment and specify another speed +# +#SERIAL_BAUDRATE = 19200 + + +# Miscellaneous +# ---------------------------------- +# Manage path with space in the name +# +CURRENT_DIR := $(shell pwd) +CURRENT_DIR := $(shell echo '$(CURRENT_DIR)' | sed 's/ /\\\ /g') + +# C-compliant project name +# +PROJECT_NAME_AS_IDENTIFIER = FastLED + +MAKEFILE_PATH = $(CURRENT_DIR)/Makefiles +UTILITIES_PATH = $(CURRENT_DIR)/Utilities + +include $(MAKEFILE_PATH)/Step1.mk + diff --git a/FastLED/FastLED/Makefiles/Arduino.mk b/FastLED/FastLED/Makefiles/Arduino.mk new file mode 100755 index 00000000..5d7dd4fc --- /dev/null +++ b/FastLED/FastLED/Makefiles/Arduino.mk @@ -0,0 +1,24 @@ +# +# embedXcode +# ---------------------------------- +# Embedded Computing on Xcode +# +# Copyright © Rei VILO, 2010-2014 +# http://embedxcode.weebly.com +# All rights reserved +# +# +# Last update: Jun 21, 2013 release 54 + + + +# Arduino specifics +# ---------------------------------- +# Automatic 0023 or 1.x.x selection based on version.txt +# +ifneq ($(shell grep 1. $(ARDUINO_PATH)/lib/version.txt),) + include $(MAKEFILE_PATH)/Arduino1.mk +else + include $(MAKEFILE_PATH)/Arduino23.mk +endif + diff --git a/FastLED/FastLED/Makefiles/Arduino1.mk b/FastLED/FastLED/Makefiles/Arduino1.mk new file mode 100755 index 00000000..67cd6490 --- /dev/null +++ b/FastLED/FastLED/Makefiles/Arduino1.mk @@ -0,0 +1,91 @@ +# +# embedXcode +# ---------------------------------- +# Embedded Computing on Xcode +# +# Copyright © Rei VILO, 2010-2014 +# http://embedxcode.weebly.com +# All rights reserved +# +# +# Last update: Jun 21, 2013 release 54 + + + +# Arduino 1.0.x specifics +# ---------------------------------- +# +PLATFORM := Arduino +PLATFORM_TAG = ARDUINO=105 EMBEDXCODE=$(RELEASE_NOW) +APPLICATION_PATH := $(ARDUINO_PATH) + +APP_TOOLS_PATH := $(APPLICATION_PATH)/hardware/tools/avr/bin +CORE_LIB_PATH := $(APPLICATION_PATH)/hardware/arduino/cores/arduino +APP_LIB_PATH := $(APPLICATION_PATH)/libraries +BOARDS_TXT := $(APPLICATION_PATH)/hardware/arduino/boards.txt + +# Sketchbook/Libraries path +# wildcard required for ~ management +# +ifeq ($(USER_PATH)/Library/Arduino/preferences.txt,) + $(error Error: run Arduino once and define the sketchbook path) +endif + +ifeq ($(wildcard $(SKETCHBOOK_DIR)),) + SKETCHBOOK_DIR = $(shell grep sketchbook.path $(USER_PATH)/Library/Arduino/preferences.txt | cut -d = -f 2) +endif +ifeq ($(wildcard $(SKETCHBOOK_DIR)),) + $(error Error: sketchbook path not found) +endif +USER_LIB_PATH = $(wildcard $(SKETCHBOOK_DIR)/?ibraries) + +# Rules for making a c++ file from the main sketch (.pde) +# +PDEHEADER = \\\#include \"Arduino.h\" + +# Tool-chain names +# +CC = $(APP_TOOLS_PATH)/avr-gcc +CXX = $(APP_TOOLS_PATH)/avr-g++ +AR = $(APP_TOOLS_PATH)/avr-ar +OBJDUMP = $(APP_TOOLS_PATH)/avr-objdump +OBJCOPY = $(APP_TOOLS_PATH)/avr-objcopy +SIZE = $(APP_TOOLS_PATH)/avr-size +NM = $(APP_TOOLS_PATH)/avr-nm + +# Specific AVRDUDE location and options +# +AVRDUDE_COM_OPTS = -D -p$(MCU) -C$(AVRDUDE_CONF) + +BOARD = $(call PARSE_BOARD,$(BOARD_TAG),board) +#LDSCRIPT = $(call PARSE_BOARD,$(BOARD_TAG),ldscript) +VARIANT = $(call PARSE_BOARD,$(BOARD_TAG),build.variant) +VARIANT_PATH = $(APPLICATION_PATH)/hardware/arduino/variants/$(VARIANT) + +MCU_FLAG_NAME = mmcu +EXTRA_LDFLAGS = +EXTRA_CPPFLAGS = -MMD -I$(VARIANT_PATH) $(addprefix -D, $(PLATFORM_TAG)) + +# Leonardo USB PID VID +# +USB_TOUCH := $(call PARSE_BOARD,$(BOARD_TAG),upload.protocol) +USB_VID := $(call PARSE_BOARD,$(BOARD_TAG),build.vid) +USB_PID := $(call PARSE_BOARD,$(BOARD_TAG),build.pid) + +ifneq ($(USB_PID),) + USB_FLAGS += -DUSB_PID=$(USB_PID) +else + USB_FLAGS += -DUSB_PID=null +endif + +ifneq ($(USB_VID),) + USB_FLAGS += -DUSB_VID=$(USB_VID) +else + USB_FLAGS += -DUSB_VID=null +endif + +# Serial 1200 reset +# +ifeq ($(USB_TOUCH),avr109) + USB_RESET = $(UTILITIES_PATH)/serial1200.py +endif diff --git a/FastLED/FastLED/Makefiles/Arduino15avr.mk b/FastLED/FastLED/Makefiles/Arduino15avr.mk new file mode 100755 index 00000000..f3b6d836 --- /dev/null +++ b/FastLED/FastLED/Makefiles/Arduino15avr.mk @@ -0,0 +1,199 @@ +# +# embedXcode +# ---------------------------------- +# Embedded Computing on Xcode +# +# Copyright © Rei VILO, 2010-2014 +# http://embedxcode.weebly.com +# All rights reserved +# +# +# Last update: Feb 10, 2014 release 132 + +# ARDUINO 1.5.X IS STILL IN BETA, UNSTABLE AND PRONE TO BUGS +WARNING_MESSAGE = 'ARDUINO 1.5.X IS STILL IN BETA, UNSTABLE AND PRONE TO BUGS' + + +# Arduino 1.5.x AVR specifics +# ---------------------------------- +# +PLATFORM := Arduino +BUILD_CORE := avr +PLATFORM_TAG = ARDUINO=155 ARDUINO_ARCH_AVR EMBEDXCODE=$(RELEASE_NOW) +APPLICATION_PATH := $(ARDUINO_PATH) + +APP_TOOLS_PATH := $(APPLICATION_PATH)/hardware/tools/avr/bin +CORE_LIB_PATH := $(APPLICATION_PATH)/hardware/arduino/avr/cores/arduino +APP_LIB_PATH := $(APPLICATION_PATH)/libraries +BOARDS_TXT := $(APPLICATION_PATH)/hardware/arduino/avr/boards.txt + +# Sketchbook/Libraries path +# wildcard required for ~ management +# ?ibraries required for libraries and Libraries +# +ifeq ($(USER_PATH)/Library/Arduino/preferences.txt,) + $(error Error: run Arduino once and define the sketchbook path) +endif + +ifeq ($(wildcard $(SKETCHBOOK_DIR)),) + SKETCHBOOK_DIR = $(shell grep sketchbook.path $(USER_PATH)/Library/Arduino15/preferences.txt | cut -d = -f 2) +endif +ifeq ($(wildcard $(SKETCHBOOK_DIR)),) + $(error Error: sketchbook path not found) +endif +USER_LIB_PATH = $(wildcard $(SKETCHBOOK_DIR)/?ibraries) + +# Rules for making a c++ file from the main sketch (.pde) +# +PDEHEADER = \\\#include \"Arduino.h\" + +# Tool-chain names +# +CC = $(APP_TOOLS_PATH)/avr-gcc +CXX = $(APP_TOOLS_PATH)/avr-g++ +AR = $(APP_TOOLS_PATH)/avr-ar +OBJDUMP = $(APP_TOOLS_PATH)/avr-objdump +OBJCOPY = $(APP_TOOLS_PATH)/avr-objcopy +SIZE = $(APP_TOOLS_PATH)/avr-size +NM = $(APP_TOOLS_PATH)/avr-nm + + +# Complicated menu system for Arduino 1.5 +# Another example of Arduino's quick and dirty job +# +MCU := $(call PARSE_BOARD,$(BOARD_TAG),build.mcu) +ifeq ($(MCU),) + MCU := $(call PARSE_BOARD,$(BOARD_TAG1),build.mcu) + ifeq ($(MCU),) + MCU := $(call PARSE_BOARD,$(BOARD_TAG2),build.mcu) + endif +endif + +F_CPU := $(call PARSE_BOARD,$(BOARD_TAG),build.f_cpu) +ifeq ($(F_CPU),) + F_CPU := $(call PARSE_BOARD,$(BOARD_TAG1),build.f_cpu) + ifeq ($(F_CPU),) + F_CPU := $(call PARSE_BOARD,$(BOARD_TAG2),build.f_cpu) + endif +endif + +BOARD_NAME := $(call PARSE_BOARD,$(BOARD_TAG),name) +ifeq ($(BOARD_NAME),) + BOARD_NAME := $(call PARSE_BOARD,$(BOARD_TAG1),name) + ifeq ($(BOARD_NAME),) + BOARD_NAME := $(call PARSE_BOARD,$(BOARD_TAG2),name) + endif +endif + +MAX_FLASH_SIZE := $(call PARSE_BOARD,$(BOARD_TAG),upload.maximum_size) +ifeq ($(MAX_FLASH_SIZE),) + MAX_FLASH_SIZE := $(call PARSE_BOARD,$(BOARD_TAG1),upload.maximum_size) + ifeq ($(MAX_FLASH_SIZE),) + MAX_FLASH_SIZE := $(call PARSE_BOARD,$(BOARD_TAG2),upload.maximum_size) + endif +endif + +AVRDUDE_BAUDRATE := $(call PARSE_BOARD,$(BOARD_TAG),upload.speed) +ifeq ($(AVRDUDE_BAUDRATE),) + AVRDUDE_BAUDRATE := $(call PARSE_BOARD,$(BOARD_TAG1),upload.speed) + ifeq ($(AVRDUDE_BAUDRATE),) + AVRDUDE_BAUDRATE := $(call PARSE_BOARD,$(BOARD_TAG2),upload.speed) + endif +endif + +AVRDUDE_PROGRAMMER := $(call PARSE_BOARD,$(BOARD_TAG),upload.protocol) +ifeq ($(AVRDUDE_PROGRAMMER),) + AVRDUDE_PROGRAMMER := $(call PARSE_BOARD,$(BOARD_TAG1),upload.protocol) + ifeq ($(AVRDUDE_PROGRAMMER),) + AVRDUDE_PROGRAMMER := $(call PARSE_BOARD,$(BOARD_TAG2),upload.protocol) + endif +endif + + + +#ifeq ($(BOARD_TAG2),) +# MCU = $(call PARSE_BOARD,$(BOARD_TAG),build.mcu) +# F_CPU = $(call PARSE_BOARD,$(BOARD_TAG),build.f_cpu) +#else +# MCU = $(call PARSE_BOARD,$(BOARD_TAG2),build.mcu) +# F_CPU = $(call PARSE_BOARD,$(BOARD_TAG2),build.f_cpu) +#endif + +# Specific AVRDUDE location and options +# +AVRDUDE_COM_OPTS = -D -p$(MCU) -C$(AVRDUDE_CONF) + +ifneq ($(BOARD_TAG1),) +#BOARD = $(call PARSE_BOARD,$(BOARD_TAG1),board) +#LDSCRIPT = $(call PARSE_BOARD,$(BOARD_TAG1),ldscript) +VARIANT = $(call PARSE_BOARD,$(BOARD_TAG1),build.variant) +VARIANT_PATH = $(APPLICATION_PATH)/hardware/arduino/avr/variants/$(VARIANT) +else +#BOARD = $(call PARSE_BOARD,$(BOARD_TAG),board) +#LDSCRIPT = $(call PARSE_BOARD,$(BOARD_TAG),ldscript) +VARIANT = $(call PARSE_BOARD,$(BOARD_TAG),build.variant) +VARIANT_PATH = $(APPLICATION_PATH)/hardware/arduino/avr/variants/$(VARIANT) +endif + +# Two locations for Arduino libraries +# +BUILD_APP_LIB_PATH = $(APPLICATION_PATH)/hardware/arduino/$(BUILD_CORE)/libraries + +ifndef APP_LIBS_LIST + w1 = $(realpath $(sort $(dir $(wildcard $(APP_LIB_PATH)/*/*.h $(APP_LIB_PATH)/*/*/*.h)))) # */ + APP_LIBS_LIST = $(subst $(APP_LIB_PATH)/,,$(filter-out $(EXCLUDE_LIST),$(w1))) + + w2 = $(realpath $(sort $(dir $(wildcard $(BUILD_APP_LIB_PATH)/*/*.h $(BUILD_APP_LIB_PATH)/*/*/*.h)))) # */ + BUILD_APP_LIBS_LIST = $(subst $(BUILD_APP_LIB_PATH)/,,$(filter-out $(EXCLUDE_LIST),$(w2))) +else + w2 = $(realpath $(sort $(dir $(wildcard $(BUILD_APP_LIB_PATH)/*/*.h $(BUILD_APP_LIB_PATH)/*/*/*.h)))) # */ + BUILD_APP_LIBS_LIST = $(subst $(BUILD_APP_LIB_PATH)/,,$(filter-out $(EXCLUDE_LIST),$(w2))) +endif + + +# Arduino 1.5.x nightmare with src and arch/sam or arch/avr +# +ifneq ($(APP_LIBS_LIST),0) + APP_LIBS = $(patsubst %,$(APP_LIB_PATH)/%/src,$(APP_LIBS_LIST)) + APP_LIBS += $(patsubst %,$(APP_LIB_PATH)/%/arch/$(BUILD_CORE),$(APP_LIBS_LIST)) + + APP_LIB_CPP_SRC = $(wildcard $(patsubst %,%/*.cpp,$(APP_LIBS))) # */ + APP_LIB_C_SRC = $(wildcard $(patsubst %,%/*.c,$(APP_LIBS))) # */ + + APP_LIB_OBJS = $(patsubst $(APP_LIB_PATH)/%.cpp,$(OBJDIR)/libs/%.o,$(APP_LIB_CPP_SRC)) + APP_LIB_OBJS += $(patsubst $(APP_LIB_PATH)/%.c,$(OBJDIR)/libs/%.o,$(APP_LIB_C_SRC)) + + BUILD_APP_LIBS = $(patsubst %,$(BUILD_APP_LIB_PATH)/%,$(BUILD_APP_LIBS_LIST)) + + BUILD_APP_LIB_CPP_SRC = $(wildcard $(patsubst %,%/*.cpp,$(BUILD_APP_LIBS))) # */ + BUILD_APP_LIB_C_SRC = $(wildcard $(patsubst %,%/*.c,$(BUILD_APP_LIBS))) # */ + + BUILD_APP_LIB_OBJS = $(patsubst $(BUILD_APP_LIB_PATH)/%.cpp,$(OBJDIR)/libs/%.o,$(BUILD_APP_LIB_CPP_SRC)) + BUILD_APP_LIB_OBJS += $(patsubst $(BUILD_APP_LIB_PATH)/%.c,$(OBJDIR)/libs/%.o,$(BUILD_APP_LIB_C_SRC)) +endif + + +MCU_FLAG_NAME = mmcu +EXTRA_LDFLAGS = +EXTRA_CPPFLAGS = -I$(VARIANT_PATH) $(addprefix -D, $(PLATFORM_TAG)) + + +# Arduino Leonardo USB PID VID +# +USB_VID := $(call PARSE_BOARD,$(BOARD_TAG),build.vid) +USB_PID := $(call PARSE_BOARD,$(BOARD_TAG),build.pid) + +ifneq ($(USB_PID),) +ifneq ($(USB_VID),) + USB_FLAGS = -DUSB_VID=$(USB_VID) + USB_FLAGS += -DUSB_PID=$(USB_PID) +endif +endif + +# Arduino Leonardo serial 1200 reset +# +USB_TOUCH := $(call PARSE_BOARD,$(BOARD_TAG),upload.protocol) + +ifeq ($(USB_TOUCH),avr109) + USB_RESET = $(UTILITIES_PATH)/serial1200.py +endif diff --git a/FastLED/FastLED/Makefiles/Arduino15sam.mk b/FastLED/FastLED/Makefiles/Arduino15sam.mk new file mode 100755 index 00000000..4ac899eb --- /dev/null +++ b/FastLED/FastLED/Makefiles/Arduino15sam.mk @@ -0,0 +1,157 @@ +# +# embedXcode +# ---------------------------------- +# Embedded Computing on Xcode +# +# Copyright © Rei VILO, 2010-2014 +# http://embedxcode.weebly.com +# All rights reserved +# +# +# Last update: Feb 10, 2014 release 132 + +# ARDUINO 1.5.X IS STILL IN BETA, UNSTABLE AND PRONE TO BUGS +WARNING_MESSAGE = 'ARDUINO 1.5.X IS STILL IN BETA, UNSTABLE AND PRONE TO BUGS' + + +# Arduino 1.5.x SAM specifics +# ---------------------------------- +# +PLATFORM := Arduino +BUILD_CORE := sam +PLATFORM_TAG = ARDUINO=155 ARDUINO_ARCH_SAM EMBEDXCODE=$(RELEASE_NOW) +APPLICATION_PATH := $(ARDUINO_PATH) + +APP_TOOLS_PATH := $(APPLICATION_PATH)/hardware/tools/g++_arm_none_eabi/bin +CORE_LIB_PATH := $(APPLICATION_PATH)/hardware/arduino/sam/cores/arduino +APP_LIB_PATH := $(APPLICATION_PATH)/libraries +BOARDS_TXT := $(APPLICATION_PATH)/hardware/arduino/sam/boards.txt + +# +# Uploader bossac +# Tested by Mike Roberts +# +UPLOADER = bossac +BOSSAC_PATH = $(APPLICATION_PATH)/hardware/tools +BOSSAC = $(BOSSAC_PATH)/bossac +BOSSAC_PORT = $(subst /dev/,,$(AVRDUDE_PORT)) +BOSSAC_OPTS = --port=$(BOSSAC_PORT) -U false -e -w -v -b + +# Sketchbook/Libraries path +# wildcard required for ~ management +# ?ibraries required for libraries and Libraries +# +ifeq ($(USER_PATH)/Library/Arduino/preferences.txt,) + $(error Error: run Arduino once and define the sketchbook path) +endif + +ifeq ($(wildcard $(SKETCHBOOK_DIR)),) + SKETCHBOOK_DIR = $(shell grep sketchbook.path $(USER_PATH)/Library/Arduino15/preferences.txt | cut -d = -f 2) +endif + +ifeq ($(wildcard $(SKETCHBOOK_DIR)),) + $(error Error: sketchbook path not found) +endif + +USER_LIB_PATH = $(wildcard $(SKETCHBOOK_DIR)/?ibraries) + +# Rules for making a c++ file from the main sketch (.pde) +# +PDEHEADER = \\\#include \"Arduino.h\" + +# Tool-chain names +# +CC = $(APP_TOOLS_PATH)/arm-none-eabi-gcc +CXX = $(APP_TOOLS_PATH)/arm-none-eabi-g++ +AR = $(APP_TOOLS_PATH)/arm-none-eabi-ar +OBJDUMP = $(APP_TOOLS_PATH)/arm-none-eabi-objdump +OBJCOPY = $(APP_TOOLS_PATH)/arm-none-eabi-objcopy +SIZE = $(APP_TOOLS_PATH)/arm-none-eabi-size +NM = $(APP_TOOLS_PATH)/arm-none-eabi-nm + +# Specific AVRDUDE location and options +# +AVRDUDE_COM_OPTS = -D -p$(MCU) -C$(AVRDUDE_CONF) + +BOARD = $(call PARSE_BOARD,$(BOARD_TAG),board) +LDSCRIPT = $(call PARSE_BOARD,$(BOARD_TAG),build.ldscript) +VARIANT = $(call PARSE_BOARD,$(BOARD_TAG),build.variant) +VARIANT_PATH = $(APPLICATION_PATH)/hardware/arduino/sam/variants/$(VARIANT) +VARIANT_CPP_SRCS = $(wildcard $(VARIANT_PATH)/*.cpp) # */ $(VARIANT_PATH)/*/*.cpp #*/ +VARIANT_OBJ_FILES = $(VARIANT_CPP_SRCS:.cpp=.o) +VARIANT_OBJS = $(patsubst $(VARIANT_PATH)/%,$(OBJDIR)/%,$(VARIANT_OBJ_FILES)) + +SYSTEM_LIB = $(call PARSE_BOARD,$(BOARD_TAG),build.variant_system_lib) +SYSTEM_PATH = $(VARIANT_PATH) +SYSTEM_OBJS = $(SYSTEM_PATH)/$(SYSTEM_LIB) + + +# Two locations for Arduino libraries +# +BUILD_APP_LIB_PATH = $(APPLICATION_PATH)/hardware/arduino/$(BUILD_CORE)/libraries + +ifndef APP_LIBS_LIST + w1 = $(realpath $(sort $(dir $(wildcard $(APP_LIB_PATH)/*/*.h $(APP_LIB_PATH)/*/*/*.h)))) # */ + APP_LIBS_LIST = $(subst $(APP_LIB_PATH)/,,$(filter-out $(EXCLUDE_LIST),$(w1))) + + w2 = $(realpath $(sort $(dir $(wildcard $(BUILD_APP_LIB_PATH)/*/*.h $(BUILD_APP_LIB_PATH)/*/*/*.h)))) # */ + BUILD_APP_LIBS_LIST = $(subst $(BUILD_APP_LIB_PATH)/,,$(filter-out $(EXCLUDE_LIST),$(w2))) +else + w2 = $(realpath $(sort $(dir $(wildcard $(BUILD_APP_LIB_PATH)/*/*.h $(BUILD_APP_LIB_PATH)/*/*/*.h)))) # */ + BUILD_APP_LIBS_LIST = $(subst $(BUILD_APP_LIB_PATH)/,,$(filter-out $(EXCLUDE_LIST),$(w2))) +endif + + +# Arduino 1.5.x nightmare with src and arch/sam or arch/avr +# Another example of Arduino's quick and dirty job +# +ifneq ($(APP_LIBS_LIST),0) + APP_LIBS = $(patsubst %,$(APP_LIB_PATH)/%/src,$(APP_LIBS_LIST)) + APP_LIBS += $(patsubst %,$(APP_LIB_PATH)/%/arch/$(BUILD_CORE),$(APP_LIBS_LIST)) + + APP_LIB_CPP_SRC = $(wildcard $(patsubst %,%/*.cpp,$(APP_LIBS))) # */ + APP_LIB_C_SRC = $(wildcard $(patsubst %,%/*.c,$(APP_LIBS))) # */ + + APP_LIB_OBJS = $(patsubst $(APP_LIB_PATH)/%.cpp,$(OBJDIR)/libs/%.o,$(APP_LIB_CPP_SRC)) + APP_LIB_OBJS += $(patsubst $(APP_LIB_PATH)/%.c,$(OBJDIR)/libs/%.o,$(APP_LIB_C_SRC)) + + BUILD_APP_LIBS = $(patsubst %,$(BUILD_APP_LIB_PATH)/%,$(BUILD_APP_LIBS_LIST)) + + BUILD_APP_LIB_CPP_SRC = $(wildcard $(patsubst %,%/*.cpp,$(BUILD_APP_LIBS))) # */ + BUILD_APP_LIB_C_SRC = $(wildcard $(patsubst %,%/*.c,$(BUILD_APP_LIBS))) # */ + + BUILD_APP_LIB_OBJS = $(patsubst $(BUILD_APP_LIB_PATH)/%.cpp,$(OBJDIR)/libs/%.o,$(BUILD_APP_LIB_CPP_SRC)) + BUILD_APP_LIB_OBJS += $(patsubst $(BUILD_APP_LIB_PATH)/%.c,$(OBJDIR)/libs/%.o,$(BUILD_APP_LIB_C_SRC)) +endif + +SYSTEM_FLAGS = -I$(APPLICATION_PATH)/hardware/arduino/sam/system/libsam +SYSTEM_FLAGS += -I$(APPLICATION_PATH)/hardware/arduino/sam/system/libsam/include +SYSTEM_FLAGS += -I$(APPLICATION_PATH)/hardware/arduino/sam/system/CMSIS/CMSIS/Include/ +SYSTEM_FLAGS += -I$(APPLICATION_PATH)/hardware/arduino/sam/system/CMSIS/Device/ATMEL/ + +MCU_FLAG_NAME = mcpu +EXTRA_LDFLAGS = -T$(VARIANT_PATH)/$(LDSCRIPT) -Wl,-Map,Builds/embeddedcomputing.map $(VARIANT_OBJS) +EXTRA_LDFLAGS += -lgcc -mthumb -Wl,--cref -Wl,--check-sections -Wl,--gc-sections -Wl,--entry=Reset_Handler +EXTRA_LDFLAGS += -Wl,--unresolved-symbols=report-all -Wl,--warn-common -Wl,--warn-section-align +EXTRA_LDFLAGS += -Wl,--warn-unresolved-symbols + +EXTRA_CPPFLAGS = -I$(VARIANT_PATH) $(addprefix -D, $(PLATFORM_TAG)) -D__SAM3X8E__ -mthumb -fno-rtti +EXTRA_CPPFLAGS += -nostdlib --param max-inline-insns-single=500 -Dprintf=iprintf $(SYSTEM_FLAGS) + +OBJCOPYFLAGS = -v -Obinary +TARGET_HEXBIN = $(TARGET_BIN) + +# Arduino Due USB PID VID +# +USB_VID := $(call PARSE_BOARD,$(BOARD_TAG),build.vid) +USB_PID := $(call PARSE_BOARD,$(BOARD_TAG),build.pid) + +USB_FLAGS = -DUSB_VID=$(USB_VID) +USB_FLAGS += -DUSB_PID=$(USB_PID) +USB_FLAGS += -DUSBCON + +# Arduino Due serial 1200 reset +# +USB_TOUCH := $(call PARSE_BOARD,$(BOARD_TAG),upload.protocol) +USB_RESET = $(UTILITIES_PATH)/serial1200.py + diff --git a/FastLED/FastLED/Makefiles/Arduino23.mk b/FastLED/FastLED/Makefiles/Arduino23.mk new file mode 100755 index 00000000..828fbbe1 --- /dev/null +++ b/FastLED/FastLED/Makefiles/Arduino23.mk @@ -0,0 +1,69 @@ +# +# embedXcode +# ---------------------------------- +# Embedded Computing on Xcode +# +# Copyright © Rei VILO, 2010-2014 +# http://embedxcode.weebly.com +# All rights reserved +# +# +# Last update: Apr 28, 2013 release 47 + +# ARDUINO 0023 IS NO LONGER SUPPORTED +WARNING_MESSAGE = 'WARNING_MESSAGE - ARDUINO 0023 IS NO LONGER SUPPORTED' + + +# Arduino 0023 specifics +# ---------------------------------- +# +PLATFORM := Arduino +PLATFORM_TAG = ARDUINO=23 EMBEDXCODE=$(RELEASE_NOW) +APPLICATION_PATH := $(ARDUINO_PATH) + +APP_TOOLS_PATH := $(APPLICATION_PATH)/hardware/tools/avr/bin +CORE_LIB_PATH := $(APPLICATION_PATH)/hardware/arduino/cores/arduino +APP_LIB_PATH := $(APPLICATION_PATH)/libraries +BOARDS_TXT := $(APPLICATION_PATH)/hardware/arduino/boards.txt + +# Sketchbook/Libraries path +# wildcard required for ~ management +# ?ibraries required for libraries and Libraries +# +ifeq ($(USER_PATH)/Library/Arduino/preferences.txt,) + $(error Error: run Arduino once and define the sketchbook path) +endif + +ifeq ($(wildcard $(SKETCHBOOK_DIR)),) + SKETCHBOOK_DIR = $(shell grep sketchbook.path $(USER_PATH)/Library/Arduino/preferences.txt | cut -d = -f 2) +endif +ifeq ($(wildcard $(SKETCHBOOK_DIR)),) + $(error Error: sketchbook path not found) +endif +USER_LIB_PATH = $(wildcard $(SKETCHBOOK_DIR)/?ibraries) + +# Rules for making a c++ file from the main sketch (.pde) +# +PDEHEADER = \\\#include \"WProgram.h\" + +# Tool-chain names +# +CC = $(APP_TOOLS_PATH)/avr-gcc +CXX = $(APP_TOOLS_PATH)/avr-g++ +AR = $(APP_TOOLS_PATH)/avr-ar +OBJDUMP = $(APP_TOOLS_PATH)/avr-objdump +OBJCOPY = $(APP_TOOLS_PATH)/avr-objcopy +SIZE = $(APP_TOOLS_PATH)/avr-size +NM = $(APP_TOOLS_PATH)/avr-nm + + +BOARD = $(call PARSE_BOARD,$(BOARD_TAG),board) +#LDSCRIPT = $(call PARSE_BOARD,$(BOARD_TAG),ldscript) +#VARIANT = $(call PARSE_BOARD,$(BOARD_TAG),build.variant) + +MCU_FLAG_NAME = mmcu +EXTRA_LDFLAGS = +EXTRA_CPPFLAGS = $(addprefix -D, $(PLATFORM_TAG)) + + + diff --git a/FastLED/FastLED/Makefiles/Avrdude.mk b/FastLED/FastLED/Makefiles/Avrdude.mk new file mode 100755 index 00000000..9ec70336 --- /dev/null +++ b/FastLED/FastLED/Makefiles/Avrdude.mk @@ -0,0 +1,93 @@ +# +# embedXcode +# ---------------------------------- +# Embedded Computing on Xcode +# +# Copyright © Rei VILO, 2010-2014 +# http://embedxcode.weebly.com +# All rights reserved +# +# +# Last update: Nov 04, 2013 release 112 + + + +# AVRDUDE +# ---------------------------------- +# +# First /dev port +# +# Port is no longer managed here but AVRDUDE_PORT is required for serial console +# +AVRDUDE_PORT = $(firstword $(wildcard $(BOARD_PORT))) + +ifndef AVRDUDE_PATH + AVRDUDE_PATH = $(APPLICATION_PATH)/hardware/tools/avr +endif + +ifndef AVRDUDE + AVRDUDE_EXEC = $(AVRDUDE_PATH)/bin/avrdude +endif + +ifndef AVRDUDE_CONF + AVRDUDE_CONF = $(AVRDUDE_PATH)/etc/avrdude.conf +endif + +ifndef AVRDUDE_COM_OPTS + AVRDUDE_COM_OPTS = -q -V -F -p$(MCU) -C$(AVRDUDE_CONF) +endif + +ifndef AVRDUDE_OPTS +# AVRDUDE_OPTS = -c$(AVRDUDE_PROGRAMMER) -b$(AVRDUDE_BAUDRATE) -P$(AVRDUDE_PORT) + AVRDUDE_OPTS = -c$(AVRDUDE_PROGRAMMER) -b$(AVRDUDE_BAUDRATE) +endif + +ifndef AVRDUDE_MCU + AVRDUDE_MCU = $(MCU) +endif + +ifndef ISP_PROG + ISP_PROG = -c stk500v2 +endif + +ifneq ($(ISP_PORT),) + AVRDUDE_ISP_OPTS = -P $(ISP_PORT) $(ISP_PROG) +else + AVRDUDE_ISP_OPTS = $(ISP_PROG) +endif + +# normal programming info +# +ifndef AVRDUDE_PROGRAMMER + AVRDUDE_PROGRAMMER = $(call PARSE_BOARD,$(BOARD_TAG),upload.protocol) +endif + +ifndef AVRDUDE_BAUDRATE + AVRDUDE_BAUDRATE = $(call PARSE_BOARD,$(BOARD_TAG),upload.speed) +endif + +# fuses if you're using e.g. ISP +# +ifndef ISP_LOCK_FUSE_PRE + ISP_LOCK_FUSE_PRE = $(call PARSE_BOARD,$(BOARD_TAG),bootloader.unlock_bits) +endif + +ifndef ISP_LOCK_FUSE_POST + ISP_LOCK_FUSE_POST = $(call PARSE_BOARD,$(BOARD_TAG),bootloader.lock_bits) +endif + +ifndef ISP_HIGH_FUSE + ISP_HIGH_FUSE = $(call PARSE_BOARD,$(BOARD_TAG),bootloader.high_fuses) +endif + +ifndef ISP_LOW_FUSE + ISP_LOW_FUSE = $(call PARSE_BOARD,$(BOARD_TAG),bootloader.low_fuses) +endif + +ifndef ISP_EXT_FUSE + ISP_EXT_FUSE = $(call PARSE_BOARD,$(BOARD_TAG),bootloader.extended_fuses) +endif + +ifndef VARIANT + VARIANT = $(call PARSE_BOARD,$(BOARD_TAG),build.variant) +endif diff --git a/FastLED/FastLED/Makefiles/Digispark.mk b/FastLED/FastLED/Makefiles/Digispark.mk new file mode 100755 index 00000000..8c6003fa --- /dev/null +++ b/FastLED/FastLED/Makefiles/Digispark.mk @@ -0,0 +1,132 @@ +# +# embedXcode +# ---------------------------------- +# Embedded Computing on Xcode +# +# Copyright © Rei VILO, 2010-2014 +# http://embedxcode.weebly.com +# All rights reserved +# +# +# Last update: Apr 28, 2013 release 47 + + + +# Digistark 1.04 AVR specifics +# ---------------------------------- +# +PLATFORM := Digistark +BUILD_CORE := avr +PLATFORM_TAG = ARDUINO=105 DIGISPARK EMBEDXCODE=$(RELEASE_NOW) +APPLICATION_PATH := $(DIGISPARK_PATH) + +APP_TOOLS_PATH := $(APPLICATION_PATH)/hardware/tools/avr/bin +CORE_LIB_PATH := $(APPLICATION_PATH)/hardware/digispark/cores/tiny +APP_LIB_PATH := $(APPLICATION_PATH)/libraries +BOARDS_TXT := $(APPLICATION_PATH)/hardware/digispark/boards.txt + +# +# Uploader bossac +# +UPLOADER = micronucleus + + +# Sketchbook/Libraries path +# wildcard required for ~ management +# ?ibraries required for libraries and Libraries +# +ifeq ($(USER_PATH)/Library/Arduino/preferences.txt,) + $(error Error: run Arduino once and define the sketchbook path) +endif + +ifeq ($(wildcard $(SKETCHBOOK_DIR)),) + SKETCHBOOK_DIR = $(shell grep sketchbook.path $(USER_PATH)/Library/Arduino/preferences.txt | cut -d = -f 2) +endif +ifeq ($(wildcard $(SKETCHBOOK_DIR)),) + $(error Error: sketchbook path not found) +endif +USER_LIB_PATH = $(wildcard $(SKETCHBOOK_DIR)/?ibraries) + +# Rules for making a c++ file from the main sketch (.pde) +# +PDEHEADER = \\\#include \"Arduino.h\" + +# Tool-chain names +# +CC = $(APP_TOOLS_PATH)/avr-gcc +CXX = $(APP_TOOLS_PATH)/avr-g++ +AR = $(APP_TOOLS_PATH)/avr-ar +OBJDUMP = $(APP_TOOLS_PATH)/avr-objdump +OBJCOPY = $(APP_TOOLS_PATH)/avr-objcopy +SIZE = $(APP_TOOLS_PATH)/avr-size +NM = $(APP_TOOLS_PATH)/avr-nm + +# Specific AVRDUDE location and options +# +AVRDUDE_COM_OPTS = -D -p$(MCU) -C$(AVRDUDE_CONF) + +BOARD = $(call PARSE_BOARD,$(BOARD_TAG),board) +#LDSCRIPT = $(call PARSE_BOARD,$(BOARD_TAG),ldscript) +#VARIANT = $(call PARSE_BOARD,$(BOARD_TAG),build.variant) +#VARIANT_PATH = $(APPLICATION_PATH)/hardware/arduino/avr/variants/$(VARIANT) + + +# Two locations for Arduino libraries +# +BUILD_APP_LIB_PATH = $(APPLICATION_PATH)/hardware/arduino/$(BUILD_CORE)/libraries + +ifndef APP_LIBS_LIST + w1 = $(realpath $(sort $(dir $(wildcard $(APP_LIB_PATH)/*/*.h $(APP_LIB_PATH)/*/*/*.h)))) # */ + APP_LIBS_LIST = $(subst $(APP_LIB_PATH)/,,$(filter-out $(EXCLUDE_LIST),$(w1))) + + w2 = $(realpath $(sort $(dir $(wildcard $(BUILD_APP_LIB_PATH)/*/*.h $(BUILD_APP_LIB_PATH)/*/*/*.h)))) # */ + BUILD_APP_LIBS_LIST = $(subst $(BUILD_APP_LIB_PATH)/,,$(filter-out $(EXCLUDE_LIST),$(w2))) +else + BUILD_APP_LIBS_LIST = $(APP_LIBS_LIST) +endif + +ifneq ($(APP_LIBS_LIST),0) + APP_LIBS = $(patsubst %,$(APP_LIB_PATH)/%,$(APP_LIBS_LIST)) + APP_LIB_CPP_SRC = $(wildcard $(patsubst %,%/*.cpp,$(APP_LIBS))) # */ + APP_LIB_C_SRC = $(wildcard $(patsubst %,%/*.c,$(APP_LIBS))) # */ + + APP_LIB_OBJS = $(patsubst $(APP_LIB_PATH)/%.cpp,$(OBJDIR)/libs/%.o,$(APP_LIB_CPP_SRC)) + APP_LIB_OBJS += $(patsubst $(APP_LIB_PATH)/%.c,$(OBJDIR)/libs/%.o,$(APP_LIB_C_SRC)) + + BUILD_APP_LIBS = $(patsubst %,$(BUILD_APP_LIB_PATH)/%,$(BUILD_APP_LIBS_LIST)) + BUILD_APP_LIB_CPP_SRC = $(wildcard $(patsubst %,%/*.cpp,$(BUILD_APP_LIBS))) # */ + BUILD_APP_LIB_C_SRC = $(wildcard $(patsubst %,%/*.c,$(BUILD_APP_LIBS))) # */ + + BUILD_APP_LIB_OBJS = $(patsubst $(BUILD_APP_LIB_PATH)/%.cpp,$(OBJDIR)/libs/%.o,$(BUILD_APP_LIB_CPP_SRC)) + BUILD_APP_LIB_OBJS += $(patsubst $(BUILD_APP_LIB_PATH)/%.c,$(OBJDIR)/libs/%.o,$(BUILD_APP_LIB_C_SRC)) +endif + + +MCU_FLAG_NAME = mmcu +EXTRA_LDFLAGS = +EXTRA_CPPFLAGS = $(addprefix -D, $(PLATFORM_TAG)) + + +# Arduino Leonardo USB PID VID +# +USB_VID := $(call PARSE_BOARD,$(BOARD_TAG),build.vid) +USB_PID := $(call PARSE_BOARD,$(BOARD_TAG),build.pid) + +ifneq ($(USB_PID),) +ifneq ($(USB_VID),) + USB_FLAGS = -DUSB_VID=$(USB_VID) + USB_FLAGS += -DUSB_PID=$(USB_PID) +endif +endif + +# Arduino Leonardo serial 1200 reset +# +USB_TOUCH := $(call PARSE_BOARD,$(BOARD_TAG),upload.use_1200bps_touch) + +ifneq ($(USB_TOUCH),) + USB_RESET = $(UTILITIES_PATH)/serial1200.py +endif + +TARGET_EEP = $(OBJDIR)/$(TARGET).eep +AVRDUDE_OPTS = -cdigispark -Pusb + diff --git a/FastLED/FastLED/Makefiles/Energia430.mk b/FastLED/FastLED/Makefiles/Energia430.mk new file mode 100755 index 00000000..68520d77 --- /dev/null +++ b/FastLED/FastLED/Makefiles/Energia430.mk @@ -0,0 +1,84 @@ +# +# embedXcode +# ---------------------------------- +# Embedded Computing on Xcode +# +# Copyright © Rei VILO, 2010-2014 +# http://embedxcode.weebly.com +# All rights reserved +# +# +# Last update: Dec 10, 2013 release 119 + + + +# Energia LaunchPad MSP430 and FR5739 specifics +# ---------------------------------- +# +PLATFORM := Energia +PLATFORM_TAG = ENERGIA=9 ARDUINO=101 EMBEDXCODE=$(RELEASE_NOW) $(filter __%__ ,$(GCC_PREPROCESSOR_DEFINITIONS)) +#PLATFORM_TAG = ENERGIA=9 ARDUINO=101 EMBEDXCODE=$(RELEASE_NOW) $(filter-out ENERGIA,$(GCC_PREPROCESSOR_DEFINITIONS)) +APPLICATION_PATH := $(ENERGIA_PATH) + +UPLOADER = mspdebug +MSPDEBUG_PATH = $(APPLICATION_PATH)/hardware/tools/msp430/mspdebug +MSPDEBUG = $(MSPDEBUG_PATH)/mspdebug +MSPDEBUG_PROTOCOL = $(call PARSE_BOARD,$(BOARD_TAG),upload.protocol) +MSPDEBUG_OPTS = $(MSPDEBUG_PROTOCOL) --force-reset + +# FraunchPad MSP430FR5739 requires a specific command +# +ifeq ($(BOARD_TAG), lpmsp430fr5739) + MSPDEBUG_COMMAND = load +else + MSPDEBUG_COMMAND = prog +endif + +APP_TOOLS_PATH := $(APPLICATION_PATH)/hardware/tools/msp430/bin +CORE_LIB_PATH := $(APPLICATION_PATH)/hardware/msp430/cores/msp430 +APP_LIB_PATH := $(APPLICATION_PATH)/hardware/msp430/libraries +BOARDS_TXT := $(APPLICATION_PATH)/hardware/msp430/boards.txt + +# Sketchbook/Libraries path +# wildcard required for ~ management +# ?ibraries required for libraries and Libraries +# +ifeq ($(USER_PATH)/Library/Energia/preferences.txt,) + $(error Error: run Energia once and define the sketchbook path) +endif + +ifeq ($(wildcard $(SKETCHBOOK_DIR)),) + SKETCHBOOK_DIR = $(shell grep sketchbook.path $(wildcard ~/Library/Energia/preferences.txt) | cut -d = -f 2) +endif +ifeq ($(wildcard $(SKETCHBOOK_DIR)),) + $(error Error: sketchbook path not found) +endif +USER_LIB_PATH = $(wildcard $(SKETCHBOOK_DIR)/?ibraries) + + +# Rules for making a c++ file from the main sketch (.pde) +# +PDEHEADER = \\\#include \"Energia.h\" + + +# Tool-chain names +# +CC = $(APP_TOOLS_PATH)/msp430-gcc +CXX = $(APP_TOOLS_PATH)/msp430-g++ +AR = $(APP_TOOLS_PATH)/msp430-ar +OBJDUMP = $(APP_TOOLS_PATH)/msp430-objdump +OBJCOPY = $(APP_TOOLS_PATH)/msp430-objcopy +SIZE = $(APP_TOOLS_PATH)/msp430-size +NM = $(APP_TOOLS_PATH)/msp430-nm +GDB = $(APP_TOOLS_PATH)/msp430-gdb + +BOARD = $(call PARSE_BOARD,$(BOARD_TAG),board) +#LDSCRIPT = $(call PARSE_BOARD,$(BOARD_TAG),ldscript) +VARIANT = $(call PARSE_BOARD,$(BOARD_TAG),build.variant) +VARIANT_PATH = $(APPLICATION_PATH)/hardware/msp430/variants/$(VARIANT) + +MCU_FLAG_NAME = mmcu +EXTRA_LDFLAGS = +#EXTRA_LDFLAGS = -T$(CORE_LIB_PATH)/$(LDSCRIPT) +EXTRA_CPPFLAGS = $(addprefix -D, $(PLATFORM_TAG)) -I$(VARIANT_PATH) + diff --git a/FastLED/FastLED/Makefiles/EnergiaLM4F.mk b/FastLED/FastLED/Makefiles/EnergiaLM4F.mk new file mode 100755 index 00000000..edb83e98 --- /dev/null +++ b/FastLED/FastLED/Makefiles/EnergiaLM4F.mk @@ -0,0 +1,102 @@ +# +# embedXcode +# ---------------------------------- +# Embedded Computing on Xcode +# +# Copyright © Rei VILO, 2010-2014 +# http://embedxcode.weebly.com +# All rights reserved +# +# +# Last update: Mar 01, 2014 release 136 + + + +# Energia LaunchPad Stellaris and Tiva C specifics +# ---------------------------------- +# +PLATFORM := Energia +PLATFORM_TAG = ENERGIA=9 ARDUINO=101 EMBEDXCODE=$(RELEASE_NOW) $(filter __%__ ,$(GCC_PREPROCESSOR_DEFINITIONS)) +#PLATFORM_TAG = ENERGIA=9 ARDUINO=101 EMBEDXCODE=$(RELEASE_NOW) $(filter-out ENERGIA,$(GCC_PREPROCESSOR_DEFINITIONS)) +APPLICATION_PATH := $(ENERGIA_PATH) + +UPLOADER = lm4flash +LM4FLASH_PATH = $(APPLICATION_PATH)/hardware/tools +LM4FLASH = $(LM4FLASH_PATH)/lm4f/bin/lm4flash +LM4FLASH_OPTS = + +# StellarPad requires a specific command +# +MSPDEBUG_COMMAND = prog + +APP_TOOLS_PATH := $(APPLICATION_PATH)/hardware/tools/lm4f/bin +CORE_LIB_PATH := $(APPLICATION_PATH)/hardware/lm4f/cores/lm4f +APP_LIB_PATH := $(APPLICATION_PATH)/hardware/lm4f/libraries +BOARDS_TXT := $(APPLICATION_PATH)/hardware/lm4f/boards.txt + +BUILD_CORE_LIB_PATH = $(APPLICATION_PATH)/hardware/lm4f/cores/lm4f/driverlib +BUILD_CORE_LIBS_LIST = $(subst .h,,$(subst $(BUILD_CORE_LIB_PATH)/,,$(wildcard $(BUILD_CORE_LIB_PATH)/*.h))) # */ + +BUILD_CORE_C_SRCS = $(wildcard $(BUILD_CORE_LIB_PATH)/*.c) # */ + +ifneq ($(strip $(NO_CORE_MAIN_FUNCTION)),) + BUILD_CORE_CPP_SRCS = $(filter-out %program.cpp %main.cpp,$(wildcard $(BUILD_CORE_LIB_PATH)/*.cpp)) # */ +else + BUILD_CORE_CPP_SRCS = $(filter-out %program.cpp, $(wildcard $(BUILD_CORE_LIB_PATH)/*.cpp)) # */ +endif + +BUILD_CORE_OBJ_FILES = $(BUILD_CORE_C_SRCS:.c=.o) $(BUILD_CORE_CPP_SRCS:.cpp=.o) +BUILD_CORE_OBJS = $(patsubst $(BUILD_CORE_LIB_PATH)/%,$(OBJDIR)/%,$(BUILD_CORE_OBJ_FILES)) + +# Sketchbook/Libraries path +# wildcard required for ~ management +# ?ibraries required for libraries and Libraries +# +ifeq ($(USER_PATH)/Library/Energia/preferences.txt,) + $(error Error: run Energia once and define the sketchbook path) +endif + +ifeq ($(wildcard $(SKETCHBOOK_DIR)),) + SKETCHBOOK_DIR = $(shell grep sketchbook.path $(wildcard ~/Library/Energia/preferences.txt) | cut -d = -f 2) +endif + +ifeq ($(wildcard $(SKETCHBOOK_DIR)),) + $(error Error: sketchbook path not found) +endif + +USER_LIB_PATH = $(wildcard $(SKETCHBOOK_DIR)/?ibraries) + + +# Rules for making a c++ file from the main sketch (.pde) +# +PDEHEADER = \\\#include \"Energia.h\" + + +# Tool-chain names +# +CC = $(APP_TOOLS_PATH)/arm-none-eabi-gcc +CXX = $(APP_TOOLS_PATH)/arm-none-eabi-g++ +AR = $(APP_TOOLS_PATH)/arm-none-eabi-ar +OBJDUMP = $(APP_TOOLS_PATH)/arm-none-eabi-objdump +OBJCOPY = $(APP_TOOLS_PATH)/arm-none-eabi-objcopy +SIZE = $(APP_TOOLS_PATH)/arm-none-eabi-size +NM = $(APP_TOOLS_PATH)/arm-none-eabi-nm +GDB = $(APP_TOOLS_PATH)/arm-none-eabi-gdb + + +BOARD = $(call PARSE_BOARD,$(BOARD_TAG),board) +LDSCRIPT = $(call PARSE_BOARD,$(BOARD_TAG),ldscript) +VARIANT = $(call PARSE_BOARD,$(BOARD_TAG),build.variant) +VARIANT_PATH = $(APPLICATION_PATH)/hardware/lm4f/variants/$(VARIANT) + +MCU_FLAG_NAME = mcpu +EXTRA_LDFLAGS = -nostartfiles -T$(CORE_LIB_PATH)/$(LDSCRIPT) -Wl,--gc-sections -Wl,-Map=$(OBJDIR)/lm4f.map +EXTRA_LDFLAGS += -mthumb --entry=ResetISR +EXTRA_LDFLAGS += -mfloat-abi=hard -mfpu=fpv4-sp-d16 -fsingle-precision-constant -nostdlib + +EXTRA_CPPFLAGS = $(addprefix -D, $(PLATFORM_TAG)) -I$(VARIANT_PATH) +EXTRA_CPPFLAGS += -fno-exceptions -fno-rtti -mthumb +EXTRA_CPPFLAGS += -mfloat-abi=hard -mfpu=fpv4-sp-d16 -fsingle-precision-constant + +OBJCOPYFLAGS = -v -Obinary +TARGET_HEXBIN = $(TARGET_BIN) diff --git a/FastLED/FastLED/Makefiles/MapleIDE.mk b/FastLED/FastLED/Makefiles/MapleIDE.mk new file mode 100755 index 00000000..a1d3c154 --- /dev/null +++ b/FastLED/FastLED/Makefiles/MapleIDE.mk @@ -0,0 +1,108 @@ +# +# embedXcode +# ---------------------------------- +# Embedded Computing on Xcode +# +# Copyright © Rei VILO, 2010-2014 +# http://embedxcode.weebly.com +# All rights reserved +# +# +# Last update: Apr 28, 2013 release 47 + +# MAPLE SUPPORT IS PUT ON HOLD +WARNING_MESSAGE = 'MAPLE SUPPORT IS PUT ON HOLD' + + +# Leaflabs Maple specifics +# ---------------------------------- +# +# The Maple reset script —which sends control signals over +# the USB-serial connection to restart and enter the bootloader— +# is written in Python and requires the PySerial library. +# +# Instructions available at http://leaflabs.com/docs/unix-toolchain.html#os-x +# Download PySerial library from http://pypi.python.org/pypi/pyserial +# +# +PLATFORM := MapleIDE +PLATFORM_TAG = MAPLE_IDE EMBEDXCODE=$(RELEASE_NOW) +APPLICATION_PATH := $(MAPLE_PATH) + +UPLOADER = dfu-util +DFU_UTIL_PATH = $(APPLICATION_PATH)/hardware/tools/arm/bin +DFU_UTIL = $(DFU_UTIL_PATH)/dfu-util +DFU_UTIL_OPTS = -a$(call PARSE_BOARD,$(BOARD_TAG),upload.altID) -d $(call PARSE_BOARD,$(BOARD_TAG),upload.usbID) +DFU_RESET = $(UTILITIES_PATH)/reset.py + +APP_TOOLS_PATH := $(APPLICATION_PATH)/hardware/tools/arm/bin +CORE_LIB_PATH := $(APPLICATION_PATH)/hardware/leaflabs/cores/maple +APP_LIB_PATH := $(APPLICATION_PATH)/libraries +BOARDS_TXT := $(APPLICATION_PATH)/hardware/leaflabs/boards.txt + +# Sketchbook/Libraries path +# wildcard required for ~ management +# ?ibraries required for libraries and Libraries +# +ifeq ($(USER_PATH)/Library/MapleIDE/preferences.txt,) + $(error Error: run Mpide once and define the sketchbook path) +endif + +ifeq ($(wildcard $(SKETCHBOOK_DIR)),) + SKETCHBOOK_DIR = $(shell grep sketchbook.path $(USER_PATH)/Library/MapleIDE/preferences.txt | cut -d = -f 2) +endif + +ifeq ($(wildcard $(SKETCHBOOK_DIR)),) + $(error Error: sketchbook path not found) +endif + +USER_LIB_PATH = $(wildcard $(SKETCHBOOK_DIR)/?ibraries) +CORE_AS_SRCS = $(wildcard $(CORE_LIB_PATH)/*.S) # */ + + +# Rules for making a c++ file from the main sketch (.pde) +# +PDEHEADER = \\\#include \"WProgram.h\" + + +# Tool-chain names +# +CC = $(APP_TOOLS_PATH)/arm-none-eabi-gcc +CXX = $(APP_TOOLS_PATH)/arm-none-eabi-g++ +AR = $(APP_TOOLS_PATH)/arm-none-eabi-ar +OBJDUMP = $(APP_TOOLS_PATH)/arm-none-eabi-objdump +OBJCOPY = $(APP_TOOLS_PATH)/arm-none-eabi-objcopy +SIZE = $(APP_TOOLS_PATH)/arm-none-eabi-size +NM = $(APP_TOOLS_PATH)/arm-none-eabi-nm + +lplm4f120h5qr.build.mcu=cortex-m4 + +BOARD = $(call PARSE_BOARD,$(BOARD_TAG),build.board) +LDSCRIPT = $(call PARSE_BOARD,$(BOARD_TAG),build.linker) +VARIANT = $(call PARSE_BOARD,$(BOARD_TAG),build.mcu) +#VARIANT_PATH = $(APPLICATION_PATH)/hardware/leaflabs/cores/maples/$(VARIANT) + + +MCU = $(call PARSE_BOARD,$(BOARD_TAG),build.family) +MCU_FLAG_NAME = mcpu + +EXTRA_LDFLAGS = -T$(CORE_LIB_PATH)/$(LDSCRIPT) -L$(APPLICATION_PATH)/hardware/leaflabs/cores/maple +EXTRA_LDFLAGS += -mthumb -Xlinker --gc-sections --print-gc-sections --march=armv7-m + +EXTRA_CPPFLAGS = -fno-rtti -fno-exceptions -mthumb -march=armv7-m -nostdlib +EXTRA_CPPFLAGS += -DBOARD_$(BOARD) -DMCU_$(call PARSE_BOARD,$(BOARD_TAG),build.mcu) +EXTRA_CPPFLAGS += -D$(call PARSE_BOARD,$(BOARD_TAG),build.vect) +EXTRA_CPPFLAGS += -D$(call PARSE_BOARD,$(BOARD_TAG),build.density) +EXTRA_CPPFLAGS += -DERROR_LED_PORT=$(call PARSE_BOARD,$(BOARD_TAG),build.error_led_port) +EXTRA_CPPFLAGS += -DERROR_LED_PIN=$(call PARSE_BOARD,$(BOARD_TAG),build.error_led_pin) +EXTRA_CPPFLAGS += $(addprefix -D, $(PLATFORM_TAG)) + +OBJCOPYFLAGS = -v -Obinary +TARGET_HEXBIN = $(TARGET_BIN) + +MAX_RAM_SIZE = $(call PARSE_BOARD,$(BOARD_TAG),upload.ram.maximum_size) + + + + + diff --git a/FastLED/FastLED/Makefiles/Microduino.mk b/FastLED/FastLED/Makefiles/Microduino.mk new file mode 100755 index 00000000..e4238383 --- /dev/null +++ b/FastLED/FastLED/Makefiles/Microduino.mk @@ -0,0 +1,93 @@ +# +# embedXcode +# ---------------------------------- +# Embedded Computing on Xcode +# +# Copyright © Rei VILO, 2010-2014 +# http://embedxcode.weebly.com +# All rights reserved +# +# +# Last update: Jan 04, 2014 release 122 + + + +# Microduino 1.0.x AVR specifics +# ---------------------------------- +# +PLATFORM := Microduino +BUILD_CORE := avr +PLATFORM_TAG = ARDUINO=105 MICRODUINO EMBEDXCODE=$(RELEASE_NOW) +APPLICATION_PATH := $(MICRODUINO_PATH) + +APP_TOOLS_PATH := $(APPLICATION_PATH)/hardware/tools/avr/bin +CORE_LIB_PATH := $(APPLICATION_PATH)/hardware/Microduino/cores/arduino +APP_LIB_PATH := $(APPLICATION_PATH)/libraries +BOARDS_TXT := $(APPLICATION_PATH)/hardware/Microduino/boards.txt + + +# Sketchbook/Libraries path +# wildcard required for ~ management +# +ifeq ($(USER_PATH)/Library/Arduino/preferences.txt,) + $(error Error: run Microduino or Arduino once and define the sketchbook path) +endif + +ifeq ($(wildcard $(SKETCHBOOK_DIR)),) + SKETCHBOOK_DIR = $(shell grep sketchbook.path $(USER_PATH)/Library/Arduino/preferences.txt | cut -d = -f 2) +endif +ifeq ($(wildcard $(SKETCHBOOK_DIR)),) + $(error Error: sketchbook path not found) +endif +USER_LIB_PATH = $(wildcard $(SKETCHBOOK_DIR)/?ibraries) + +# Rules for making a c++ file from the main sketch (.pde) +# +PDEHEADER = \\\#include \"Arduino.h\" + +# Tool-chain names +# +CC = $(APP_TOOLS_PATH)/avr-gcc +CXX = $(APP_TOOLS_PATH)/avr-g++ +AR = $(APP_TOOLS_PATH)/avr-ar +OBJDUMP = $(APP_TOOLS_PATH)/avr-objdump +OBJCOPY = $(APP_TOOLS_PATH)/avr-objcopy +SIZE = $(APP_TOOLS_PATH)/avr-size +NM = $(APP_TOOLS_PATH)/avr-nm + +# Specific AVRDUDE location and options +# +AVRDUDE_COM_OPTS = -D -p$(MCU) -C$(AVRDUDE_CONF) + +BOARD = $(call PARSE_BOARD,$(BOARD_TAG),board) +#LDSCRIPT = $(call PARSE_BOARD,$(BOARD_TAG),ldscript) +VARIANT = $(call PARSE_BOARD,$(BOARD_TAG),build.variant) +VARIANT_PATH = $(APPLICATION_PATH)/hardware/Microduino/variants/$(VARIANT) + +MCU_FLAG_NAME = mmcu +EXTRA_LDFLAGS = +EXTRA_CPPFLAGS = -MMD -I$(VARIANT_PATH) $(addprefix -D, $(PLATFORM_TAG)) + +# Leonardo USB PID VID +# +USB_TOUCH := $(call PARSE_BOARD,$(BOARD_TAG),upload.protocol) +USB_VID := $(call PARSE_BOARD,$(BOARD_TAG),build.vid) +USB_PID := $(call PARSE_BOARD,$(BOARD_TAG),build.pid) + +ifneq ($(USB_PID),) + USB_FLAGS += -DUSB_PID=$(USB_PID) +else + USB_FLAGS += -DUSB_PID=null +endif + +ifneq ($(USB_VID),) + USB_FLAGS += -DUSB_VID=$(USB_VID) +else + USB_FLAGS += -DUSB_VID=null +endif + +# Serial 1200 reset +# +ifeq ($(USB_TOUCH),avr109) + USB_RESET = $(UTILITIES_PATH)/serial1200.py +endif diff --git a/FastLED/FastLED/Makefiles/Mpide.mk b/FastLED/FastLED/Makefiles/Mpide.mk new file mode 100755 index 00000000..a8a7979c --- /dev/null +++ b/FastLED/FastLED/Makefiles/Mpide.mk @@ -0,0 +1,77 @@ +# +# embedXcode +# ---------------------------------- +# Embedded Computing on Xcode +# +# Copyright © Rei VILO, 2010-2014 +# http://embedxcode.weebly.com +# All rights reserved +# +# +# Last update: Jan 20, 2014 release 125 + + + +# chipKIT MPIDE specifics +# ---------------------------------- +# Dirty implementation for MPIDE release 0023-macosx-20130715 +# OPT_SYSTEM_INTERNAL is defined in main.cpp but used in wiring.h +# +PLATFORM := MPIDE +PLATFORM_TAG = ARDUINO=23 MPIDE=23 MPIDEVER=0x01000202 EMBEDXCODE=$(RELEASE_NOW) + +APPLICATION_PATH := $(MPIDE_PATH) + +APP_TOOLS_PATH := $(APPLICATION_PATH)/hardware/pic32/compiler/pic32-tools/bin +CORE_LIB_PATH := $(APPLICATION_PATH)/hardware/pic32/cores/pic32 +APP_LIB_PATH := $(APPLICATION_PATH)/hardware/pic32/libraries +BOARDS_TXT := $(APPLICATION_PATH)/hardware/pic32/boards.txt + +# Sketchbook/Libraries path +# wildcard required for ~ management +# ?ibraries required for libraries and Libraries +# +ifeq ($(wildcard $(USER_PATH)/Library/Mpide/preferences.txt),) + $(error Error: run Mpide once and define the sketchbook path) +endif + +ifeq ($(wildcard $(SKETCHBOOK_DIR)),) + SKETCHBOOK_DIR = $(shell grep sketchbook.path $(USER_PATH)/Library/Mpide/preferences.txt | cut -d = -f 2) +endif +ifeq ($(wildcard $(SKETCHBOOK_DIR)),) + $(error Error: sketchbook path not found) +endif +USER_LIB_PATH = $(wildcard $(SKETCHBOOK_DIR)/?ibraries) + + +# Rules for making a c++ file from the main sketch (.pde) +# +PDEHEADER = \\\#include \"WProgram.h\" + + +# Add .S files required by MPIDE release 0023-macosx-20130715 +# +CORE_AS_SRCS = $(wildcard $(CORE_LIB_PATH)/*.S) # */ + + +# Tool-chain names +# +CC = $(APP_TOOLS_PATH)/pic32-gcc +CXX = $(APP_TOOLS_PATH)/pic32-g++ +AR = $(APP_TOOLS_PATH)/pic32-ar +OBJDUMP = $(APP_TOOLS_PATH)/pic32-objdump +OBJCOPY = $(APP_TOOLS_PATH)/pic32-objcopy +SIZE = $(APP_TOOLS_PATH)/pic32-size +NM = $(APP_TOOLS_PATH)/pic32-nm + + +BOARD = $(call PARSE_BOARD,$(BOARD_TAG),board) +LDSCRIPT = $(call PARSE_BOARD,$(BOARD_TAG),ldscript) +VARIANT = $(call PARSE_BOARD,$(BOARD_TAG),build.variant) +VARIANT_PATH = $(APPLICATION_PATH)/hardware/pic32/variants/$(VARIANT) + +MCU_FLAG_NAME = mprocessor +# chipKIT-application-COMMON.ld added by MPIDE release 0023-macosx-20130715 +EXTRA_LDFLAGS = -T$(CORE_LIB_PATH)/$(LDSCRIPT) -T$(CORE_LIB_PATH)/chipKIT-application-COMMON.ld +EXTRA_CPPFLAGS = -mdebugger -Wcast-align -O2 -mno-smart-io -G1024 $(addprefix -D, $(PLATFORM_TAG)) -D$(BOARD) -I$(VARIANT_PATH) + diff --git a/FastLED/FastLED/Makefiles/Step1.mk b/FastLED/FastLED/Makefiles/Step1.mk new file mode 100755 index 00000000..6b64106c --- /dev/null +++ b/FastLED/FastLED/Makefiles/Step1.mk @@ -0,0 +1,229 @@ +# +# embedXcode +# ---------------------------------- +# Embedded Computing on Xcode +# +# Copyright © Rei VILO, 2010-2014 +# http://embedxcode.weebly.com +# All rights reserved +# +# +# Last update: Dec 06, 2013 release 119 + + + +# Sketch unicity test and extension +# ---------------------------------- +# +ifndef SKETCH_EXTENSION + ifeq ($(words $(wildcard *.pde) $(wildcard *.ino)), 0) + $(error No pde or ino sketch) + endif + + ifneq ($(words $(wildcard *.pde) $(wildcard *.ino)), 1) + $(error More than 1 pde or ino sketch) + endif + + ifneq ($(wildcard *.pde),) + SKETCH_EXTENSION := pde + else ifneq ($(wildcard *.ino),) + SKETCH_EXTENSION := ino + else + $(error Extension error) + endif +endif + + +ifneq ($(SKETCH_EXTENSION),cpp) + ifeq ($(words $(wildcard *.$(SKETCH_EXTENSION))), 0) + $(error No $(SKETCH_EXTENSION) sketch) + endif + + ifneq ($(words $(wildcard *.$(SKETCH_EXTENSION))), 1) + $(error More than one $(SKETCH_EXTENSION) sketch) + endif +endif + + +# Board selection +# ---------------------------------- +# Board specifics defined in .xconfig file +# BOARD_TAG and AVRDUDE_PORT +# +ifneq ($(MAKECMDGOALS),boards) + ifneq ($(MAKECMDGOALS),clean) + ifndef BOARD_TAG + $(error BOARD_TAG not defined) + endif + endif +endif + +ifndef BOARD_PORT + BOARD_PORT = /dev/tty.usb* +endif + + +# Arduino.app Mpide.app Wiring.app Energia.app MapleIDE.app paths +# +ARDUINO_APP = /Applications/Arduino.app +MPIDE_APP = /Applications/Mpide.app +WIRING_APP = /Applications/Wiring.app +ENERGIA_APP = /Applications/Energia.app +MAPLE_APP = /Applications/MapleIDE.app + +# Teensyduino.app path +# +TEENSY_0 = /Applications/Teensyduino.app +ifneq ($(wildcard $(TEENSY_0)),) + TEENSY_APP = $(TEENSY_0) +else + TEENSY_APP = /Applications/Arduino.app +endif + +# DigisparkArduino.app path +# +DIGISPARK_0 = /Applications/DigisparkArduino.app +ifneq ($(wildcard $(DIGISPARK_0)),) + DIGISPARK_APP = $(DIGISPARK_0) +else + DIGISPARK_APP = /Applications/Arduino.app +endif + +# Microduino.app path +# +MICRODUINO_0 = /Applications/Microduino.app +ifneq ($(wildcard $(MICRODUINO_0)),) + MICRODUINO_APP = $(MICRODUINO_0) +else + MICRODUINO_APP = /Applications/Arduino.app +endif + + +ifeq ($(wildcard $(ARDUINO_APP)),) + ifeq ($(wildcard $(MPIDE_APP)),) + ifeq ($(wildcard $(WIRING_APP)),) + ifeq ($(wildcard $(ENERGIA_APP)),) + ifeq ($(wildcard $(MAPLE_APP)),) + ifeq ($(wildcard $(TEENSY_APP)),) + ifeq ($(wildcard $(DIGISPARK_APP)),) + ifeq ($(wildcard $(MICRODUINO_APP)),) + $(error Error: no application found) + endif + endif + endif + endif + endif + endif + endif +endif + +ARDUINO_PATH = $(ARDUINO_APP)/Contents/Resources/Java +MPIDE_PATH = $(MPIDE_APP)/Contents/Resources/Java +WIRING_PATH = $(WIRING_APP)/Contents/Resources/Java +ENERGIA_PATH = $(ENERGIA_APP)/Contents/Resources/Java +MAPLE_PATH = $(MAPLE_APP)/Contents/Resources/Java +TEENSY_PATH = $(TEENSY_APP)/Contents/Resources/Java +DIGISPARK_PATH = $(DIGISPARK_APP)/Contents/Resources/Java +MICRODUINO_PATH = $(MICRODUINO_APP)/Contents/Resources/Java + +# Miscellaneous +# ---------------------------------- +# Variables +# +TARGET := embeddedcomputing +USER_PATH := $(wildcard ~/) +TEMPLATE := ePsiEJEtRXnDNaFGpywBX9vzeNQP4vUb + +# main.cpp selection +# = 1 takes local main.cpp +# +NO_CORE_MAIN_FUNCTION := 1 + +# Builds directory +# +OBJDIR = Builds + +# Function PARSE_BOARD data retrieval from boards.txt +# result = $(call PARSE_BOARD 'boardname','parameter') +# +PARSE_BOARD = $(shell if [ -f $(BOARDS_TXT) ]; then grep ^$(1).$(2)= $(BOARDS_TXT) | cut -d = -f 2; fi; ) + +# Function PARSE_FILE data retrieval from specified file +# result = $(call PARSE_FILE 'boardname','parameter','filename') +# +PARSE_FILE = $(shell if [ -f $(3) ]; then grep ^$(1).$(2) $(3) | cut -d = -f 2; fi; ) + + +# Clean if new BOARD_TAG +# ---------------------------------- +# +NEW_TAG := $(strip $(OBJDIR)/$(BOARD_TAG)-TAG) # +OLD_TAG := $(strip $(wildcard $(OBJDIR)/*-TAG)) # */ + +ifneq ($(OLD_TAG),$(NEW_TAG)) + CHANGE_FLAG := 1 +else + CHANGE_FLAG := 0 +endif + + +# Identification and switch +# ---------------------------------- +# Look if BOARD_TAG is listed as a Arduino/Arduino board +# Look if BOARD_TAG is listed as a Arduino/Arduino/avr board *1.5 +# Look if BOARD_TAG is listed as a Arduino/Arduino/sam board *1.5 +# Look if BOARD_TAG is listed as a Mpide/PIC32 board +# Look if BOARD_TAG is listed as a Wiring/Wiring board +# Look if BOARD_TAG is listed as a Energia/MPS430 board +# Look if BOARD_TAG is listed as a MapleIDE/LeafLabs board +# Look if BOARD_TAG is listed as a Teensy/Teensy board +# Look if BOARD_TAG is listed as a Microduino/Microduino board +# Look if BOARD_TAG is listed as a Digispark/Digispark board +# Order matters! +# + +ifneq ($(MAKECMDGOALS),boards) + ifneq ($(MAKECMDGOALS),clean) + ifneq ($(call PARSE_FILE,$(BOARD_TAG),name,$(ARDUINO_PATH)/hardware/arduino/boards.txt),) + include $(MAKEFILE_PATH)/Arduino.mk + else ifneq ($(call PARSE_FILE,$(BOARD_TAG),name,$(ARDUINO_PATH)/hardware/arduino/avr/boards.txt),) + include $(MAKEFILE_PATH)/Arduino15avr.mk + else ifneq ($(call PARSE_FILE,$(BOARD_TAG1),name,$(ARDUINO_PATH)/hardware/arduino/avr/boards.txt),) + include $(MAKEFILE_PATH)/Arduino15avr.mk + else ifneq ($(call PARSE_FILE,$(BOARD_TAG),name,$(ARDUINO_PATH)/hardware/arduino/sam/boards.txt),) + include $(MAKEFILE_PATH)/Arduino15sam.mk + else ifneq ($(call PARSE_FILE,$(BOARD_TAG),name,$(ARDUINO_PATH)/hardware/arduino/boards.txt),) + include $(MAKEFILE_PATH)/Arduino.mk + else ifneq ($(call PARSE_FILE,$(BOARD_TAG),name,$(MPIDE_PATH)/hardware/pic32/boards.txt),) + include $(MAKEFILE_PATH)/Mpide.mk + else ifneq ($(call PARSE_FILE,$(BOARD_TAG),name,$(WIRING_PATH)/hardware/Wiring/boards.txt),) + include $(MAKEFILE_PATH)/Wiring.mk + else ifneq ($(call PARSE_FILE,$(BOARD_TAG),name,$(ENERGIA_PATH)/hardware/msp430/boards.txt),) + include $(MAKEFILE_PATH)/Energia430.mk + else ifneq ($(call PARSE_FILE,$(BOARD_TAG),name,$(ENERGIA_PATH)/hardware/lm4f/boards.txt),) + include $(MAKEFILE_PATH)/EnergiaLM4F.mk + else ifneq ($(call PARSE_FILE,$(BOARD_TAG),name,$(MAPLE_PATH)/hardware/leaflabs/boards.txt),) + include $(MAKEFILE_PATH)/MapleIDE.mk + else ifneq ($(call PARSE_FILE,$(BOARD_TAG),name,$(TEENSY_PATH)/hardware/teensy/boards.txt),) + include $(MAKEFILE_PATH)/Teensy.mk + else ifneq ($(call PARSE_FILE,$(BOARD_TAG),name,$(MICRODUINO_PATH)/hardware/Microduino/boards.txt),) + include $(MAKEFILE_PATH)/Microduino.mk + else ifneq ($(call PARSE_FILE,$(BOARD_TAG),name,$(DIGISPARK_PATH)/hardware/digispark/boards.txt),) + include $(MAKEFILE_PATH)/Digispark.mk + else + $(error $(BOARD_TAG) board is unknown) + endif + endif +endif + + +# List of sub-paths to be excluded +# +EXCLUDE_NAMES = Example example Examples examples Archive archive Archives archives Documentation documentation Reference reference +EXCLUDE_NAMES += ArduinoTestSuite +EXCLUDE_NAMES += $(EXCLUDE_LIBS) +EXCLUDE_LIST = $(addprefix %,$(EXCLUDE_NAMES)) + +# Step 2 +# +include $(MAKEFILE_PATH)/Step2.mk diff --git a/FastLED/FastLED/Makefiles/Step2.mk b/FastLED/FastLED/Makefiles/Step2.mk new file mode 100755 index 00000000..63bac5ba --- /dev/null +++ b/FastLED/FastLED/Makefiles/Step2.mk @@ -0,0 +1,1021 @@ +# +# embedXcode +# ---------------------------------- +# Embedded Computing on Xcode +# +# Copyright © Rei VILO, 2010-2014 +# http://embedxcode.weebly.com +# All rights reserved +# +# +# Last update: Mar 14, 2014 release 141 + + + +# Serial port check and selection +# ---------------------------------- +# +include $(MAKEFILE_PATH)/Avrdude.mk + +ifeq ($(AVRDUDE_NO_SERIAL_PORT),1) +# +else ifeq ($(UPLOADER),teensy_flash) +# teensy uploader in charge +else ifneq ($(MAKECMDGOALS),boards) + ifneq ($(MAKECMDGOALS),build) + ifneq ($(MAKECMDGOALS),make) + ifneq ($(MAKECMDGOALS),document) + ifneq ($(MAKECMDGOALS),clean) + ifneq ($(MAKECMDGOALS),distribute) + ifneq ($(MAKECMDGOALS),info) + ifneq ($(MAKECMDGOALS),depends) + ifeq ($(AVRDUDE_PORT),) + $(error Serial port not available) + endif + endif + endif + endif + endif + endif + endif + endif +endif + +ifndef UPLOADER + UPLOADER = avrdude +endif + +ifndef BOARD_NAME + BOARD_NAME = $(call PARSE_BOARD,$(BOARD_TAG),name) +endif + +# Functions +# ---------------------------------- +# + +# Function TRACE action target source to ~/Library/Logs/embedXcode.log +# result = $(shell echo 'action',$(BOARD_TAG),'target','source' >> ~/Library/Logs/embedXcode.log) +# +TRACE = $(shell echo $(1)': '$(suffix $(2))' < '$(suffix $(3))' '$(BOARD_TAG)' '$(dir $(2))' '$(notdir $(3)) >> ~/Library/Logs/embedXcode.log) + +# Function SHOW action target source +# result = $(shell echo 'action',$(BOARD_TAG),'target','source') +# +SHOW = @echo $(1)': '$(suffix $(2))' < '$(suffix $(3))' '$(BOARD_TAG)' '$(dir $(2))' '$(notdir $(3)) +#SHOW = + + +# CORE libraries +# ---------------------------------- +# +ifndef CORE_LIB_PATH + CORE_LIB_PATH = $(APPLICATION_PATH)/hardware/arduino/cores/arduino +endif + +s5 = $(subst .h,,$(subst $(CORE_LIB_PATH)/,,$(wildcard $(CORE_LIB_PATH)/*.h))) # */ +CORE_LIBS_LIST = $(subst $(USER_LIB_PATH)/,,$(filter-out $(EXCLUDE_LIST),$(s5))) + + +# List of sources +# ---------------------------------- +# + +# CORE sources +# +ifdef CORE_LIB_PATH + CORE_C_SRCS = $(wildcard $(CORE_LIB_PATH)/*.c) # */ + + ifneq ($(strip $(NO_CORE_MAIN_FUNCTION)),) + CORE_CPP_SRCS = $(filter-out %main.cpp, $(wildcard $(CORE_LIB_PATH)/*.cpp $(CORE_LIB_PATH)/*/*.cpp)) # */ + else + CORE_CPP_SRCS = $(wildcard $(CORE_LIB_PATH)/*.cpp $(CORE_LIB_PATH)/*/*.cpp) # */ + endif + + CORE_OBJ_FILES = $(CORE_C_SRCS:.c=.o) $(CORE_CPP_SRCS:.cpp=.o) $(CORE_AS_SRCS:.S=.o) + CORE_OBJS = $(patsubst $(CORE_LIB_PATH)/%,$(OBJDIR)/%,$(CORE_OBJ_FILES)) +endif + + +# APPlication Arduino/chipKIT/Digispark/Energia/Maple/Microduino/Teensy/Wiring sources +# +ifndef APP_LIB_PATH + APP_LIB_PATH = $(APPLICATION_PATH)/libraries +endif + +ifeq ($(APP_LIBS_LIST),) + s1 = $(realpath $(sort $(dir $(wildcard $(APP_LIB_PATH)/*/*.h $(APP_LIB_PATH)/*/*/*.h)))) # */ + APP_LIBS_LIST = $(subst $(APP_LIB_PATH)/,,$(filter-out $(EXCLUDE_LIST),$(s1))) +endif + +ifndef APP_LIBS +ifneq ($(APP_LIBS_LIST),0) + s4 = $(patsubst %,$(APP_LIB_PATH)/%,$(APP_LIBS_LIST)) + APP_LIBS = $(realpath $(sort $(dir $(foreach dir,$(s4),$(wildcard $(dir)/*.h $(dir)/*/*.h $(dir)/*/*/*.h))))) +endif +endif + +ifndef APP_LIB_OBJS + FLAG = 1 + APP_LIB_C_SRC = $(wildcard $(patsubst %,%/*.c,$(APP_LIBS))) # */ + APP_LIB_CPP_SRC = $(wildcard $(patsubst %,%/*.cpp,$(APP_LIBS))) # */ + APP_LIB_OBJS = $(patsubst $(APP_LIB_PATH)/%.c,$(OBJDIR)/libs/%.o,$(APP_LIB_C_SRC)) + APP_LIB_OBJS += $(patsubst $(APP_LIB_PATH)/%.cpp,$(OBJDIR)/libs/%.o,$(APP_LIB_CPP_SRC)) +else + FLAG = 0 +endif + +# USER sources +# wildcard required for ~ management +# ?ibraries required for libraries and Libraries +# +ifndef USER_LIB_PATH + USER_LIB_PATH = $(wildcard $(SKETCHBOOK_DIR)/?ibraries) +endif + +ifndef USER_LIBS_LIST + s2 = $(realpath $(sort $(dir $(wildcard $(USER_LIB_PATH)/*/*.h)))) # */ + USER_LIBS_LIST = $(subst $(USER_LIB_PATH)/,,$(filter-out $(EXCLUDE_LIST),$(s2))) +endif + +ifneq ($(USER_LIBS_LIST),0) + s3 = $(patsubst %,$(USER_LIB_PATH)/%,$(USER_LIBS_LIST)) + USER_LIBS = $(realpath $(sort $(dir $(foreach dir,$(s3),$(wildcard $(dir)/*.h $(dir)/*/*.h $(dir)/*/*/*.h))))) + + USER_LIB_CPP_SRC = $(wildcard $(patsubst %,%/*.cpp,$(USER_LIBS))) # */ + USER_LIB_C_SRC = $(wildcard $(patsubst %,%/*.c,$(USER_LIBS))) # */ + + USER_OBJS = $(patsubst $(USER_LIB_PATH)/%.cpp,$(OBJDIR)/libs/%.o,$(USER_LIB_CPP_SRC)) + USER_OBJS += $(patsubst $(USER_LIB_PATH)/%.c,$(OBJDIR)/libs/%.o,$(USER_LIB_C_SRC)) +endif + +# LOCAL sources +# +LOCAL_C_SRCS = $(wildcard *.c) + +ifneq ($(strip $(NO_CORE_MAIN_FUNCTION)),) + LOCAL_CPP_SRCS = $(wildcard *.cpp) +else + LOCAL_CPP_SRCS = $(filter-out %main.cpp, $(wildcard *.cpp)) +endif + +LOCAL_CC_SRCS = $(wildcard *.cc) + +# Use of implicit rule for LOCAL_PDE_SRCS +# +#LOCAL_PDE_SRCS = $(wildcard *.$(SKETCH_EXTENSION)) +LOCAL_AS_SRCS = $(wildcard *.S) +LOCAL_OBJ_FILES = $(LOCAL_C_SRCS:.c=.o) $(LOCAL_CPP_SRCS:.cpp=.o) \ + $(LOCAL_PDE_SRCS:.$(SKETCH_EXTENSION)=.o) \ + $(LOCAL_CC_SRCS:.cc=.o) $(LOCAL_AS_SRCS:.S=.o) +#LOCAL_OBJS = $(patsubst %,$(OBJDIR)/%,$(LOCAL_OBJ_FILES)) +LOCAL_OBJS = $(patsubst %,$(OBJDIR)/%,$(filter-out $(PROJECT_NAME_AS_IDENTIFIER).o,$(LOCAL_OBJ_FILES))) + +# All the objects +# ??? Does order matter? +# +REMOTE_OBJS = $(CORE_OBJS) $(BUILD_CORE_OBJS) $(APP_LIB_OBJS) $(BUILD_APP_LIB_OBJS) $(VARIANT_OBJS) $(USER_OBJS) +OBJS = $(REMOTE_OBJS) $(LOCAL_OBJS) + +# Dependency files +# +#DEPS = $(LOCAL_OBJS:.o=.d) +DEPS = $(OBJS:.o=.d) + + +# Processor model and frequency +# ---------------------------------- +# +ifndef MCU + MCU = $(call PARSE_BOARD,$(BOARD_TAG),build.mcu) +endif + +ifndef F_CPU + F_CPU = $(call PARSE_BOARD,$(BOARD_TAG),build.f_cpu) +endif + + +# Rules +# ---------------------------------- +# + +# Main targets +# +TARGET_A = $(OBJDIR)/$(TARGET).a +TARGET_HEX = $(OBJDIR)/$(TARGET).hex +TARGET_ELF = $(OBJDIR)/$(TARGET).elf +TARGET_BIN = $(OBJDIR)/$(TARGET).bin +TARGETS = $(OBJDIR)/$(TARGET).* + +ifndef TARGET_HEXBIN + TARGET_HEXBIN = $(TARGET_HEX) +endif + +ifndef TARGET_EEP + TARGET_EEP = +endif + +# List of dependencies +# +DEP_FILE = $(OBJDIR)/depends.mk + +# Executables +# +REMOVE = rm -r +MV = mv -f +CAT = cat +ECHO = echo + +# General arguments +# +SYS_INCLUDES = $(patsubst %,-I%,$(APP_LIBS)) +SYS_INCLUDES += $(patsubst %,-I%,$(BUILD_APP_LIBS)) +SYS_INCLUDES += $(patsubst %,-I%,$(USER_LIBS)) + +SYS_OBJS = $(wildcard $(patsubst %,%/*.o,$(APP_LIBS))) # */ +SYS_OBJS += $(wildcard $(patsubst %,%/*.o,$(BUILD_APP_LIBS))) # */ +SYS_OBJS += $(wildcard $(patsubst %,%/*.o,$(USER_LIBS))) # */ + +CPPFLAGS = -$(MCU_FLAG_NAME)=$(MCU) -DF_CPU=$(F_CPU) -I$(CORE_LIB_PATH) +CPPFLAGS += $(SYS_INCLUDES) -g -Os -w -Wall -ffunction-sections -fdata-sections +CPPFLAGS += $(EXTRA_CPPFLAGS) + +ifdef USB_FLAGS + CPPFLAGS += $(USB_FLAGS) +endif + +ifdef USE_GNU99 + CFLAGS = -std=gnu99 +endif + +SCOPE_FLAG := -$(PLATFORM) + +# CXX = flags for C++ only +# CPP = flags for both C and C++ +# +ifndef EXTRA_CXXFLAGS + CXXFLAGS = -fno-exceptions +else + CXXFLAGS = $(EXTRA_CXXFLAGS) +endif + +ASFLAGS = -$(MCU_FLAG_NAME)=$(MCU) -x assembler-with-cpp +ifeq ($(BUILD_CORE),sam) + LDFLAGS = -$(MCU_FLAG_NAME)=$(MCU) -lm -Wl,--gc-sections,-u,main -Os $(EXTRA_LDFLAGS) +else + LDFLAGS = -$(MCU_FLAG_NAME)=$(MCU) -Wl,--gc-sections -Os $(EXTRA_LDFLAGS) +endif + +ifndef OBJCOPYFLAGS + OBJCOPYFLAGS = -Oihex -R .eeprom +endif + +# Implicit rules for building everything (needed to get everything in +# the right directory) +# +# Rather than mess around with VPATH there are quasi-duplicate rules +# here for building e.g. a system C++ file and a local C++ +# file. Besides making things simpler now, this would also make it +# easy to change the build options in future + + +# 1-6 Build +# ---------------------------------- +# + +# 2- APPlication Arduino/chipKIT/Digispark/Energia/Maple/Microduino/Teensy/Wiring library sources +# +$(OBJDIR)/libs/%.o: $(APP_LIB_PATH)/%.c + $(call SHOW,"2.1-APP",$@,$<) + $(call TRACE,"2-APP",$@,$<) + @mkdir -p $(dir $@) + $(CC) -c $(CPPFLAGS) $(CFLAGS) $< -o $@ + +$(OBJDIR)/libs/%.o: $(APP_LIB_PATH)/%.cpp + $(call SHOW,"2.2-APP",$@,$<) + $(call TRACE,"2-APP",$@,$<) + @mkdir -p $(dir $@) + $(CXX) -c $(CPPFLAGS) $(CXXFLAGS) $(CFLAGS) $< -o $@ + +$(OBJDIR)/libs/%.o: $(BUILD_APP_LIB_PATH)/%.cpp + $(call SHOW,"2.3-APP",$@,$<) + $(call TRACE,"2-APP",$@,$<) + @mkdir -p $(dir $@) + $(CXX) -c $(CPPFLAGS) $(CFLAGS) $< -o $@ + +$(OBJDIR)/libs/%.o: $(BUILD_APP_LIB_PATH)/%.c + $(call SHOW,"2.4-APP",$@,$<) + $(call TRACE,"2-APP",$@,$<) + @mkdir -p $(dir $@) + $(CC) -c $(CPPFLAGS) $(CFLAGS) $< -o $@ + +$(OBJDIR)/libs/%.d: $(APP_LIB_PATH)/%.cpp + $(call SHOW,"2.5-APP",$@,$<) + $(call TRACE,"2-APP",$@,$<) + @mkdir -p $(dir $@) + $(CXX) -MM $(CPPFLAGS) $(CXXFLAGS) $(CFLAGS) $< -MF $@ -MT $(@:.d=.o) + +$(OBJDIR)/libs/%.d: $(APP_LIB_PATH)/%.c + $(call SHOW,"2.6-APP",$@,$<) + $(call TRACE,"2-APP",$@,$<) + @mkdir -p $(dir $@) + $(CC) -MM $(CPPFLAGS) $(CFLAGS) $< -MF $@ -MT $(@:.d=.o) + +$(OBJDIR)/libs/%.d: $(BUILD_APP_LIB_PATH)/%.cpp + $(call SHOW,"2.7-APP",$@,$<) + $(call TRACE,"2-APP",$@,$<) + @mkdir -p $(dir $@) + $(CXX) -MM $(CPPFLAGS) $(CXXFLAGS) $(CFLAGS) $< -MF $@ -MT $(@:.d=.o) + +$(OBJDIR)/libs/%.d: $(BUILD_APP_LIB_PATH)/%.c + $(call SHOW,"2.8-APP",$@,$<) + $(call TRACE,"2-APP",$@,$<) + @mkdir -p $(dir $@) + $(CC) -MM $(CPPFLAGS) $(CFLAGS) $< -MF $@ -MT $(@:.d=.o) + + +# 3- USER library sources +# +$(OBJDIR)/libs/%.o: $(USER_LIB_PATH)/%.cpp + $(call SHOW,"3.1-USER",$@,$<) + $(call TRACE,"3-USER",$@,$<) + @mkdir -p $(dir $@) + $(CXX) -c $(CPPFLAGS) $(CXXFLAGS) $(CFLAGS) $< -o $@ + +$(OBJDIR)/libs/%.o: $(USER_LIB_PATH)/%.c + $(call SHOW,"3.2-USER",$@,$<) + $(call TRACE,"3-USER",$@,$<) + @mkdir -p $(dir $@) + $(CC) -c $(CPPFLAGS) $(CFLAGS) $< -o $@ + +$(OBJDIR)/libs/%.d: $(USER_LIB_PATH)/%.cpp + $(call SHOW,"3.1-USER",$@,$<) + $(call TRACE,"3-USER",$@,$<) + @mkdir -p $(dir $@) + $(CXX) -MM $(CPPFLAGS) $(CXXFLAGS) $(CFLAGS) $< -MF $@ -MT $(@:.d=.o) + +$(OBJDIR)/libs/%.d: $(USER_LIB_PATH)/%.c + $(call SHOW,"3.2-USER",$@,$<) + $(call TRACE,"3-USER",$@,$<) + @mkdir -p $(dir $@) + $(CC) -MM $(CPPFLAGS) $(CFLAGS) $< -MF $@ -MT $(@:.d=.o) + + +# 4- LOCAL sources +# .o rules are for objects, .d for dependency tracking +# +$(OBJDIR)/%.o: %.c + $(call SHOW,"4.1-LOCAL",$@,$<) + $(call TRACE,"4-LOCAL",$@,$<) + $(CC) -c $(CPPFLAGS) $(CFLAGS) $< -o $@ + +$(OBJDIR)/%.o: %.cc + $(call SHOW,"4.2-LOCAL",$@,$<) + $(call TRACE,"4-LOCAL",$@,$<) + $(CXX) -c $(CPPFLAGS) $(CXXFLAGS) $< -o $@ + +$(OBJDIR)/%.o: %.cpp + $(call SHOW,"4.3-LOCAL",$@,$<) + $(call TRACE,"4-LOCAL",$@,$<) + $(CXX) -c $(CPPFLAGS) $(CXXFLAGS) $< -o $@ + +$(OBJDIR)/%.o: %.S + $(call SHOW,"4.4-LOCAL",$@,$<) + $(call TRACE,"4-LOCAL",$@,$<) + $(CC) -c $(CPPFLAGS) $(ASFLAGS) $< -o $@ + +$(OBJDIR)/%.o: %.s + $(call SHOW,"4.5-LOCAL",$@,$<) + $(call TRACE,"4-LOCAL",$@,$<) + $(CC) -c $(CPPFLAGS) $(ASFLAGS) $< -o $@ + +$(OBJDIR)/%.d: %.c + $(call SHOW,"4.6-LOCAL",$@,$<) + $(call TRACE,"4-LOCAL",$@,$<) + $(CC) -MM $(CPPFLAGS) $(CFLAGS) $< -MF $@ -MT $(@:.d=.o) + +$(OBJDIR)/%.d: %.cpp + $(call SHOW,"4.7-LOCAL",$@,$<) + $(call TRACE,"4-LOCAL",$@,$<) + $(CXX) -MM $(CPPFLAGS) $(CXXFLAGS) $< -MF $@ -MT $(@:.d=.o) + +$(OBJDIR)/%.d: %.S + $(call SHOW,"4.8-LOCAL",$@,$<) + $(call TRACE,"4-LOCAL",$@,$<) + $(CC) -MM $(CPPFLAGS) $(ASFLAGS) $< -MF $@ -MT $(@:.d=.o) + +$(OBJDIR)/%.d: %.s + $(call SHOW,"4.9-LOCAL",$@,$<) + $(call TRACE,"4-LOCAL",$@,$<) + $(CC) -MM $(CPPFLAGS) $(ASFLAGS) $< -MF $@ -MT $(@:.d=.o) + + +# 5- SKETCH pde/ino -> cpp -> o file +# +$(OBJDIR)/%.cpp: %.$(SKETCH_EXTENSION) + $(call SHOW,"5.1-SKETCH",$@,$<) + $(call TRACE,"5-SKETCH",$@,$<) + @$(ECHO) $(PDEHEADER) > $@ + @$(CAT) $< >> $@ +# @$(ECHO) $(PDEHEADER) > $(OBJDIR)/text.txt +# @$(CAT) $< >> $(OBJDIR)/text.txt + +$(OBJDIR)/%.o: $(OBJDIR)/%.cpp + $(call SHOW,"5.2-SKETCH",$@,$<) + $(call TRACE,"5-SKETCH",$@,$<) + $(CXX) -c $(CPPFLAGS) $(CXXFLAGS) -I. $< -o $@ + +$(OBJDIR)/%.d: $(OBJDIR)/%.cpp + $(call SHOW,"5.3-SKETCH",$@,$<) + $(call TRACE,"5-SKETCH",$@,$<) + $(CXX) -MM $(CPPFLAGS) $(CXXFLAGS) -I. $< -MF $@ -MT $(@:.d=.o) + + +# 6- VARIANT files +# +$(OBJDIR)/libs/%.o: $(VARIANT_PATH)/%.cpp + $(call SHOW,"6.1-VARIANT",$@,$<) + $(call TRACE,"6-VARIANT",$@,$<) + @mkdir -p $(dir $@) + $(CXX) -c $(CPPFLAGS) $(CXXFLAGS) $(CFLAGS) $< -o $@ + +$(OBJDIR)/%.o: $(VARIANT_PATH)/%.cpp + $(call SHOW,"6.2-VARIANT",$@,$<) + $(call TRACE,"6-VARIANT",$@,$<) + @mkdir -p $(dir $@) + $(CXX) -c $(CPPFLAGS) $(CXXFLAGS) $(CFLAGS) $< -o $@ + +$(OBJDIR)/libs/%.d: $(VARIANT_PATH)/%.cpp + $(call SHOW,"6.3-VARIANT",$@,$<) + $(call TRACE,"6-VARIANT",$@,$<) + @mkdir -p $(dir $@) + $(CXX) -MM $(CPPFLAGS) $(CXXFLAGS) $(CFLAGS) $< -MF $@ -MT $(@:.d=.o) + +$(OBJDIR)/%.d: $(VARIANT_PATH)/%.cpp + $(call SHOW,"6.4-VARIANT",$@,$<) + $(call TRACE,"6-VARIANT",$@,$<) + @mkdir -p $(dir $@) + $(CXX) -c $(CPPFLAGS) $(CXXFLAGS) $(CFLAGS) $< -MF $@ -MT $(@:.d=.o) + + +# 1- CORE files +# +$(OBJDIR)/%.o: $(CORE_LIB_PATH)/%.c + $(call SHOW,"1.1-CORE",$@,$<) + $(call TRACE,"1-CORE",$@,$<) + $(CC) -c $(CPPFLAGS) $(CFLAGS) $< -o $@ + +$(OBJDIR)/%.o: $(CORE_LIB_PATH)/%.S + $(call SHOW,"1.2-CORE",$@,$<) + $(call TRACE,"1-CORE",$@,$<) + $(CC) -c $(CPPFLAGS) $(CFLAGS) $< -o $@ + +$(OBJDIR)/%.o: $(CORE_LIB_PATH)/%.cpp + $(call SHOW,"1.3-CORE",$@,$<) + $(call TRACE,"1-CORE",$@,$<) + @mkdir -p $(dir $@) + $(CXX) -c $(CPPFLAGS) $(CXXFLAGS) $< -o $@ + +$(OBJDIR)/%.o: $(BUILD_CORE_LIB_PATH)/%.c + $(call SHOW,"1.4-CORE",$@,$<) + $(call TRACE,"1-CORE",$@,$<) + $(CC) -c $(CPPFLAGS) $(CFLAGS) $< -o $@ + +$(OBJDIR)/%.o: $(BUILD_CORE_LIB_PATH)/%.cpp + $(call SHOW,"1.5-CORE",$@,$<) + $(call TRACE,"1-CORE",$@,$<) + $(CXX) -c $(CPPFLAGS) $(CXXFLAGS) $< -o $@ + +$(OBJDIR)/%.d: $(CORE_LIB_PATH)/%.c + $(call SHOW,"1.6-CORE",$@,$<) + $(call TRACE,"1-CORE",$@,$<) + $(CC) -MM $(CPPFLAGS) $(CFLAGS) $< -MF $@ -MT $(@:.d=.o) + +$(OBJDIR)/%.d: $(CORE_LIB_PATH)/%.cpp + $(call SHOW,"1.7-CORE",$@,$<) + $(call TRACE,"1-CORE",$@,$<) + $(CXX) -MM $(CPPFLAGS) $(CXXFLAGS) $(CFLAGS) $< -MF $@ -MT $(@:.d=.o) + +$(OBJDIR)/%.d: $(BUILD_CORE_LIB_PATH)/%.c + $(call SHOW,"1.8-CORE",$@,$<) + $(call TRACE,"1-CORE",$@,$<) + $(CC) -MM $(CPPFLAGS) $(CFLAGS) $< -MF $@ -MT $(@:.d=.o) + +$(OBJDIR)/%.d: $(BUILD_CORE_LIB_PATH)/%.cpp + $(call SHOW,"1.9-CORE",$@,$<) + $(call TRACE,"1-CORE",$@,$<) + $(CXX) -MM $(CPPFLAGS) $(CXXFLAGS) $< -MF $@ -MT $(@:.d=.o) + + +# 7- Link +# ---------------------------------- +# +$(TARGET_ELF): $(OBJS) + @echo "---- Link ---- " + +ifneq ($(BOARD_TAG),teensy3) +ifneq ($(BOARD_TAG),teensy31) + $(call SHOW,"7.1-ARCHIVE",$@,.) + $(call TRACE,"7-ARCHIVE",$@,.) + $(AR) rcs $(TARGET_A) $(REMOTE_OBJS) +endif +endif + $(call SHOW,"7.2-LINK",$@,.) + $(call TRACE,"7-LINK",$@,.) + +ifeq ($(BUILD_CORE),sam) +# Builds/syscalls_sam3.c.o needs to be mentioned again + $(CXX) $(LDFLAGS) -o $@ -L$(OBJDIR) -Wl,--start-group Builds/syscalls_sam3.o $(SYSTEM_OBJS) $(LOCAL_OBJS) $(TARGET_A) -Wl,--end-group +else ifeq ($(VARIANT),stellarpad) +# -lc -lm -lgcc need to be at the end of the sentence +# $(CXX) $(LDFLAGS) -o $@ $(SYSTEM_OBJS) $(LOCAL_OBJS) $(TARGET_A) -L$(OBJDIR) -lc -lm -lgcc +# arm-none-eabi-ar doesn't seem to work with release 4.7.1 +# $(CXX) $(LDFLAGS) -o $@ $(LOCAL_OBJS) $(REMOTE_OBJS) -L$(OBJDIR) -lm -lc -lgcc + $(CXX) $(LDFLAGS) -o $@ $(SYSTEM_OBJS) $(LOCAL_OBJS) $(TARGET_A) -L$(OBJDIR) -lm -lc -lgcc + +else ifeq ($(PLATFORM),MapleIDE) + $(CXX) $(LDFLAGS) -o $@ $(LOCAL_OBJS) $(TARGET_A) -L$(OBJDIR) + +else ifeq ($(PLATFORM),MPIDE) +# compatible with MPIDE release 0023-macosx-20130715 + $(CXX) $(LDFLAGS) -o $@ $(LOCAL_OBJS) $(TARGET_A) -L$(OBJDIR) -lm + +else ifeq ($(BOARD_TAG),teensy3) +# arm-none-eabi-ar doesn't work with release 4.7.1 +# $(CXX) $(LDFLAGS) -o $@ $(LOCAL_OBJS) $(TARGET_A) -lc -L$(OBJDIR) -lm +# $(CXX) $(LDFLAGS) -o $@ $(TARGET_A) $(LOCAL_OBJS) -L$(OBJDIR) -larm_cortexM4l_math -lm +# alternative without archive + $(CXX) $(LDFLAGS) -o $@ $(REMOTE_OBJS) $(LOCAL_OBJS) -L$(OBJDIR) -larm_cortexM4l_math -lm +# $(CC) $(LDFLAGS) -o $@ $(LOCAL_OBJS) $(REMOTE_OBJS) -L$(OBJDIR) -lm +# $(CXX) $(LDFLAGS) -o $@ $(OBJS) -L$(OBJDIR) -lm + +else ifeq ($(BOARD_TAG),teensy31) +# arm-none-eabi-ar doesn't work with release 4.7.1 + $(CXX) $(LDFLAGS) -o $@ $(REMOTE_OBJS) $(LOCAL_OBJS) -L$(OBJDIR) -larm_cortexM4l_math -lm + +else + $(CC) $(LDFLAGS) -o $@ $(LOCAL_OBJS) $(TARGET_A) -lm +endif + + +# 8- Final conversions +# ---------------------------------- +# +$(OBJDIR)/%.hex: $(OBJDIR)/%.elf + $(call SHOW,"8.1-COPY",$@,$<) + $(call TRACE,"8-COPY",$@,$<) + $(OBJCOPY) -Oihex -R .eeprom $< $@ + +$(OBJDIR)/%.bin: $(OBJDIR)/%.elf + $(call SHOW,"8.2-COPY",$@,$<) + $(call TRACE,"8-COPY",$@,$<) + $(OBJCOPY) -Obinary -v $< $@ + +$(OBJDIR)/%.eep: $(OBJDIR)/%.elf + $(call SHOW,"8.3-COPY",$@,$<) + $(call TRACE,"8-COPY",$@,$<) + -$(OBJCOPY) -Oihex -j .eeprom --set-section-flags=.eeprom=alloc,load --no-change-warnings --change-section-lma .eeprom=0 $< $@ + +$(OBJDIR)/%.lss: $(OBJDIR)/%.elf + $(call SHOW,"8.4-COPY",$@,$<) + $(call TRACE,"8-COPY",$@,$<) + $(OBJDUMP) -h -S $< > $@ + +$(OBJDIR)/%.sym: $(OBJDIR)/%.elf + $(call SHOW,"8.5-COPY",$@,$<) + $(call TRACE,"8-COPY",$@,$<) + $(NM) -n $< > $@ + + +# Size of file +# ---------------------------------- +# +ifeq ($(TARGET_HEXBIN),$(TARGET_HEX)) + HEXSIZE = $(SIZE) --target=ihex --totals $(CURRENT_DIR)/$(TARGET_HEX) | grep TOTALS | tr '\t' . | cut -d. -f2 | tr -d ' ' +else ifeq ($(TARGET_HEXBIN),$(TARGET_BIN)) + BINSIZE = $(SIZE) --target=binary --totals $(CURRENT_DIR)/$(TARGET_BIN) | grep TOTALS | tr '\t' . | cut -d. -f2 | tr -d ' ' +endif + +ifndef MAX_FLASH_SIZE + MAX_FLASH_SIZE = $(call PARSE_BOARD,$(BOARD_TAG),upload.maximum_size) +endif +ifndef MAX_RAM_SIZE + MAX_RAM_SIZE = $(call PARSE_BOARD,$(BOARD_TAG),upload.maximum_data_size) +endif +ELFSIZE = $(SIZE) $(CURRENT_DIR)/$(TARGET_ELF) +RAMSIZE = $(SIZE) $(CURRENT_DIR)/$(TARGET_ELF) | sed '1d' | awk '{t=$$3 + $$2} END {print t}' + +#PROGRAM_SIZE = $(SIZE) $(CURRENT_DIR)/$(TARGET_ELF) -C | grep Program: | cut -d: -f2 | sed -e 's/^[ \t]*//' + +#DATA_SIZE = $(SIZE) $(CURRENT_DIR)/$(TARGET_ELF) -C | grep Data: | cut -d: -f2 | sed -e 's/^[ \t]*//' + + +ifneq ($(MAX_FLASH_SIZE),) + MAX_FLASH_BYTES = 'bytes (of a '$(MAX_FLASH_SIZE)' byte maximum)' +else + MAX_FLASH_BYTES = bytes +endif + +ifneq ($(MAX_RAM_SIZE),) + MAX_RAM_BYTES = 'bytes (of a '$(MAX_RAM_SIZE)' byte maximum)' +else + MAX_RAM_BYTES = bytes +endif + + +# Serial monitoring +# ---------------------------------- +# + +# First /dev port +# +ifndef SERIAL_PORT + SERIAL_PORT = $(firstword $(wildcard $(BOARD_PORT))) +endif + +ifndef SERIAL_BAUDRATE + SERIAL_BAUDRATE = 9600 +endif + +ifndef SERIAL_COMMAND + SERIAL_COMMAND = screen +endif + +STARTCHRONO = $(shell $(UTILITIES_PATH)/embedXcode_chrono) +STOPCHRONO = $(shell $(UTILITIES_PATH)/embedXcode_chrono -s) + +ifeq ($(PLATFORM),Energia) + USED_SERIAL_PORT = $(lastword $(wildcard $(BOARD_PORT))) +# $(shell ls -1 $(BOARD_PORT) | tail -1 > $(UTILITIES_PATH)/serial.txt) +# $(shell ls -1 $(BOARD_PORT) | head -1 > $(UTILITIES_PATH)/serial.txt) +else + USED_SERIAL_PORT = $(firstword $(wildcard $(BOARD_PORT))) +endif + +#BOARD_PORT := $(shell $(UTILITIES_PATH)/embedXcode_serial $(BOARD_PORT)) + + +# Info for debugging +# ---------------------------------- +# +# 0- Info +# +info: + @if [ -f $(CURRENT_DIR)/About/About.txt ]; then $(CAT) $(CURRENT_DIR)/About/About.txt; fi; + @if [ -f $(UTILITIES_PATH)/embedXcode_check ]; then $(UTILITIES_PATH)/embedXcode_check; fi + @echo $(STARTCHRONO) + $(call TRACE,"0-START",) + +ifneq ($(MAKECMDGOALS),boards) +ifneq ($(MAKECMDGOALS),clean) + + @echo ==== Info ==== + @echo ---- Project ---- + @echo 'Target '$(MAKECMDGOALS) + @echo 'Name '$(PROJECT_NAME) + @echo 'Tag '$(BOARD_TAG) + @echo 'Extension '$(SKETCH_EXTENSION) + + @echo 'User '$(USER_PATH) + +ifneq ($(PLATFORM),Wiring) + @echo ---- Platform ---- + @echo 'IDE '$(PLATFORM) + +ifneq ($(PLATFORM),MapleIDE) + @echo 'Version '$(shell cat $(APPLICATION_PATH)/lib/version.txt) +else + @echo 'Version '$(shell cat $(APPLICATION_PATH)/lib/build-version.txt) +endif +endif + +ifneq ($(WARNING_MESSAGE),) + @echo 'WARNING ''$(WARNING_MESSAGE)' +endif + +ifneq ($(BUILD_CORE),) + @echo 'Platform '$(BUILD_CORE) +endif + +ifneq ($(VARIANT),) + @echo 'Variant '$(VARIANT) +endif + +ifneq ($(USB_VID),) + @echo 'USB VID '$(USB_VID) +endif + +ifneq ($(USB_PID),) + @echo 'USB PID '$(USB_PID) +endif + + @echo ---- Board ---- + @echo 'Name ''$(BOARD_NAME)' + @echo 'Frequency '$(F_CPU) + @echo 'MCU '$(MCU) +ifneq ($(MAX_FLASH_SIZE),) + @echo 'Flash memory '$(MAX_FLASH_SIZE)' bytes' +endif +ifneq ($(MAX_RAM_SIZE),) + @echo 'SRAM memory '$(MAX_RAM_SIZE)' bytes' +endif + + @echo ---- Port ---- + @echo 'Uploader '$(UPLOADER) + +ifeq ($(UPLOADER),avrdude) + @echo 'AVRdude '$(AVRDUDE_PORT) + ifneq ($(AVRDUDE_PROGRAMMER),) + @echo 'Programmer '$(AVRDUDE_PROGRAMMER) + endif +endif +ifeq ($(UPLOADER),mspdebug) + @echo 'Protocol '$(MSPDEBUG_PROTOCOL) +endif + +ifeq ($(AVRDUDE_NO_SERIAL_PORT),1) + @echo 'Serial no serial port' +else + @echo 'Serial '$(USED_SERIAL_PORT) +endif + + @echo ---- Libraries ---- + @echo . Core libraries from $(CORE_LIB_PATH) | cut -d. -f1,2 + @echo $(CORE_LIBS_LIST) + + @echo . Application libraries from $(basename $(APP_LIB_PATH)) | cut -d. -f1,2 + @echo $(APP_LIBS_LIST) + + @echo . User libraries from $(SKETCHBOOK_DIR) + @echo $(USER_LIBS_LIST) + + @echo . Local libraries from $(CURRENT_DIR) + +ifneq ($(wildcard *.h),) + @echo $(subst .h,,$(wildcard *.h)) +else + @echo 0 +endif + + @echo ==== Info done ==== +endif +endif + + +# Release management +# ---------------------------------- +# +RELEASE_NOW := 141 + + +# Rules +# ---------------------------------- +# +all: info message_all clean compile reset raw_upload serial end_all prepare + +build: info message_build clean compile end_build prepare + +compile: info message_compile $(OBJDIR) $(TARGET_HEXBIN) $(TARGET_EEP) size + @echo $(BOARD_TAG) > $(NEW_TAG) + +prepare: + @if [ -f $(UTILITIES_PATH)/embedXcode_prepare ]; then $(UTILITIES_PATH)/embedXcode_prepare $(SCOPE_FLAG) "$(USER_LIB_PATH)"; rm -r $(UTILITIES_PATH)/embedXcode_prepare; fi; + +$(OBJDIR): + @echo "---- Build ---- " + @mkdir $(OBJDIR) + +#$(TARGET_ELF): $(OBJS) +# @echo "7-" $< +#ifeq ($(PLATFORM),MapleIDE) +# $(CXX) $(LDFLAGS) -o $@ $(OBJS) $(SYS_OBJS) -L$(OBJDIR) +#else +# $(CC) $(LDFLAGS) -o $@ $(OBJS) $(SYS_OBJS) -lc +#endif + +$(DEP_FILE): $(OBJDIR) $(DEPS) + @echo "9-" $< + @cat $(DEPS) > $(DEP_FILE) + + +upload: message_upload reset raw_upload + @echo "==== upload done ==== " + + +reset: + @echo "---- Reset ---- " + -screen -X kill + sleep 1 +ifeq ($(UPLOADER),dfu-util) + $(call SHOW,"9.1-RESET",$(DFU_RESET)) + $(call TRACE,"9-RESET",$(DFU_RESET)) + $(DFU_RESET) + sleep 1 +endif + +ifdef USB_RESET +# Method 1 + $(call SHOW,"9.2-RESET",USB_RESET 1200) + $(call TRACE,"9-RESET",USB_RESET 1200) + stty -f $(AVRDUDE_PORT) 1200 + sleep 2 +# Method 2 +# $(USB_RESET) $(AVRDUDE_PORT) +# sleep 2 +endif + +# stty on MacOS likes -F, but on Debian it likes -f redirecting +# stdin/out appears to work but generates a spurious error on MacOS at +# least. Perhaps it would be better to just do it in perl ? +# @if [ -z "$(AVRDUDE_PORT)" ]; then \ +# echo "No Arduino-compatible TTY device found -- exiting"; exit 2; \ +# fi +# for STTYF in 'stty --file' 'stty -f' 'stty <' ; \ +# do $$STTYF /dev/tty >/dev/null 2>/dev/null && break ; \ +# done ;\ +# $$STTYF $(AVRDUDE_PORT) hupcl ;\ +# (sleep 0.1 || sleep 1) ;\ +# $$STTYF $(AVRDUDE_PORT) -hupcl + + +raw_upload: + @echo "---- Upload ---- " + +ifeq ($(UPLOADER),micronucleus) + osascript -e 'tell application "System Events" to display dialog "Click OK and plug the Digispark into the USB port." buttons {"OK"} with icon POSIX file ("$(UTILITIES_PATH)/TemplateIcon.icns") with title "embedXcode"' + $(call SHOW,"9.1-UPLOAD",$(UPLOADER)) + $(call TRACE,"9-UPLOAD",$(UPLOADER)) + $(AVRDUDE_EXEC) $(AVRDUDE_COM_OPTS) $(AVRDUDE_OPTS) -P$(USED_SERIAL_PORT) -Uflash:w:$(TARGET_HEX):i + +else ifeq ($(UPLOADER),avrdude) + $(call SHOW,"9.3-UPLOAD",$(UPLOADER)) + $(call TRACE,"9-UPLOAD",$(UPLOADER)) + $(AVRDUDE_EXEC) $(AVRDUDE_COM_OPTS) $(AVRDUDE_OPTS) -P$(USED_SERIAL_PORT) -Uflash:w:$(TARGET_HEX):i + + ifeq ($(AVRDUDE_PROGRAMMER),avr109) + sleep 2 + endif + +else ifeq ($(UPLOADER),bossac) + $(call SHOW,"9.4-UPLOAD",$(UPLOADER)) + $(call TRACE,"9-UPLOAD",$(UPLOADER)) + $(BOSSAC) $(BOSSAC_OPTS) $(TARGET_BIN) -R + +else ifeq ($(UPLOADER),mspdebug) + $(call SHOW,"9.5-UPLOAD",$(UPLOADER)) + $(call TRACE,"9-UPLOAD",$(UPLOADER)) + +ifeq ($(MSPDEBUG_PROTOCOL),tilib) +# libmsp430.so needs to be in the current directory +# Solution 1: change directory doesn't work +# cd $(MSPDEBUG_PATH) +# $(MSPDEBUG) $(MSPDEBUG_OPTS) "$(MSPDEBUG_COMMAND) $(TARGET_HEX)" +# cd $(CURRENT_DIR) + +# Solution 2: make a copy of libmsp430.so in the current directory + @cp $(MSPDEBUG_PATH)/libmsp430.so . + $(MSPDEBUG) $(MSPDEBUG_OPTS) "$(MSPDEBUG_COMMAND) $(TARGET_HEX)" + @rm libmsp430.so + @rm comm.log + +else + $(MSPDEBUG) $(MSPDEBUG_OPTS) "$(MSPDEBUG_COMMAND) $(TARGET_HEX)" +endif + +else ifeq ($(UPLOADER),lm4flash) + $(call SHOW,"9.6-UPLOAD",$(UPLOADER)) + $(call TRACE,"9-UPLOAD",$(UPLOADER)) + $(LM4FLASH) $(LM4FLASH_OPTS) $(TARGET_BIN) + +else ifeq ($(UPLOADER),dfu-util) + $(call SHOW,"9.7-UPLOAD",$(UPLOADER)) + $(call TRACE,"9-UPLOAD",$(UPLOADER)) + $(DFU_UTIL) $(DFU_UTIL_OPTS) -D $(TARGET_BIN) -R + sleep 4 + $(info .) + +else ifeq ($(UPLOADER),teensy_flash) + $(call SHOW,"9.8-UPLOAD",$(UPLOADER)) + $(call TRACE,"9-UPLOAD",$(UPLOADER)) + $(TEENSY_POST_COMPILE) -file=$(basename $(notdir $(TARGET_HEX))) -path=$(dir $(abspath $(TARGET_HEX))) -tools=$(abspath $(TEENSY_FLASH_PATH))/ + sleep 2 + $(TEENSY_REBOOT) + sleep 2 + +else + $(error No valid uploader) +endif + + +ispload: $(TARGET_HEX) + @echo "---- ISP upload ---- " +ifeq ($(UPLOADER),avrdude) + $(call SHOW,"9.9-UPLOAD",$(UPLOADER)) + $(call TRACE,"9-UPLOAD",$(UPLOADER)) + $(AVRDUDE_EXEC) $(AVRDUDE_COM_OPTS) $(AVRDUDE_ISP_OPTS) -e \ + -U lock:w:$(ISP_LOCK_FUSE_PRE):m \ + -U hfuse:w:$(ISP_HIGH_FUSE):m \ + -U lfuse:w:$(ISP_LOW_FUSE):m \ + -U efuse:w:$(ISP_EXT_FUSE):m + $(AVRDUDE_EXEC) $(AVRDUDE_COM_OPTS) $(AVRDUDE_ISP_OPTS) -D \ + -U flash:w:$(TARGET_HEX):i + $(AVRDUDE_EXEC) $(AVRDUDE_COM_OPTS) $(AVRDUDE_ISP_OPTS) \ + -U lock:w:$(ISP_LOCK_FUSE_POST):m +endif + +serial: reset + @echo "---- Serial ---- " +ifeq ($(AVRDUDE_NO_SERIAL_PORT),1) + @echo "The programmer provides no serial port" +else + osascript -e 'tell application "Terminal" to do script "$(SERIAL_COMMAND) $(USED_SERIAL_PORT) $(SERIAL_BAUDRATE)"' +endif + +# echo "$@" +# echo "-- " +# export TERM="vt100" +# echo "#!/bin/sh" /tmp/arduino.command +# echo "$(SERIAL_COMMAND) $(SERIAL_PORT) $(SERIAL_BAUDRATE)" > /tmp/arduino.command +# chmod 0755 /tmp/arduino.command +# open /tmp/arduino.command + +size: + @echo "---- Size ----" +# echo 'PROGRAM_SIZE ' $(shell $(PROGRAM_SIZE)) +# echo 'DATA_SIZE ' $(shell $(DATA_SIZE)) + @if [ -f $(TARGET_HEX) ]; then echo 'Binary sketch size: ' $(shell $(HEXSIZE)) $(MAX_FLASH_BYTES); echo; fi +# @if [ -f $(TARGET_ELF) ]; then $(ELFSIZE); echo; fi + @if [ -f $(TARGET_BIN) ]; then echo 'Binary sketch size:' $(shell $(BINSIZE)) $(MAX_FLASH_BYTES); echo; fi + @if [ -f $(TARGET_ELF) ]; then echo 'Estimated SRAM used:' $(shell $(RAMSIZE)) $(MAX_RAM_BYTES); echo; fi +# @echo PROGRAM_SIZE $(PROGRAM_SIZE) +# @echo DATA_SIZE $(DATA_SIZE) + @echo 'Elapsed time:' $(STOPCHRONO) +# @if [ -n '$(MESSAGE_LINE)' ]; then echo 'Message: $(MESSAGE_LINE)'; fi; + +clean: + @if [ ! -d $(OBJDIR) ]; then mkdir $(OBJDIR); fi + @echo "nil" > $(OBJDIR)/nil + @echo "---- Clean ----" + -@rm -r $(OBJDIR)/* # */ + +changed: + @echo "---- Clean changed ----" +ifeq ($(CHANGE_FLAG),1) + @if [ ! -d $(OBJDIR) ]; then mkdir $(OBJDIR); fi + @echo "nil" > $(OBJDIR)/nil + $(REMOVE) $(OBJDIR)/* # */ +else +# $(REMOVE) $(LOCAL_OBJS) + for f in $(LOCAL_OBJS); do if [ -f $$f ]; then rm $$f; fi; done +endif + +depends: $(DEPS) + @echo "---- Depends ---- " + @cat $(DEPS) > $(DEP_FILE) + +boards: + @echo "==== Boards ====" + @echo "Tag=Name" + @if [ -f $(ARDUINO_PATH)/hardware/arduino/boards.txt ]; then echo "---- $(notdir $(basename $(ARDUINO_APP))) ---- "; \ + grep .name $(ARDUINO_PATH)/hardware/arduino/boards.txt; echo; fi + @if [ -d $(ARDUINO_PATH)/hardware/arduino/sam ]; then echo "---- $(notdir $(basename $(ARDUINO_APP))) SAM ---- "; \ + grep .name $(ARDUINO_PATH)/hardware/arduino/sam/boards.txt; echo; fi + @if [ -d $(ARDUINO_PATH)/hardware/arduino/avr ]; then echo "---- $(notdir $(basename $(ARDUINO_APP))) AVR ---- "; \ + grep .name $(ARDUINO_PATH)/hardware/arduino/avr/boards.txt; echo; fi + @if [ -d $(MPIDE_APP) ]; then echo "---- $(notdir $(basename $(MPIDE_APP))) ---- "; \ + grep .name $(MPIDE_PATH)/hardware/pic32/boards.txt; echo; fi + @if [ -d $(DIGISPARK_APP) ]; then echo "---- $(notdir $(basename $(DIGISPARK_APP))) ---- "; \ + grep .name $(DIGISPARK_PATH)/hardware/digispark/boards.txt; echo; fi + @if [ -d $(ENERGIA_APP) ]; then echo "---- $(notdir $(basename $(ENERGIA_APP))) MSP430 ---- "; \ + grep .name $(ENERGIA_PATH)/hardware/msp430/boards.txt; echo; fi + @if [ -d $(ENERGIA_PATH)/hardware/lm4f ]; then echo "---- $(notdir $(basename $(ENERGIA_APP))) LM4F ---- "; \ + grep .name $(ENERGIA_PATH)/hardware/lm4f/boards.txt; echo; fi + @if [ -d $(MAPLE_APP) ]; then echo "---- $(notdir $(basename $(MAPLE_APP))) ---- "; \ + grep .name $(MAPLE_PATH)/hardware/leaflabs/boards.txt; echo; fi + @if [ -d $(MICRODUINO_APP) ]; then echo "---- $(notdir $(basename $(MICRODUINO_APP))) ---- "; \ + grep .name $(MICRODUINO_PATH)/hardware/Microduino/boards.txt; echo; fi + @if [ -d $(TEENSY_APP) ]; then echo "---- $(notdir $(basename $(TEENSY_APP))) ---- "; \ + grep .name $(TEENSY_PATH)/hardware/teensy/boards.txt | grep -v menu; echo; fi + @if [ -d $(WIRING_APP) ]; then echo "---- $(notdir $(basename $(WIRING_APP))) ---- "; \ + grep .name $(WIRING_PATH)/hardware/Wiring/boards.txt; echo; fi + @echo "==== Boards done ==== " + +message_all: + @echo "==== All ====" + +message_build: + @echo "==== Build ====" + +message_compile: + @echo "---- Compile ----" + +message_upload: + @echo "==== Upload ====" + +end_all: + @echo "==== All done ==== " + +end_build: + @echo "==== Build done ==== " + + +.PHONY: all clean depends upload raw_upload reset serial show_boards headers size document diff --git a/FastLED/FastLED/Makefiles/Teensy.mk b/FastLED/FastLED/Makefiles/Teensy.mk new file mode 100755 index 00000000..331388a5 --- /dev/null +++ b/FastLED/FastLED/Makefiles/Teensy.mk @@ -0,0 +1,57 @@ +# +# embedXcode +# ---------------------------------- +# Embedded Computing on Xcode +# +# Copyright © Rei VILO, 2010-2014 +# http://embedxcode.weebly.com +# All rights reserved +# +# +# Last update: Feb 01, 2014 release 129 + + + +# Teensy specifics +# ---------------------------------- +# +PLATFORM := Teensy +PLATFORM_TAG = ARDUINO=105 TEENSYDUINO=117 EMBEDXCODE=$(RELEASE_NOW) +APPLICATION_PATH := $(TEENSY_PATH) + + +# Automatic Teensy2 or Teensy 3 selection based on build.core +# +BOARDS_TXT := $(APPLICATION_PATH)/hardware/teensy/boards.txt +BUILD_CORE = $(call PARSE_BOARD,$(BOARD_TAG),build.core) + +ifeq ($(BUILD_CORE),teensy) + include $(MAKEFILE_PATH)/Teensy2.mk +else ifeq ($(BUILD_CORE),teensy3) + include $(MAKEFILE_PATH)/Teensy3.mk +else + $(error $(BUILD_CORE) unknown) +endif + +# Teensy USB PID VID +# +USB_VID := $(call PARSE_BOARD,$(BOARD_TAG),build.vid) +USB_PID := $(call PARSE_BOARD,$(BOARD_TAG),build.pid) + +ifneq ($(USB_PID),) +ifneq ($(USB_VID),) + USB_FLAGS = -DUSB_VID=$(USB_VID) + USB_FLAGS += -DUSB_PID=$(USB_PID) +endif +endif + +ifeq ($(USB_FLAGS),) + USB_FLAGS = -DUSB_VID=null -DUSB_PID=null +endif + +USB_FLAGS += -DUSB_SERIAL -DLAYOUT_US_ENGLISH -DTIME_T=$(shell date +%s) + +MAX_RAM_SIZE = $(call PARSE_BOARD,$(BOARD_TAG),upload.maximum_ram_size) + + + diff --git a/FastLED/FastLED/Makefiles/Teensy2.mk b/FastLED/FastLED/Makefiles/Teensy2.mk new file mode 100755 index 00000000..851d8eaa --- /dev/null +++ b/FastLED/FastLED/Makefiles/Teensy2.mk @@ -0,0 +1,99 @@ +# +# embedXcode +# ---------------------------------- +# Embedded Computing on Xcode +# +# Copyright © Rei VILO, 2010-2014 +# http://embedxcode.weebly.com +# All rights reserved +# +# +# Last update: Mar 01, 2014 release 136 + + + +# Teensy 2.0 specifics +# ---------------------------------- +# +BUILD_CORE := avr + +UPLOADER = teensy_flash +TEENSY_FLASH_PATH = $(APPLICATION_PATH)/hardware/tools/avr/bin +TEENSY_POST_COMPILE = $(TEENSY_FLASH_PATH)/teensy_post_compile +TEENSY_REBOOT = $(TEENSY_FLASH_PATH)/teensy_reboot + +APP_TOOLS_PATH := $(APPLICATION_PATH)/hardware/tools/avr/bin +CORE_LIB_PATH := $(APPLICATION_PATH)/hardware/teensy/cores/teensy +APP_LIB_PATH := $(APPLICATION_PATH)/libraries + +BUILD_CORE_LIB_PATH = $(APPLICATION_PATH)/hardware/teensy/cores/teensy3/avr +BUILD_CORE_LIBS_LIST = $(subst .h,,$(subst $(BUILD_CORE_LIB_PATH)/,,$(wildcard $(BUILD_CORE_LIB_PATH)/*.h))) # */ +BUILD_CORE_C_SRCS = $(wildcard $(BUILD_CORE_LIB_PATH)/*.c) # */ + +ifneq ($(strip $(NO_CORE_MAIN_FUNCTION)),) + BUILD_CORE_CPP_SRCS = $(filter-out %program.cpp %main.cpp,$(wildcard $(BUILD_CORE_LIB_PATH)/*.cpp)) # */ +else + BUILD_CORE_CPP_SRCS = $(filter-out %program.cpp, $(wildcard $(BUILD_CORE_LIB_PATH)/*.cpp)) # */ +endif + +BUILD_CORE_OBJ_FILES = $(BUILD_CORE_C_SRCS:.c=.o) $(BUILD_CORE_CPP_SRCS:.cpp=.o) +BUILD_CORE_OBJS = $(patsubst $(BUILD_CORE_LIB_PATH)/%,$(OBJDIR)/%,$(BUILD_CORE_OBJ_FILES)) + +# Sketchbook/Libraries path +# wildcard required for ~ management +# ?ibraries required for libraries and Libraries +# +ifeq ($(USER_PATH)/Library/Arduino/preferences.txt,) + $(error Error: run Teensy once and define the sketchbook path) +endif + +ifeq ($(wildcard $(SKETCHBOOK_DIR)),) + SKETCHBOOK_DIR = $(shell grep sketchbook.path $(wildcard ~/Library/Arduino/preferences.txt) | cut -d = -f 2) +endif + +ifeq ($(wildcard $(SKETCHBOOK_DIR)),) + $(error Error: sketchbook path not found) +endif + +USER_LIB_PATH = $(wildcard $(SKETCHBOOK_DIR)/?ibraries) + + +# Rules for making a c++ file from the main sketch (.pde) +# +PDEHEADER = \\\#include \"WProgram.h\" + + +# Tool-chain names +# +CC = $(APP_TOOLS_PATH)/avr-gcc +CXX = $(APP_TOOLS_PATH)/avr-g++ +AR = $(APP_TOOLS_PATH)/avr-ar +OBJDUMP = $(APP_TOOLS_PATH)/avr-objdump +OBJCOPY = $(APP_TOOLS_PATH)/avr-objcopy +SIZE = $(APP_TOOLS_PATH)/avr-size +NM = $(APP_TOOLS_PATH)/avr-nm + + +#LDSCRIPT = $(call PARSE_BOARD,$(BOARD_TAG),build.linkscript) +#VARIANT = $(call PARSE_BOARD,$(BOARD_TAG),build.variant) +#VARIANT_PATH = $(APPLICATION_PATH)/hardware/lm4f/variants/$(VARIANT) + +MCU_FLAG_NAME = mmcu +MCU = atmega32u4 +F_CPU = 16000000 + +#EXTRA_LDFLAGS = -T$(CORE_LIB_PATH)/$(LDSCRIPT) -mthumb + +# CXX = flags for C++ only +# CPP = flags for both C and C++ +# +EXTRA_CPPFLAGS = $(addprefix -D, $(PLATFORM_TAG)) -D__AVR_ATmega32U4__ -nostdlib -MMD +EXTRA_CXXFLAGS = -fno-rtti -felide-constructors -std=c++0x + + +#EXTRA_CPPFLAGS += $(call PARSE_BOARD,$(BOARD_TAG),build.option3) # -D__MK20DX128__ + +OBJCOPYFLAGS = -R .eeprom -Oihex +TARGET_HEXBIN = $(TARGET_HEX) +TARGET_EEP = $(OBJDIR)/$(TARGET).eep + diff --git a/FastLED/FastLED/Makefiles/Teensy3.mk b/FastLED/FastLED/Makefiles/Teensy3.mk new file mode 100755 index 00000000..9d3b8d82 --- /dev/null +++ b/FastLED/FastLED/Makefiles/Teensy3.mk @@ -0,0 +1,96 @@ +# +# embedXcode +# ---------------------------------- +# Embedded Computing on Xcode +# +# Copyright © Rei VILO, 2010-2014 +# http://embedxcode.weebly.com +# All rights reserved +# +# +# Last update: Mar 01, 2014 release 136 + + + +# Teensy 3.0 specifics +# ---------------------------------- +# +BUILD_CORE := arm + +UPLOADER = teensy_flash +TEENSY_FLASH_PATH = $(APPLICATION_PATH)/hardware/tools +TEENSY_POST_COMPILE = $(TEENSY_FLASH_PATH)/teensy_post_compile +TEENSY_REBOOT = $(TEENSY_FLASH_PATH)/teensy_reboot + +APP_TOOLS_PATH := $(APPLICATION_PATH)/hardware/tools/arm-none-eabi/bin +CORE_LIB_PATH := $(APPLICATION_PATH)/hardware/teensy/cores/teensy3 +APP_LIB_PATH := $(APPLICATION_PATH)/libraries + +BUILD_CORE_LIB_PATH = $(APPLICATION_PATH)/hardware/teensy/cores/teensy3/avr +BUILD_CORE_LIBS_LIST = $(subst .h,,$(subst $(BUILD_CORE_LIB_PATH)/,,$(wildcard $(BUILD_CORE_LIB_PATH)/*/*.h))) # */ +BUILD_CORE_C_SRCS = $(wildcard $(BUILD_CORE_LIB_PATH)/*.c) # */ + +ifneq ($(strip $(NO_CORE_MAIN_FUNCTION)),) + BUILD_CORE_CPP_SRCS = $(filter-out %program.cpp %main.cpp,$(wildcard $(BUILD_CORE_LIB_PATH)/*.cpp)) # */ +else + BUILD_CORE_CPP_SRCS = $(filter-out %program.cpp, $(wildcard $(BUILD_CORE_LIB_PATH)/*.cpp)) # */ +endif + +BUILD_CORE_OBJ_FILES = $(BUILD_CORE_C_SRCS:.c=.o) $(BUILD_CORE_CPP_SRCS:.cpp=.o) +BUILD_CORE_OBJS = $(patsubst $(BUILD_CORE_LIB_PATH)/%,$(OBJDIR)/%,$(BUILD_CORE_OBJ_FILES)) + +# Sketchbook/Libraries path +# wildcard required for ~ management +# ?ibraries required for libraries and Libraries +# +ifeq ($(USER_PATH)/Library/Arduino/preferences.txt,) + $(error Error: run Arduino with Teensy plug-in once and define the sketchbook path) +endif + +ifeq ($(wildcard $(SKETCHBOOK_DIR)),) + SKETCHBOOK_DIR = $(shell grep sketchbook.path $(wildcard ~/Library/Arduino/preferences.txt) | cut -d = -f 2) +endif + +ifeq ($(wildcard $(SKETCHBOOK_DIR)),) + $(error Error: sketchbook path not found) +endif + +USER_LIB_PATH = $(wildcard $(SKETCHBOOK_DIR)/?ibraries) + + +# Rules for making a c++ file from the main sketch (.pde) +# +PDEHEADER = \\\#include \"WProgram.h\" + + +# Tool-chain names +# +CC = $(APP_TOOLS_PATH)/arm-none-eabi-gcc +CXX = $(APP_TOOLS_PATH)/arm-none-eabi-g++ +AR = $(APP_TOOLS_PATH)/arm-none-eabi-ar +OBJDUMP = $(APP_TOOLS_PATH)/arm-none-eabi-objdump +OBJCOPY = $(APP_TOOLS_PATH)/arm-none-eabi-objcopy +SIZE = $(APP_TOOLS_PATH)/arm-none-eabi-size +NM = $(APP_TOOLS_PATH)/arm-none-eabi-nm + + +LDSCRIPT = $(call PARSE_BOARD,$(BOARD_TAG),build.linkscript) +#VARIANT = $(call PARSE_BOARD,$(BOARD_TAG),build.variant) +#VARIANT_PATH = $(APPLICATION_PATH)/hardware/lm4f/variants/$(VARIANT) + +MCU_FLAG_NAME = mcpu +MCU = $(call PARSE_BOARD,$(BOARD_TAG),build.cpu) +F_CPU = 96000000 + +EXTRA_LDFLAGS = -mthumb -T$(CORE_LIB_PATH)/$(LDSCRIPT) + +# CXX = flags for C++ only +# CPP = flags for both C and C++ +# +EXTRA_CPPFLAGS = $(addprefix -D, $(PLATFORM_TAG)) $(call PARSE_BOARD,$(BOARD_TAG),build.option3) -nostdlib -mthumb -MMD +EXTRA_CXXFLAGS = -fno-exceptions -fno-rtti -felide-constructors -std=gnu++0x + +OBJCOPYFLAGS = -R .eeprom -O ihex +TARGET_HEXBIN = $(TARGET_HEX) +TARGET_EEP = $(OBJDIR)/$(TARGET).eep + diff --git a/FastLED/FastLED/Makefiles/Wiring.mk b/FastLED/FastLED/Makefiles/Wiring.mk new file mode 100755 index 00000000..115bad28 --- /dev/null +++ b/FastLED/FastLED/Makefiles/Wiring.mk @@ -0,0 +1,123 @@ +# +# embedXcode +# ---------------------------------- +# Embedded Computing on Xcode +# +# Copyright © Rei VILO, 2010-2014 +# http://embedxcode.weebly.com +# All rights reserved +# +# +# Last update: Mar 01, 2014 release 136 + +# WIRING SUPPORT IS PUT ON HOLD +WARNING_MESSAGE = 'WIRING SUPPORT IS PUT ON HOLD' + + +# Wiring specifics +# ---------------------------------- +# +PLATFORM := Wiring +PLATFORM_TAG = WIRING=100 EMBEDXCODE=$(RELEASE_NOW) +APPLICATION_PATH := $(WIRING_PATH) + +APP_TOOLS_PATH := $(APPLICATION_PATH)/tools/avr/bin +CORE_LIB_PATH := $(APPLICATION_PATH)/cores/Common +APP_LIB_PATH := $(APPLICATION_PATH)/libraries +BOARDS_TXT := $(APPLICATION_PATH)/hardware/Wiring/boards.txt + +# Sketchbook/Libraries path +# wildcard required for ~ management +# ?ibraries required for libraries and Libraries +# +ifeq ($(USER_PATH)/Library/Wiring/preferences.txt,) + $(error Error: run Wiring once and define the sketchbook path) +endif + +ifeq ($(wildcard $(SKETCHBOOK_DIR)),) + SKETCHBOOK_DIR = $(shell grep sketchbook.path $(USER_PATH)/Library/Wiring/preferences.txt | cut -d = -f 2) +endif +ifeq ($(wildcard $(SKETCHBOOK_DIR)),) + $(error Error: sketchbook path not found) +endif +USER_LIB_PATH = $(wildcard $(SKETCHBOOK_DIR)/?ibraries) + +# Rules for making a c++ file from the main sketch (.pde) +# +PDEHEADER = \\\#include \"Wiring.h\" + +# Tool-chain names +# +CC = $(APP_TOOLS_PATH)/avr-gcc +CXX = $(APP_TOOLS_PATH)/avr-g++ +AR = $(APP_TOOLS_PATH)/avr-ar +OBJDUMP = $(APP_TOOLS_PATH)/avr-objdump +OBJCOPY = $(APP_TOOLS_PATH)/avr-objcopy +SIZE = $(APP_TOOLS_PATH)/avr-size +NM = $(APP_TOOLS_PATH)/avr-nm + +# Specific AVRDUDE location and options +# +AVRDUDE_PATH = $(APPLICATION_PATH)/tools/avr +AVRDUDE = $(AVRDUDE_PATH)/bin/avrdude +AVRDUDE_CONF = $(AVRDUDE_PATH)/bin/avrdude.conf +AVRDUDE_COM_OPTS = -D -p$(MCU) -C$(AVRDUDE_CONF) + +BOARD = $(call PARSE_BOARD,$(BOARD_TAG),board) +#LDSCRIPT = $(call PARSE_BOARD,$(BOARD_TAG),ldscript) +VARIANT = $(call PARSE_BOARD,$(BOARD_TAG),build.hardware) +VARIANT_PATH = $(APPLICATION_PATH)/hardware/Wiring/$(VARIANT) +BUILD_CORE = $(call PARSE_BOARD,$(BOARD_TAG),build.core) + +BUILD_CORE_LIB_PATH = $(APPLICATION_PATH)/cores/$(BUILD_CORE) +BUILD_CORE_LIBS_LIST = $(subst .h,,$(subst $(BUILD_CORE_LIB_PATH)/,,$(wildcard $(BUILD_CORE_LIB_PATH)/*.h))) # */ + +BUILD_CORE_C_SRCS = $(wildcard $(BUILD_CORE_LIB_PATH)/*.c) # */ + +ifneq ($(strip $(NO_CORE_MAIN_FUNCTION)),) + BUILD_CORE_CPP_SRCS = $(filter-out %program.cpp %main.cpp,$(wildcard $(BUILD_CORE_LIB_PATH)/*.cpp)) # */ +else + BUILD_CORE_CPP_SRCS = $(filter-out %program.cpp, $(wildcard $(BUILD_CORE_LIB_PATH)/*.cpp)) # */ +endif + +BUILD_CORE_OBJ_FILES = $(BUILD_CORE_C_SRCS:.c=.o) $(BUILD_CORE_CPP_SRCS:.cpp=.o) +BUILD_CORE_OBJS = $(patsubst $(BUILD_CORE_LIB_PATH)/%,$(OBJDIR)/%,$(BUILD_CORE_OBJ_FILES)) + +# Extra variant library +# +VARIANT_CPP_SRC = $(wildcard $(VARIANT_PATH)/*.cpp) +VARIANT_OBJS = $(patsubst $(VARIANT_PATH)/%.cpp,$(OBJDIR)/libs/%.o,$(VARIANT_CPP_SRC)) # */ + +# Two locations for Wiring libraries +# +BUILD_APP_LIB_PATH = $(BUILD_CORE_LIB_PATH)/libraries + +ifndef APP_LIBS_LIST + w1 = $(realpath $(sort $(dir $(wildcard $(APP_LIB_PATH)/*/*.h $(APP_LIB_PATH)/*/*/*.h)))) # */ + APP_LIBS_LIST = $(subst $(APP_LIB_PATH)/,,$(filter-out $(EXCLUDE_LIST),$(w1))) + + w2 = $(realpath $(sort $(dir $(wildcard $(BUILD_APP_LIB_PATH)/*/*.h $(BUILD_APP_LIB_PATH)/*/*/*.h)))) # */ + BUILD_APP_LIBS_LIST = $(subst $(BUILD_APP_LIB_PATH)/,,$(filter-out $(EXCLUDE_LIST),$(w2))) +else + BUILD_APP_LIBS_LIST = $(APP_LIBS_LIST) +endif + +ifneq ($(APP_LIBS_LIST),0) + APP_LIBS = $(patsubst %,$(APP_LIB_PATH)/%,$(APP_LIBS_LIST)) + APP_LIB_CPP_SRC = $(wildcard $(patsubst %,%/*.cpp,$(APP_LIBS))) # */ + APP_LIB_C_SRC = $(wildcard $(patsubst %,%/*.c,$(APP_LIBS))) # */ + + APP_LIB_OBJS = $(patsubst $(APP_LIB_PATH)/%.cpp,$(OBJDIR)/libs/%.o,$(APP_LIB_CPP_SRC)) + APP_LIB_OBJS += $(patsubst $(APP_LIB_PATH)/%.c,$(OBJDIR)/libs/%.o,$(APP_LIB_C_SRC)) + + BUILD_APP_LIBS = $(patsubst %,$(BUILD_APP_LIB_PATH)/%,$(BUILD_APP_LIBS_LIST)) + BUILD_APP_LIB_CPP_SRC = $(wildcard $(patsubst %,%/*.cpp,$(BUILD_APP_LIBS))) # */ + BUILD_APP_LIB_C_SRC = $(wildcard $(patsubst %,%/*.c,$(BUILD_APP_LIBS))) # */ + + BUILD_APP_LIB_OBJS = $(patsubst $(BUILD_APP_LIB_PATH)/%.cpp,$(OBJDIR)/libs/%.o,$(BUILD_APP_LIB_CPP_SRC)) + BUILD_APP_LIB_OBJS += $(patsubst $(BUILD_APP_LIB_PATH)/%.c,$(OBJDIR)/libs/%.o,$(BUILD_APP_LIB_C_SRC)) +endif + +MCU_FLAG_NAME = mmcu +EXTRA_LDFLAGS = +EXTRA_CPPFLAGS = $(addprefix -D, $(PLATFORM_TAG)) -I$(CORE_LIB_PATH) -I$(BUILD_CORE_LIB_PATH) -I$(VARIANT_PATH) diff --git a/FastLED/FastLED/ReadMe.txt b/FastLED/FastLED/ReadMe.txt new file mode 100644 index 00000000..0a6d3b4f --- /dev/null +++ b/FastLED/FastLED/ReadMe.txt @@ -0,0 +1,26 @@ + + FastLED + Project + ---------------------------------- + Developed with embedXcode + + Project FastLED + Created by Daniel Garcia on 4/2/14 + Copyright © 2014 Daniel Garcia + License <#license#> + + + + References + ---------------------------------- + + + + embedXcode + embedXcode+ + ---------------------------------- + Embedded Computing on Xcode + Copyright © Rei VILO, 2010-2014 + All rights reserved + http://embedXcode.weebly.com + diff --git a/FastLED/FastLED/Sketchbook/Sketchbook.txt b/FastLED/FastLED/Sketchbook/Sketchbook.txt new file mode 100644 index 00000000..029dd8a5 --- /dev/null +++ b/FastLED/FastLED/Sketchbook/Sketchbook.txt @@ -0,0 +1,9 @@ + +Drag and drop your user library folder under the Sketchbook group. + +Then, +• Uncheck Copy items into destination group's folder (if necessary). +• Choose Folders Create groups for any added folders. +• Check Add to targets Index. + +Your user library folder is usually located at Sketchbook > Libraries. \ No newline at end of file diff --git a/FastLED/FastLED/Utilities/TemplateIcon.icns b/FastLED/FastLED/Utilities/TemplateIcon.icns new file mode 100644 index 00000000..80e2c3f0 Binary files /dev/null and b/FastLED/FastLED/Utilities/TemplateIcon.icns differ diff --git a/FastLED/FastLED/Utilities/embedXcode_check b/FastLED/FastLED/Utilities/embedXcode_check new file mode 100755 index 00000000..d8a7a710 Binary files /dev/null and b/FastLED/FastLED/Utilities/embedXcode_check differ diff --git a/FastLED/FastLED/Utilities/embedXcode_chrono b/FastLED/FastLED/Utilities/embedXcode_chrono new file mode 100755 index 00000000..7fec711d Binary files /dev/null and b/FastLED/FastLED/Utilities/embedXcode_chrono differ diff --git a/FastLED/FastLED/Utilities/embedXcode_prepare b/FastLED/FastLED/Utilities/embedXcode_prepare new file mode 100755 index 00000000..7ce78022 Binary files /dev/null and b/FastLED/FastLED/Utilities/embedXcode_prepare differ diff --git a/FastLED/FastLED/Utilities/reset.py b/FastLED/FastLED/Utilities/reset.py new file mode 100755 index 00000000..6410c563 --- /dev/null +++ b/FastLED/FastLED/Utilities/reset.py @@ -0,0 +1,124 @@ +#!/usr/bin/env python + +import serial +import os +import platform +import sys +import time +from struct import pack + +def unix_get_maple_path(file_prefix): + """Try to find the device file for the Maple on *nix; assuming + that it looks like /dev/*. If there are multiple + possibilities, ask the user what to do. If the user chooses not + to say, returns None.""" + possible_paths = [os.path.join('/dev', x) for x in os.listdir('/dev') \ + if x.startswith(file_prefix)] + return choose_path(possible_paths) + +def windows_get_maple_path(): + """Similar to unix_get_maple_path(), but on Windows.""" + import _winreg as reg + p = 'HARDWARE\\DEVICEMAP\\SERIALCOMM' + k = reg.OpenKey(reg.HKEY_LOCAL_MACHINE, p) + possible_paths = [] + i = 0 + while True: + try: + possible_paths.append(reg.EnumValue(k, i)[1]) + i += 1 + except WindowsError: + break + return choose_path(possible_paths) + +def choose_path(possible_paths): + if len(possible_paths) == 0: + return None + elif len(possible_paths) == 1: + return possible_paths[0] + else: + print 'Found multiple candidates for the Maple device:' + return choose_among_options(possible_paths) + +def choose_among_options(options): + for (i,p) in enumerate(options): + print '\t%d. %s' % (i+1, p) + + prompt = 'Enter a number to select one, or q to quit: ' + while True: + resp = raw_input(prompt).strip().lower() + if resp == 'q': sys.exit() + + try: + i = int(resp, 10) + except ValueError: + pass + else: + if 0 <= i-1 < len(options): + return options[i-1] + + prompt = 'Please enter a number from the list, or q to quit: ' + +plat_sys = platform.system() +plat_bits = platform.architecture()[0] +if plat_sys == 'Linux': + if plat_bits == '64bit': + print 'You appear to be using 64-bit Linux. Let us know if this works.' + maple_path = unix_get_maple_path('ttyACM') + # fall back on /dev/maple if that doesn't work + if maple_path is None: + maple_path = '/dev/maple' + print 'Could not find Maple serial port; defaulting to /dev/maple.' +elif plat_sys == 'Darwin': + maple_path = unix_get_maple_path('tty.usbmodem') +elif plat_sys == 'Windows': + maple_path = windows_get_maple_path() +else: + maple_path = raw_input('Unrecognized platform. Please enter ' + "the path to the Maple's serial port device file:") + +if maple_path is None: + print 'Could not find the Maple serial port for reset.', \ + 'Perhaps this is your first upload, or the board is already', \ + 'in bootloader mode.' + print + print "If your sketch doesn't upload, try putting your Maple", \ + 'into bootloader mode manually by pressing the RESET button', \ + 'then letting it go and quickly pressing button BUT', \ + '(hold for several seconds).' + sys.exit() + +print 'Using %s as Maple serial port' % maple_path + +try: + ser = serial.Serial(maple_path, baudrate=115200, xonxoff=1) + + try: + # try to toggle DTR/RTS (old scheme) + ser.setRTS(0) + time.sleep(0.01) + ser.setDTR(0) + time.sleep(0.01) + ser.setDTR(1) + time.sleep(0.01) + ser.setDTR(0) + + # try magic number + ser.setRTS(1) + time.sleep(0.01) + ser.setDTR(1) + time.sleep(0.01) + ser.setDTR(0) + time.sleep(0.01) + ser.write("1EAF") + + # Windows quirk: delay a bit before proceeding + if plat_sys == 'Windows': time.sleep(0.5) + finally: + # ok we're done here + ser.close() + +except Exception as e: + print 'Failed to open serial port %s for reset' % maple_path + sys.exit() + diff --git a/FastLED/FastLED/Utilities/serial1200.py b/FastLED/FastLED/Utilities/serial1200.py new file mode 100755 index 00000000..1e482c1c --- /dev/null +++ b/FastLED/FastLED/Utilities/serial1200.py @@ -0,0 +1,13 @@ +#!/usr/bin/env python + +import serial +import sys + +if len(sys.argv) < 2: + print "Missing serial port" + sys.exit() + +print 'Setting %s at 1200' % sys.argv[1] + +ser = serial.Serial(sys.argv[1], baudrate=1200) + diff --git a/FastLED/FastLED/main.cpp b/FastLED/FastLED/main.cpp new file mode 100644 index 00000000..dabe2749 --- /dev/null +++ b/FastLED/FastLED/main.cpp @@ -0,0 +1,475 @@ +// +// main.cpp +// Main file +// ---------------------------------- +// Developed with embedXcode +// http://embedXcode.weebly.com +// +// Project FastLED +// +// Created by Daniel Garcia, 4/2/14 8:09 PM +// Daniel Garcia +// +// Copyright © Daniel Garcia, 2014 +// License <#license#> +// +// See FastLED.ino and ReadMe.txt for references +// +// ---------------------------------- +// DO NOT EDIT THIS FILE. +// THE SKETCH IS IN FastLED.ino +// ---------------------------------- +// +// Last update: Mar 12, 2014 release 139 + +// IDE selection +#if defined(EMBEDXCODE) + +// Sketch +#include "FastLED.ino" + +// Core library and main() +#if defined(MPIDE) +// ============================================================================= chipKIT specific + +//************************************************************************ +//* main.c +//* +//* Arduino core files for PIC32 +//* Copyright (c) 2010, 2011 by Mark Sproul +//* +//* +//************************************************************************ +//* this code is based on code Copyright (c) 2005-2006 David A. Mellis +//* +//* This library is free software; you can redistribute it and/or +//* modify it under the terms of the GNU Lesser General Public +//* License as published by the Free Software Foundation; either +//* version 2.1 of the License, or (at your option) any later version. +//* +//* This library is distributed in the hope that it will be useful, +//* but WITHOUT ANY WARRANTY; without even the implied warranty of +//* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.//* See the GNU +//* Lesser General Public License for more details. +//* +//* You should have received a copy of the GNU Lesser General +//* Public License along with this library; if not, write to the +//* Free Software Foundation, Inc., 59 Temple Place, Suite 330, +//* Boston, MA 02111-1307 USA +//* +//* +//************************************************************************ +//* Edit History +//************************************************************************ +//* Oct 12, 2010 Got MPLAB X working on MacOSX 1.6 for the first time +//* Dec 12, 2011 added call to _scheduleTask() before call +//* to loop(). +//************************************************************************ + +#define OPT_SYSTEM_INTERNAL +#include + +#if (ARDUINO >= 100) +#include +#else +#include +#endif + +extern "C" { + extern void __use_isr_install(void); + __attribute__((section(".comment"))) void (*__use_force_isr_install)(void) = &__use_isr_install; +} + +//************************************************************************ +int main(void) +{ + init(); + + setup(); + + while (1) + { + _scheduleTask(); + loop(); + } + return 0; +} + + +#elif defined(DIGISPARK) +// ============================================================================= Digispark specific + +#include "WProgram.h" + +int main(void) +{ + init(); + + setup(); + + for (;;) + loop(); + + return 0; +} + + + +#elif defined(MICRODUINO) +// ============================================================================= Microduino specific + +#include "Arduino.h" + +int main(void) +{ + init(); + +#if defined(USBCON) + USBDevice.attach(); +#endif + + setup(); + + for (;;) { + loop(); + if (serialEventRun) serialEventRun(); + } + + return 0; +} + + +#elif defined(ENERGIA) +// ============================================================================= LaunchPad MSP430, Stellaris and Tiva, Experimeter Board FR5739 specific + +#if defined(__LM4F120H5QR__) || defined(__TM4C1230C3PM__) || defined(__TM4C129XNCZAD__) +// ----------------------------------------------------------------------------- LaunchPad Stellaris and Tiva specific +#include + +#if defined(PART_TM4C129XNCZAD) +#include "inc/tm4c129xnczad.h" +#elif defined(PART_TM4C1294NCPDT) +#include "inc/tm4c1294ncpdt.h" +#elif defined(PART_TM4C1233H6PM) || defined(PART_LM4F120H5QR) +#include "inc/tm4c123gh6pm.h" +#else +#error "**** No PART defined or unsupported PART ****" +#endif + +#include "inc/hw_gpio.h" +#include "driverlib/rom.h" +#include "driverlib/sysctl.h" +#include "driverlib/eeprom.h" + +int main(void) +{ + + ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_EEPROM0); + if(ROM_EEPROMInit() == EEPROM_INIT_ERROR) { + if(ROM_EEPROMInit() != EEPROM_INIT_ERROR) + EEPROMMassErase(); + } + + timerInit(); + + ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA); + ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB); + ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC); + ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD); + ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE); + ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF); + ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOG); + ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOH); + ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOJ); + ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOK); + ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOL); + ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOM); + ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPION); + ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOP); + ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOQ); +#ifdef TARGET_IS_SNOWFLAKE_RA0 + ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOR); + ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOS); + ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOT); +#endif + + //Unlock and commit NMI pins PD7 and PF0 + HWREG(GPIO_PORTF_BASE + GPIO_O_LOCK) = 0x4C4F434B; + HWREG(GPIO_PORTF_BASE + GPIO_O_CR) |= 0x1; + HWREG(GPIO_PORTD_BASE + GPIO_O_LOCK) = 0x4C4F434B; + HWREG(GPIO_PORTD_BASE + GPIO_O_CR) |= 0x80; + + setup(); + + for (;;) { + loop(); + if (serialEventRun) serialEventRun(); + } + +} + +#else +// ----------------------------------------------------------------------------- LaunchPad MSP430 and Experimeter Board FR5739 specific + +#include + +int main(void) +{ + init(); + + setup(); + + for (;;) { + loop(); + if (serialEventRun) serialEventRun(); + } + + return 0; +} + +#endif // Energia + + +#elif defined(MAPLE_IDE) +// ============================================================================= Maple specific + +// ***************************************************************************** +// The MIT License +// +// Copyright (c) 2010 LeafLabs LLC. +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without +// restriction, including without limitation the rights to use, copy, +// modify, merge, publish, distribute, sublicense, and/or sell copies +// of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +// **************************************************************************** + +__attribute__(( constructor )) void premain() { + init(); +} + +int main(void) { + setup(); + + for (;;) + loop(); + + return 0; +} + + +#elif defined(TEENSYDUINO) || defined(CORE_TEENSY) +// ============================================================================= Teensy specific + +#if defined(__MK20DX128__) || defined(__MK20DX256__) +// ----------------------------------------------------------------------------- Teensy 3 specific + +#include "WProgram.h" + +extern "C" int main(void) +{ + // Arduino's main() function just calls setup() and loop().... + setup(); + while (1) { + loop(); + yield(); + } +} + +#else +// ----------------------------------------------------------------------------- Teensy 2 specific + +#include "WProgram.h" + +//int main(void) __attribute__((noreturn)); +int main(void) +{ + _init_Teensyduino_internal_(); + + setup(); + + for (;;) + loop(); +} + + +#endif // Teensy + + +#elif defined(WIRING) +// ============================================================================= Wiring specific + +// Replace #include "WProgram.h" by #include "Wiring.h" +// Comment boardInit(); + +#include "Wiring.h" + +int main(void) +{ + // Hardware specific initializations. + // boardInit(); + init(); + + // User defined setup routine + setup(); + // User defined loop routine + for(;;) + loop(); +} + + +#elif defined(ARDUINO) +// ============================================================================= Arduino specific + +#if (ARDUINO < 100) +// ----------------------------------------------------------------------------- Arduino 0023 specific + +#include "WProgram.h" + +int main(void) +{ + init(); + + setup(); + + for (;;) + loop(); + + return 0; +} + + +#elif (ARDUINO < 150) +// ----------------------------------------------------------------------------- Arduino 1.0x specific + +#include "Arduino.h" + +int main(void) +{ + init(); + +#if defined(USBCON) + USBDevice.attach(); +#endif + + setup(); + + for (;;) { + loop(); + if (serialEventRun) serialEventRun(); + } + + return 0; +} + + +#else +// ----------------------------------------------------------------------------- Arduino 1.5x specific + +#if defined(__SAM3X8E__) +// ............................................................................. Arduino 1.5x SAM architecture specific + +/* + Copyright (c) 2011 Arduino. All rights reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#define ARDUINO_MAIN +#include "Arduino.h" + +/* + * Cortex-M3 Systick IT handler + */ +/* + extern void SysTick_Handler( void ) + { + // Increment tick count each ms + TimeTick_Increment() ; + } + */ + +/* + * \brief Main entry point of Arduino application + */ +int main( void ) +{ + init(); + + delay(1); + +#if defined(USBCON) + USBDevice.attach(); +#endif + + setup(); + + for (;;) + { + loop(); + if (serialEventRun) serialEventRun(); + } + + return 0; +} + +#else +// ............................................................................. Arduino 1.5x AVR architecture specific + +#include "Arduino.h" + +int main(void) +{ + init(); + +#if defined(USBCON) + USBDevice.attach(); +#endif + + setup(); + + for (;;) { + loop(); + if (serialEventRun) serialEventRun(); + } + + return 0; +} + + +#endif // architecture +#endif // Arduino + +#else // error +#error Platform not defined +#endif // end IDE + +#endif // end embedXcode + -- cgit v1.2.3 From 20e4e4cd65dec69edd46b40d90c9f0b4c8078014 Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Wed, 2 Apr 2014 20:11:22 -0700 Subject: not putting this here --- FastLED/FastLED.xcodeproj/project.pbxproj | 514 ---------- .../project.xcworkspace/contents.xcworkspacedata | 7 - .../UserInterfaceState.xcuserstate | Bin 4192 -> 0 bytes .../dgarcia.xcuserdatad/xcschemes/All.xcscheme | 59 -- .../dgarcia.xcuserdatad/xcschemes/Build.xcscheme | 59 -- .../dgarcia.xcuserdatad/xcschemes/Index.xcscheme | 86 -- .../dgarcia.xcuserdatad/xcschemes/Serial.xcscheme | 59 -- .../dgarcia.xcuserdatad/xcschemes/Upload.xcscheme | 59 -- .../xcschemes/xcschememanagement.plist | 62 -- FastLED/FastLED/About/About.txt | 15 - .../FastLED/Configurations/Arduino Due.xcconfig | 45 - .../Configurations/Arduino Duemilanove.xcconfig | 46 - .../Configurations/Arduino Leonardo.xcconfig | 41 - .../Configurations/Arduino Mega 2560.xcconfig | 46 - .../Arduino Mini with ATmega328-3.3V.xcconfig | 45 - .../Arduino Mini with ATmega328-5V.xcconfig | 46 - .../Configurations/Arduino Robot Control.xcconfig | 40 - .../Configurations/Arduino Robot Motor.xcconfig | 40 - .../FastLED/Configurations/Arduino Uno.xcconfig | 40 - .../FastLED/Configurations/Arduino Yun.xcconfig | 40 - .../FastLED/Configurations/DFRobot BLuno.xcconfig | 40 - .../Configurations/Digispark Tiny Core.xcconfig | 44 - .../Experimeter Board with MSP430FR5739.xcconfig | 40 - .../LaunchPad Stellaris with LM4F120.xcconfig | 40 - .../LaunchPad Tiva C with TM4C123.xcconfig | 44 - .../LaunchPad with MSP430F5529.xcconfig | 39 - .../LaunchPad with MSP430G2231.xcconfig | 40 - .../LaunchPad with MSP430G2452.xcconfig | 40 - .../LaunchPad with MSP430G2553.xcconfig | 40 - .../Maple Flash revision 3+.xcconfig | 39 - .../Microduino Core with ATmega328-5V.xcconfig | 39 - .../Microduino Core+ with ATmega644-5V.xcconfig | 39 - .../FastLED/Configurations/Sparkfun Uno.xcconfig | 45 - FastLED/FastLED/Configurations/Teensy 2.0.xcconfig | 39 - FastLED/FastLED/Configurations/Teensy 3.0.xcconfig | 39 - FastLED/FastLED/Configurations/Teensy 3.1.xcconfig | 39 - FastLED/FastLED/Configurations/Wiring S.xcconfig | 40 - .../FastLED/Configurations/chipKIT Max32.xcconfig | 40 - .../FastLED/Configurations/chipKIT Uno32.xcconfig | 40 - .../FastLED/Configurations/chipKIT uC32.xcconfig | 45 - FastLED/FastLED/FastLED.ino | 91 -- FastLED/FastLED/LocalLibrary.cpp | 29 - FastLED/FastLED/LocalLibrary.h | 55 -- FastLED/FastLED/Makefile | 80 -- FastLED/FastLED/Makefiles/Arduino.mk | 24 - FastLED/FastLED/Makefiles/Arduino1.mk | 91 -- FastLED/FastLED/Makefiles/Arduino15avr.mk | 199 ---- FastLED/FastLED/Makefiles/Arduino15sam.mk | 157 --- FastLED/FastLED/Makefiles/Arduino23.mk | 69 -- FastLED/FastLED/Makefiles/Avrdude.mk | 93 -- FastLED/FastLED/Makefiles/Digispark.mk | 132 --- FastLED/FastLED/Makefiles/Energia430.mk | 84 -- FastLED/FastLED/Makefiles/EnergiaLM4F.mk | 102 -- FastLED/FastLED/Makefiles/MapleIDE.mk | 108 --- FastLED/FastLED/Makefiles/Microduino.mk | 93 -- FastLED/FastLED/Makefiles/Mpide.mk | 77 -- FastLED/FastLED/Makefiles/Step1.mk | 229 ----- FastLED/FastLED/Makefiles/Step2.mk | 1021 -------------------- FastLED/FastLED/Makefiles/Teensy.mk | 57 -- FastLED/FastLED/Makefiles/Teensy2.mk | 99 -- FastLED/FastLED/Makefiles/Teensy3.mk | 96 -- FastLED/FastLED/Makefiles/Wiring.mk | 123 --- FastLED/FastLED/ReadMe.txt | 26 - FastLED/FastLED/Sketchbook/Sketchbook.txt | 9 - FastLED/FastLED/Utilities/TemplateIcon.icns | Bin 82737 -> 0 bytes FastLED/FastLED/Utilities/embedXcode_check | Bin 113608 -> 0 bytes FastLED/FastLED/Utilities/embedXcode_chrono | Bin 40868 -> 0 bytes FastLED/FastLED/Utilities/embedXcode_prepare | Bin 115748 -> 0 bytes FastLED/FastLED/Utilities/reset.py | 124 --- FastLED/FastLED/Utilities/serial1200.py | 13 - FastLED/FastLED/main.cpp | 475 --------- examples/RGBCalibrate/RGBCalibrate.ino | 9 +- 72 files changed, 6 insertions(+), 5919 deletions(-) delete mode 100644 FastLED/FastLED.xcodeproj/project.pbxproj delete mode 100644 FastLED/FastLED.xcodeproj/project.xcworkspace/contents.xcworkspacedata delete mode 100644 FastLED/FastLED.xcodeproj/project.xcworkspace/xcuserdata/dgarcia.xcuserdatad/UserInterfaceState.xcuserstate delete mode 100644 FastLED/FastLED.xcodeproj/xcuserdata/dgarcia.xcuserdatad/xcschemes/All.xcscheme delete mode 100644 FastLED/FastLED.xcodeproj/xcuserdata/dgarcia.xcuserdatad/xcschemes/Build.xcscheme delete mode 100644 FastLED/FastLED.xcodeproj/xcuserdata/dgarcia.xcuserdatad/xcschemes/Index.xcscheme delete mode 100644 FastLED/FastLED.xcodeproj/xcuserdata/dgarcia.xcuserdatad/xcschemes/Serial.xcscheme delete mode 100644 FastLED/FastLED.xcodeproj/xcuserdata/dgarcia.xcuserdatad/xcschemes/Upload.xcscheme delete mode 100644 FastLED/FastLED.xcodeproj/xcuserdata/dgarcia.xcuserdatad/xcschemes/xcschememanagement.plist delete mode 100644 FastLED/FastLED/About/About.txt delete mode 100755 FastLED/FastLED/Configurations/Arduino Due.xcconfig delete mode 100644 FastLED/FastLED/Configurations/Arduino Duemilanove.xcconfig delete mode 100755 FastLED/FastLED/Configurations/Arduino Leonardo.xcconfig delete mode 100755 FastLED/FastLED/Configurations/Arduino Mega 2560.xcconfig delete mode 100644 FastLED/FastLED/Configurations/Arduino Mini with ATmega328-3.3V.xcconfig delete mode 100755 FastLED/FastLED/Configurations/Arduino Mini with ATmega328-5V.xcconfig delete mode 100644 FastLED/FastLED/Configurations/Arduino Robot Control.xcconfig delete mode 100644 FastLED/FastLED/Configurations/Arduino Robot Motor.xcconfig delete mode 100755 FastLED/FastLED/Configurations/Arduino Uno.xcconfig delete mode 100755 FastLED/FastLED/Configurations/Arduino Yun.xcconfig delete mode 100755 FastLED/FastLED/Configurations/DFRobot BLuno.xcconfig delete mode 100644 FastLED/FastLED/Configurations/Digispark Tiny Core.xcconfig delete mode 100755 FastLED/FastLED/Configurations/Experimeter Board with MSP430FR5739.xcconfig delete mode 100755 FastLED/FastLED/Configurations/LaunchPad Stellaris with LM4F120.xcconfig delete mode 100644 FastLED/FastLED/Configurations/LaunchPad Tiva C with TM4C123.xcconfig delete mode 100644 FastLED/FastLED/Configurations/LaunchPad with MSP430F5529.xcconfig delete mode 100755 FastLED/FastLED/Configurations/LaunchPad with MSP430G2231.xcconfig delete mode 100755 FastLED/FastLED/Configurations/LaunchPad with MSP430G2452.xcconfig delete mode 100755 FastLED/FastLED/Configurations/LaunchPad with MSP430G2553.xcconfig delete mode 100755 FastLED/FastLED/Configurations/Maple Flash revision 3+.xcconfig delete mode 100644 FastLED/FastLED/Configurations/Microduino Core with ATmega328-5V.xcconfig delete mode 100644 FastLED/FastLED/Configurations/Microduino Core+ with ATmega644-5V.xcconfig delete mode 100755 FastLED/FastLED/Configurations/Sparkfun Uno.xcconfig delete mode 100755 FastLED/FastLED/Configurations/Teensy 2.0.xcconfig delete mode 100755 FastLED/FastLED/Configurations/Teensy 3.0.xcconfig delete mode 100755 FastLED/FastLED/Configurations/Teensy 3.1.xcconfig delete mode 100755 FastLED/FastLED/Configurations/Wiring S.xcconfig delete mode 100644 FastLED/FastLED/Configurations/chipKIT Max32.xcconfig delete mode 100755 FastLED/FastLED/Configurations/chipKIT Uno32.xcconfig delete mode 100644 FastLED/FastLED/Configurations/chipKIT uC32.xcconfig delete mode 100644 FastLED/FastLED/FastLED.ino delete mode 100644 FastLED/FastLED/LocalLibrary.cpp delete mode 100644 FastLED/FastLED/LocalLibrary.h delete mode 100644 FastLED/FastLED/Makefile delete mode 100755 FastLED/FastLED/Makefiles/Arduino.mk delete mode 100755 FastLED/FastLED/Makefiles/Arduino1.mk delete mode 100755 FastLED/FastLED/Makefiles/Arduino15avr.mk delete mode 100755 FastLED/FastLED/Makefiles/Arduino15sam.mk delete mode 100755 FastLED/FastLED/Makefiles/Arduino23.mk delete mode 100755 FastLED/FastLED/Makefiles/Avrdude.mk delete mode 100755 FastLED/FastLED/Makefiles/Digispark.mk delete mode 100755 FastLED/FastLED/Makefiles/Energia430.mk delete mode 100755 FastLED/FastLED/Makefiles/EnergiaLM4F.mk delete mode 100755 FastLED/FastLED/Makefiles/MapleIDE.mk delete mode 100755 FastLED/FastLED/Makefiles/Microduino.mk delete mode 100755 FastLED/FastLED/Makefiles/Mpide.mk delete mode 100755 FastLED/FastLED/Makefiles/Step1.mk delete mode 100755 FastLED/FastLED/Makefiles/Step2.mk delete mode 100755 FastLED/FastLED/Makefiles/Teensy.mk delete mode 100755 FastLED/FastLED/Makefiles/Teensy2.mk delete mode 100755 FastLED/FastLED/Makefiles/Teensy3.mk delete mode 100755 FastLED/FastLED/Makefiles/Wiring.mk delete mode 100644 FastLED/FastLED/ReadMe.txt delete mode 100644 FastLED/FastLED/Sketchbook/Sketchbook.txt delete mode 100644 FastLED/FastLED/Utilities/TemplateIcon.icns delete mode 100755 FastLED/FastLED/Utilities/embedXcode_check delete mode 100755 FastLED/FastLED/Utilities/embedXcode_chrono delete mode 100755 FastLED/FastLED/Utilities/embedXcode_prepare delete mode 100755 FastLED/FastLED/Utilities/reset.py delete mode 100755 FastLED/FastLED/Utilities/serial1200.py delete mode 100644 FastLED/FastLED/main.cpp diff --git a/FastLED/FastLED.xcodeproj/project.pbxproj b/FastLED/FastLED.xcodeproj/project.pbxproj deleted file mode 100644 index 76200e69..00000000 --- a/FastLED/FastLED.xcodeproj/project.pbxproj +++ /dev/null @@ -1,514 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 46; - objects = { - -/* Begin PBXBuildFile section */ - 7BA555FA18ED087600E45020 /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7BA555F918ED087600E45020 /* main.cpp */; }; - 7BA555FC18ED087600E45020 /* LocalLibrary.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7BA555FB18ED087600E45020 /* LocalLibrary.cpp */; }; - 7BA555FF18ED087600E45020 /* Makefile in Sources */ = {isa = PBXBuildFile; fileRef = 7BA555FE18ED087600E45020 /* Makefile */; }; -/* End PBXBuildFile section */ - -/* Begin PBXFileReference section */ - 7BA555F618ED087600E45020 /* Index */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = Index; sourceTree = BUILT_PRODUCTS_DIR; }; - 7BA555F918ED087600E45020 /* main.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = ""; }; - 7BA555FB18ED087600E45020 /* LocalLibrary.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = LocalLibrary.cpp; sourceTree = ""; }; - 7BA555FD18ED087600E45020 /* LocalLibrary.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LocalLibrary.h; sourceTree = ""; }; - 7BA555FE18ED087600E45020 /* Makefile */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.make; path = Makefile; sourceTree = ""; }; - 7BA5560118ED087600E45020 /* Sketchbook.txt */ = {isa = PBXFileReference; lastKnownFileType = text; name = Sketchbook.txt; path = Sketchbook/Sketchbook.txt; sourceTree = ""; }; - 7BA5560318ED087600E45020 /* Arduino Due.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "Arduino Due.xcconfig"; path = "Configurations/Arduino Due.xcconfig"; sourceTree = ""; }; - 7BA5560418ED087600E45020 /* Arduino Duemilanove.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "Arduino Duemilanove.xcconfig"; path = "Configurations/Arduino Duemilanove.xcconfig"; sourceTree = ""; }; - 7BA5560518ED087600E45020 /* Arduino Leonardo.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "Arduino Leonardo.xcconfig"; path = "Configurations/Arduino Leonardo.xcconfig"; sourceTree = ""; }; - 7BA5560618ED087600E45020 /* Arduino Mega 2560.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "Arduino Mega 2560.xcconfig"; path = "Configurations/Arduino Mega 2560.xcconfig"; sourceTree = ""; }; - 7BA5560718ED087600E45020 /* Arduino Mini with ATmega328-3.3V.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "Arduino Mini with ATmega328-3.3V.xcconfig"; path = "Configurations/Arduino Mini with ATmega328-3.3V.xcconfig"; sourceTree = ""; }; - 7BA5560818ED087600E45020 /* Arduino Mini with ATmega328-5V.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "Arduino Mini with ATmega328-5V.xcconfig"; path = "Configurations/Arduino Mini with ATmega328-5V.xcconfig"; sourceTree = ""; }; - 7BA5560918ED087600E45020 /* Arduino Robot Control.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "Arduino Robot Control.xcconfig"; path = "Configurations/Arduino Robot Control.xcconfig"; sourceTree = ""; }; - 7BA5560A18ED087600E45020 /* Arduino Robot Motor.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "Arduino Robot Motor.xcconfig"; path = "Configurations/Arduino Robot Motor.xcconfig"; sourceTree = ""; }; - 7BA5560B18ED087600E45020 /* Arduino Uno.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "Arduino Uno.xcconfig"; path = "Configurations/Arduino Uno.xcconfig"; sourceTree = ""; }; - 7BA5560C18ED087600E45020 /* Arduino Yun.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "Arduino Yun.xcconfig"; path = "Configurations/Arduino Yun.xcconfig"; sourceTree = ""; }; - 7BA5560D18ED087600E45020 /* chipKIT Uno32.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "chipKIT Uno32.xcconfig"; path = "Configurations/chipKIT Uno32.xcconfig"; sourceTree = ""; }; - 7BA5560E18ED087600E45020 /* chipKIT Max32.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "chipKIT Max32.xcconfig"; path = "Configurations/chipKIT Max32.xcconfig"; sourceTree = ""; }; - 7BA5560F18ED087600E45020 /* chipKIT uC32.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "chipKIT uC32.xcconfig"; path = "Configurations/chipKIT uC32.xcconfig"; sourceTree = ""; }; - 7BA5561018ED087600E45020 /* DFRobot BLuno.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "DFRobot BLuno.xcconfig"; path = "Configurations/DFRobot BLuno.xcconfig"; sourceTree = ""; }; - 7BA5561118ED087600E45020 /* Digispark Tiny Core.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "Digispark Tiny Core.xcconfig"; path = "Configurations/Digispark Tiny Core.xcconfig"; sourceTree = ""; }; - 7BA5561218ED087600E45020 /* Experimeter Board with MSP430FR5739.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "Experimeter Board with MSP430FR5739.xcconfig"; path = "Configurations/Experimeter Board with MSP430FR5739.xcconfig"; sourceTree = ""; }; - 7BA5561318ED087600E45020 /* LaunchPad Stellaris with LM4F120.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "LaunchPad Stellaris with LM4F120.xcconfig"; path = "Configurations/LaunchPad Stellaris with LM4F120.xcconfig"; sourceTree = ""; }; - 7BA5561418ED087600E45020 /* LaunchPad Tiva C with TM4C123.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "LaunchPad Tiva C with TM4C123.xcconfig"; path = "Configurations/LaunchPad Tiva C with TM4C123.xcconfig"; sourceTree = ""; }; - 7BA5561518ED087600E45020 /* LaunchPad with MSP430G2553.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "LaunchPad with MSP430G2553.xcconfig"; path = "Configurations/LaunchPad with MSP430G2553.xcconfig"; sourceTree = ""; }; - 7BA5561618ED087600E45020 /* LaunchPad with MSP430G2231.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "LaunchPad with MSP430G2231.xcconfig"; path = "Configurations/LaunchPad with MSP430G2231.xcconfig"; sourceTree = ""; }; - 7BA5561718ED087600E45020 /* LaunchPad with MSP430G2452.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "LaunchPad with MSP430G2452.xcconfig"; path = "Configurations/LaunchPad with MSP430G2452.xcconfig"; sourceTree = ""; }; - 7BA5561818ED087600E45020 /* LaunchPad with MSP430F5529.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "LaunchPad with MSP430F5529.xcconfig"; path = "Configurations/LaunchPad with MSP430F5529.xcconfig"; sourceTree = ""; }; - 7BA5561918ED087600E45020 /* Maple Flash revision 3+.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "Maple Flash revision 3+.xcconfig"; path = "Configurations/Maple Flash revision 3+.xcconfig"; sourceTree = ""; }; - 7BA5561A18ED087600E45020 /* Microduino Core with ATmega328-5V.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "Microduino Core with ATmega328-5V.xcconfig"; path = "Configurations/Microduino Core with ATmega328-5V.xcconfig"; sourceTree = ""; }; - 7BA5561B18ED087600E45020 /* Microduino Core+ with ATmega644-5V.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "Microduino Core+ with ATmega644-5V.xcconfig"; path = "Configurations/Microduino Core+ with ATmega644-5V.xcconfig"; sourceTree = ""; }; - 7BA5561C18ED087600E45020 /* Sparkfun Uno.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "Sparkfun Uno.xcconfig"; path = "Configurations/Sparkfun Uno.xcconfig"; sourceTree = ""; }; - 7BA5561D18ED087600E45020 /* Teensy 2.0.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "Teensy 2.0.xcconfig"; path = "Configurations/Teensy 2.0.xcconfig"; sourceTree = ""; }; - 7BA5561E18ED087600E45020 /* Teensy 3.0.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "Teensy 3.0.xcconfig"; path = "Configurations/Teensy 3.0.xcconfig"; sourceTree = ""; }; - 7BA5561F18ED087600E45020 /* Teensy 3.1.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "Teensy 3.1.xcconfig"; path = "Configurations/Teensy 3.1.xcconfig"; sourceTree = ""; }; - 7BA5562018ED087600E45020 /* Wiring S.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "Wiring S.xcconfig"; path = "Configurations/Wiring S.xcconfig"; sourceTree = ""; }; - 7BA5562218ED087600E45020 /* Arduino.mk */ = {isa = PBXFileReference; lastKnownFileType = text; name = Arduino.mk; path = Makefiles/Arduino.mk; sourceTree = ""; }; - 7BA5562318ED087600E45020 /* Arduino1.mk */ = {isa = PBXFileReference; lastKnownFileType = text; name = Arduino1.mk; path = Makefiles/Arduino1.mk; sourceTree = ""; }; - 7BA5562418ED087600E45020 /* Arduino15avr.mk */ = {isa = PBXFileReference; lastKnownFileType = text; name = Arduino15avr.mk; path = Makefiles/Arduino15avr.mk; sourceTree = ""; }; - 7BA5562518ED087600E45020 /* Arduino15sam.mk */ = {isa = PBXFileReference; lastKnownFileType = text; name = Arduino15sam.mk; path = Makefiles/Arduino15sam.mk; sourceTree = ""; }; - 7BA5562618ED087600E45020 /* Arduino23.mk */ = {isa = PBXFileReference; lastKnownFileType = text; name = Arduino23.mk; path = Makefiles/Arduino23.mk; sourceTree = ""; }; - 7BA5562718ED087600E45020 /* Digispark.mk */ = {isa = PBXFileReference; lastKnownFileType = text; name = Digispark.mk; path = Makefiles/Digispark.mk; sourceTree = ""; }; - 7BA5562818ED087600E45020 /* Energia430.mk */ = {isa = PBXFileReference; lastKnownFileType = text; name = Energia430.mk; path = Makefiles/Energia430.mk; sourceTree = ""; }; - 7BA5562918ED087600E45020 /* EnergiaLM4F.mk */ = {isa = PBXFileReference; lastKnownFileType = text; name = EnergiaLM4F.mk; path = Makefiles/EnergiaLM4F.mk; sourceTree = ""; }; - 7BA5562A18ED087600E45020 /* MapleIDE.mk */ = {isa = PBXFileReference; lastKnownFileType = text; name = MapleIDE.mk; path = Makefiles/MapleIDE.mk; sourceTree = ""; }; - 7BA5562B18ED087600E45020 /* Microduino.mk */ = {isa = PBXFileReference; lastKnownFileType = text; name = Microduino.mk; path = Makefiles/Microduino.mk; sourceTree = ""; }; - 7BA5562C18ED087600E45020 /* Mpide.mk */ = {isa = PBXFileReference; lastKnownFileType = text; name = Mpide.mk; path = Makefiles/Mpide.mk; sourceTree = ""; }; - 7BA5562D18ED087600E45020 /* Wiring.mk */ = {isa = PBXFileReference; lastKnownFileType = text; name = Wiring.mk; path = Makefiles/Wiring.mk; sourceTree = ""; }; - 7BA5562E18ED087600E45020 /* Step1.mk */ = {isa = PBXFileReference; lastKnownFileType = text; name = Step1.mk; path = Makefiles/Step1.mk; sourceTree = ""; }; - 7BA5562F18ED087600E45020 /* Step2.mk */ = {isa = PBXFileReference; lastKnownFileType = text; name = Step2.mk; path = Makefiles/Step2.mk; sourceTree = ""; }; - 7BA5563018ED087600E45020 /* Teensy.mk */ = {isa = PBXFileReference; lastKnownFileType = text; name = Teensy.mk; path = Makefiles/Teensy.mk; sourceTree = ""; }; - 7BA5563118ED087600E45020 /* Teensy2.mk */ = {isa = PBXFileReference; lastKnownFileType = text; name = Teensy2.mk; path = Makefiles/Teensy2.mk; sourceTree = ""; }; - 7BA5563218ED087600E45020 /* Teensy3.mk */ = {isa = PBXFileReference; lastKnownFileType = text; name = Teensy3.mk; path = Makefiles/Teensy3.mk; sourceTree = ""; }; - 7BA5563318ED087600E45020 /* Avrdude.mk */ = {isa = PBXFileReference; lastKnownFileType = text; name = Avrdude.mk; path = Makefiles/Avrdude.mk; sourceTree = ""; }; - 7BA5563418ED087600E45020 /* ReadMe.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = ReadMe.txt; sourceTree = ""; }; - 7BA5563618ED087600E45020 /* About.txt */ = {isa = PBXFileReference; lastKnownFileType = text; name = About.txt; path = About/About.txt; sourceTree = ""; }; - 7BA5563818ED087600E45020 /* reset.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; name = reset.py; path = Utilities/reset.py; sourceTree = ""; }; - 7BA5563918ED087600E45020 /* serial1200.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; name = serial1200.py; path = Utilities/serial1200.py; sourceTree = ""; }; - 7BA5563A18ED087600E45020 /* embedXcode_prepare */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.executable"; name = embedXcode_prepare; path = Utilities/embedXcode_prepare; sourceTree = ""; }; - 7BA5563B18ED087600E45020 /* embedXcode_check */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.executable"; name = embedXcode_check; path = Utilities/embedXcode_check; sourceTree = ""; }; - 7BA5563C18ED087600E45020 /* embedXcode_chrono */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.executable"; name = embedXcode_chrono; path = Utilities/embedXcode_chrono; sourceTree = ""; }; - 7BA5563D18ED087600E45020 /* TemplateIcon.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; name = TemplateIcon.icns; path = Utilities/TemplateIcon.icns; sourceTree = ""; }; - 7BA5563E18ED087600E45020 /* FastLED.ino */ = {isa = PBXFileReference; lastKnownFileType = text; path = FastLED.ino; sourceTree = ""; }; -/* End PBXFileReference section */ - -/* Begin PBXGroup section */ - 7BA555EB18ED087600E45020 = { - isa = PBXGroup; - children = ( - 7BA555F818ED087600E45020 /* FastLED */, - 7BA555F718ED087600E45020 /* Products */, - ); - sourceTree = ""; - }; - 7BA555F718ED087600E45020 /* Products */ = { - isa = PBXGroup; - children = ( - 7BA555F618ED087600E45020 /* Index */, - ); - name = Products; - sourceTree = ""; - }; - 7BA555F818ED087600E45020 /* FastLED */ = { - isa = PBXGroup; - children = ( - 7BA555F918ED087600E45020 /* main.cpp */, - 7BA555FB18ED087600E45020 /* LocalLibrary.cpp */, - 7BA555FD18ED087600E45020 /* LocalLibrary.h */, - 7BA555FE18ED087600E45020 /* Makefile */, - 7BA5563418ED087600E45020 /* ReadMe.txt */, - 7BA5563E18ED087600E45020 /* FastLED.ino */, - 7BA5560018ED087600E45020 /* Sketchbook */, - 7BA5560218ED087600E45020 /* Configurations */, - 7BA5562118ED087600E45020 /* Makefiles */, - 7BA5563518ED087600E45020 /* About */, - 7BA5563718ED087600E45020 /* Utilities */, - ); - path = FastLED; - sourceTree = ""; - }; - 7BA5560018ED087600E45020 /* Sketchbook */ = { - isa = PBXGroup; - children = ( - 7BA5560118ED087600E45020 /* Sketchbook.txt */, - ); - name = Sketchbook; - sourceTree = ""; - }; - 7BA5560218ED087600E45020 /* Configurations */ = { - isa = PBXGroup; - children = ( - 7BA5560318ED087600E45020 /* Arduino Due.xcconfig */, - 7BA5560418ED087600E45020 /* Arduino Duemilanove.xcconfig */, - 7BA5560518ED087600E45020 /* Arduino Leonardo.xcconfig */, - 7BA5560618ED087600E45020 /* Arduino Mega 2560.xcconfig */, - 7BA5560718ED087600E45020 /* Arduino Mini with ATmega328-3.3V.xcconfig */, - 7BA5560818ED087600E45020 /* Arduino Mini with ATmega328-5V.xcconfig */, - 7BA5560918ED087600E45020 /* Arduino Robot Control.xcconfig */, - 7BA5560A18ED087600E45020 /* Arduino Robot Motor.xcconfig */, - 7BA5560B18ED087600E45020 /* Arduino Uno.xcconfig */, - 7BA5560C18ED087600E45020 /* Arduino Yun.xcconfig */, - 7BA5560D18ED087600E45020 /* chipKIT Uno32.xcconfig */, - 7BA5560E18ED087600E45020 /* chipKIT Max32.xcconfig */, - 7BA5560F18ED087600E45020 /* chipKIT uC32.xcconfig */, - 7BA5561018ED087600E45020 /* DFRobot BLuno.xcconfig */, - 7BA5561118ED087600E45020 /* Digispark Tiny Core.xcconfig */, - 7BA5561218ED087600E45020 /* Experimeter Board with MSP430FR5739.xcconfig */, - 7BA5561318ED087600E45020 /* LaunchPad Stellaris with LM4F120.xcconfig */, - 7BA5561418ED087600E45020 /* LaunchPad Tiva C with TM4C123.xcconfig */, - 7BA5561518ED087600E45020 /* LaunchPad with MSP430G2553.xcconfig */, - 7BA5561618ED087600E45020 /* LaunchPad with MSP430G2231.xcconfig */, - 7BA5561718ED087600E45020 /* LaunchPad with MSP430G2452.xcconfig */, - 7BA5561818ED087600E45020 /* LaunchPad with MSP430F5529.xcconfig */, - 7BA5561918ED087600E45020 /* Maple Flash revision 3+.xcconfig */, - 7BA5561A18ED087600E45020 /* Microduino Core with ATmega328-5V.xcconfig */, - 7BA5561B18ED087600E45020 /* Microduino Core+ with ATmega644-5V.xcconfig */, - 7BA5561C18ED087600E45020 /* Sparkfun Uno.xcconfig */, - 7BA5561D18ED087600E45020 /* Teensy 2.0.xcconfig */, - 7BA5561E18ED087600E45020 /* Teensy 3.0.xcconfig */, - 7BA5561F18ED087600E45020 /* Teensy 3.1.xcconfig */, - 7BA5562018ED087600E45020 /* Wiring S.xcconfig */, - ); - name = Configurations; - sourceTree = ""; - }; - 7BA5562118ED087600E45020 /* Makefiles */ = { - isa = PBXGroup; - children = ( - 7BA5562218ED087600E45020 /* Arduino.mk */, - 7BA5562318ED087600E45020 /* Arduino1.mk */, - 7BA5562418ED087600E45020 /* Arduino15avr.mk */, - 7BA5562518ED087600E45020 /* Arduino15sam.mk */, - 7BA5562618ED087600E45020 /* Arduino23.mk */, - 7BA5562718ED087600E45020 /* Digispark.mk */, - 7BA5562818ED087600E45020 /* Energia430.mk */, - 7BA5562918ED087600E45020 /* EnergiaLM4F.mk */, - 7BA5562A18ED087600E45020 /* MapleIDE.mk */, - 7BA5562B18ED087600E45020 /* Microduino.mk */, - 7BA5562C18ED087600E45020 /* Mpide.mk */, - 7BA5562D18ED087600E45020 /* Wiring.mk */, - 7BA5562E18ED087600E45020 /* Step1.mk */, - 7BA5562F18ED087600E45020 /* Step2.mk */, - 7BA5563018ED087600E45020 /* Teensy.mk */, - 7BA5563118ED087600E45020 /* Teensy2.mk */, - 7BA5563218ED087600E45020 /* Teensy3.mk */, - 7BA5563318ED087600E45020 /* Avrdude.mk */, - ); - name = Makefiles; - sourceTree = ""; - }; - 7BA5563518ED087600E45020 /* About */ = { - isa = PBXGroup; - children = ( - 7BA5563618ED087600E45020 /* About.txt */, - ); - name = About; - sourceTree = ""; - }; - 7BA5563718ED087600E45020 /* Utilities */ = { - isa = PBXGroup; - children = ( - 7BA5563818ED087600E45020 /* reset.py */, - 7BA5563918ED087600E45020 /* serial1200.py */, - 7BA5563A18ED087600E45020 /* embedXcode_prepare */, - 7BA5563B18ED087600E45020 /* embedXcode_check */, - 7BA5563C18ED087600E45020 /* embedXcode_chrono */, - 7BA5563D18ED087600E45020 /* TemplateIcon.icns */, - ); - name = Utilities; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXLegacyTarget section */ - 7BA555F018ED087600E45020 /* All */ = { - isa = PBXLegacyTarget; - buildArgumentsString = "all -C \"$(PROJECT)\""; - buildConfigurationList = 7BA5564118ED087600E45020 /* Build configuration list for PBXLegacyTarget "All" */; - buildPhases = ( - ); - buildToolPath = make; - dependencies = ( - ); - name = All; - passBuildSettingsInEnvironment = 1; - productName = All; - }; - 7BA555F118ED087600E45020 /* Build */ = { - isa = PBXLegacyTarget; - buildArgumentsString = "build -C \"$(PROJECT)\""; - buildConfigurationList = 7BA5564418ED087600E45020 /* Build configuration list for PBXLegacyTarget "Build" */; - buildPhases = ( - ); - buildToolPath = make; - dependencies = ( - ); - name = Build; - passBuildSettingsInEnvironment = 1; - productName = Build; - }; - 7BA555F218ED087600E45020 /* Serial */ = { - isa = PBXLegacyTarget; - buildArgumentsString = "serial -C \"$(PROJECT)\""; - buildConfigurationList = 7BA5564718ED087600E45020 /* Build configuration list for PBXLegacyTarget "Serial" */; - buildPhases = ( - ); - buildToolPath = make; - dependencies = ( - ); - name = Serial; - passBuildSettingsInEnvironment = 1; - productName = Serial; - }; - 7BA555F318ED087600E45020 /* Upload */ = { - isa = PBXLegacyTarget; - buildArgumentsString = "upload -C \"$(PROJECT)\""; - buildConfigurationList = 7BA5564A18ED087600E45020 /* Build configuration list for PBXLegacyTarget "Upload" */; - buildPhases = ( - ); - buildToolPath = make; - dependencies = ( - ); - name = Upload; - passBuildSettingsInEnvironment = 1; - productName = Upload; - }; -/* End PBXLegacyTarget section */ - -/* Begin PBXNativeTarget section */ - 7BA555F518ED087600E45020 /* Index */ = { - isa = PBXNativeTarget; - buildConfigurationList = 7BA5564D18ED087600E45020 /* Build configuration list for PBXNativeTarget "Index" */; - buildPhases = ( - 7BA555F418ED087600E45020 /* Sources */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = Index; - productName = Index; - productReference = 7BA555F618ED087600E45020 /* Index */; - productType = "com.apple.product-type.tool"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 7BA555EC18ED087600E45020 /* Project object */ = { - isa = PBXProject; - attributes = { - LastUpgradeCheck = 0510; - ORGANIZATIONNAME = "Daniel Garcia"; - }; - buildConfigurationList = 7BA555EF18ED087600E45020 /* Build configuration list for PBXProject "FastLED" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; - hasScannedForEncodings = 0; - knownRegions = ( - en, - ); - mainGroup = 7BA555EB18ED087600E45020; - productRefGroup = 7BA555F718ED087600E45020 /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 7BA555F018ED087600E45020 /* All */, - 7BA555F118ED087600E45020 /* Build */, - 7BA555F218ED087600E45020 /* Serial */, - 7BA555F318ED087600E45020 /* Upload */, - 7BA555F518ED087600E45020 /* Index */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXSourcesBuildPhase section */ - 7BA555F418ED087600E45020 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 7BA555FF18ED087600E45020 /* Makefile in Sources */, - 7BA555FA18ED087600E45020 /* main.cpp in Sources */, - 7BA555FC18ED087600E45020 /* LocalLibrary.cpp in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin XCBuildConfiguration section */ - 7BA5563F18ED087600E45020 /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 7BA5560B18ED087600E45020 /* Arduino Uno.xcconfig */; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - COPY_PHASE_STRIP = NO; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_DYNAMIC_NO_PIC = NO; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_SYMBOLS_PRIVATE_EXTERN = NO; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - HEADER_SEARCH_PATHS = "$(inherited)"; - PATH = "$(PATH):$(PROJECT_DIR)"; - PRODUCT_NAME = "$(TARGET_NAME)"; - SKETCHBOOK_DIR = ""; - SKETCH_EXTENSION = ino; - }; - name = Debug; - }; - 7BA5564018ED087600E45020 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - COPY_PHASE_STRIP = YES; - ENABLE_NS_ASSERTIONS = NO; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - HEADER_SEARCH_PATHS = "$(inherited)"; - PATH = "$(PATH):$(PROJECT_DIR)"; - PRODUCT_NAME = "$(TARGET_NAME)"; - SKETCHBOOK_DIR = ""; - SKETCH_EXTENSION = ino; - }; - name = Release; - }; - 7BA5564218ED087600E45020 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Debug; - }; - 7BA5564318ED087600E45020 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Release; - }; - 7BA5564518ED087600E45020 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - }; - name = Debug; - }; - 7BA5564618ED087600E45020 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - }; - name = Release; - }; - 7BA5564818ED087600E45020 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - }; - name = Debug; - }; - 7BA5564918ED087600E45020 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - }; - name = Release; - }; - 7BA5564B18ED087600E45020 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - }; - name = Debug; - }; - 7BA5564C18ED087600E45020 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - }; - name = Release; - }; - 7BA5564E18ED087600E45020 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - }; - name = Debug; - }; - 7BA5564F18ED087600E45020 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 7BA555EF18ED087600E45020 /* Build configuration list for PBXProject "FastLED" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 7BA5563F18ED087600E45020 /* Debug */, - 7BA5564018ED087600E45020 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 7BA5564118ED087600E45020 /* Build configuration list for PBXLegacyTarget "All" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 7BA5564218ED087600E45020 /* Debug */, - 7BA5564318ED087600E45020 /* Release */, - ); - defaultConfigurationIsVisible = 0; - }; - 7BA5564418ED087600E45020 /* Build configuration list for PBXLegacyTarget "Build" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 7BA5564518ED087600E45020 /* Debug */, - 7BA5564618ED087600E45020 /* Release */, - ); - defaultConfigurationIsVisible = 0; - }; - 7BA5564718ED087600E45020 /* Build configuration list for PBXLegacyTarget "Serial" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 7BA5564818ED087600E45020 /* Debug */, - 7BA5564918ED087600E45020 /* Release */, - ); - defaultConfigurationIsVisible = 0; - }; - 7BA5564A18ED087600E45020 /* Build configuration list for PBXLegacyTarget "Upload" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 7BA5564B18ED087600E45020 /* Debug */, - 7BA5564C18ED087600E45020 /* Release */, - ); - defaultConfigurationIsVisible = 0; - }; - 7BA5564D18ED087600E45020 /* Build configuration list for PBXNativeTarget "Index" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 7BA5564E18ED087600E45020 /* Debug */, - 7BA5564F18ED087600E45020 /* Release */, - ); - defaultConfigurationIsVisible = 0; - }; -/* End XCConfigurationList section */ - }; - rootObject = 7BA555EC18ED087600E45020 /* Project object */; -} diff --git a/FastLED/FastLED.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/FastLED/FastLED.xcodeproj/project.xcworkspace/contents.xcworkspacedata deleted file mode 100644 index 203db588..00000000 --- a/FastLED/FastLED.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ /dev/null @@ -1,7 +0,0 @@ - - - - - diff --git a/FastLED/FastLED.xcodeproj/project.xcworkspace/xcuserdata/dgarcia.xcuserdatad/UserInterfaceState.xcuserstate b/FastLED/FastLED.xcodeproj/project.xcworkspace/xcuserdata/dgarcia.xcuserdatad/UserInterfaceState.xcuserstate deleted file mode 100644 index 8685299f..00000000 Binary files a/FastLED/FastLED.xcodeproj/project.xcworkspace/xcuserdata/dgarcia.xcuserdatad/UserInterfaceState.xcuserstate and /dev/null differ diff --git a/FastLED/FastLED.xcodeproj/xcuserdata/dgarcia.xcuserdatad/xcschemes/All.xcscheme b/FastLED/FastLED.xcodeproj/xcuserdata/dgarcia.xcuserdatad/xcschemes/All.xcscheme deleted file mode 100644 index 6ff2b50f..00000000 --- a/FastLED/FastLED.xcodeproj/xcuserdata/dgarcia.xcuserdatad/xcschemes/All.xcscheme +++ /dev/null @@ -1,59 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/FastLED/FastLED.xcodeproj/xcuserdata/dgarcia.xcuserdatad/xcschemes/Build.xcscheme b/FastLED/FastLED.xcodeproj/xcuserdata/dgarcia.xcuserdatad/xcschemes/Build.xcscheme deleted file mode 100644 index c5853b74..00000000 --- a/FastLED/FastLED.xcodeproj/xcuserdata/dgarcia.xcuserdatad/xcschemes/Build.xcscheme +++ /dev/null @@ -1,59 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/FastLED/FastLED.xcodeproj/xcuserdata/dgarcia.xcuserdatad/xcschemes/Index.xcscheme b/FastLED/FastLED.xcodeproj/xcuserdata/dgarcia.xcuserdatad/xcschemes/Index.xcscheme deleted file mode 100644 index 0ee62c4a..00000000 --- a/FastLED/FastLED.xcodeproj/xcuserdata/dgarcia.xcuserdatad/xcschemes/Index.xcscheme +++ /dev/null @@ -1,86 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/FastLED/FastLED.xcodeproj/xcuserdata/dgarcia.xcuserdatad/xcschemes/Serial.xcscheme b/FastLED/FastLED.xcodeproj/xcuserdata/dgarcia.xcuserdatad/xcschemes/Serial.xcscheme deleted file mode 100644 index 47d41b70..00000000 --- a/FastLED/FastLED.xcodeproj/xcuserdata/dgarcia.xcuserdatad/xcschemes/Serial.xcscheme +++ /dev/null @@ -1,59 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/FastLED/FastLED.xcodeproj/xcuserdata/dgarcia.xcuserdatad/xcschemes/Upload.xcscheme b/FastLED/FastLED.xcodeproj/xcuserdata/dgarcia.xcuserdatad/xcschemes/Upload.xcscheme deleted file mode 100644 index e9440d31..00000000 --- a/FastLED/FastLED.xcodeproj/xcuserdata/dgarcia.xcuserdatad/xcschemes/Upload.xcscheme +++ /dev/null @@ -1,59 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/FastLED/FastLED.xcodeproj/xcuserdata/dgarcia.xcuserdatad/xcschemes/xcschememanagement.plist b/FastLED/FastLED.xcodeproj/xcuserdata/dgarcia.xcuserdatad/xcschemes/xcschememanagement.plist deleted file mode 100644 index 16c50ac3..00000000 --- a/FastLED/FastLED.xcodeproj/xcuserdata/dgarcia.xcuserdatad/xcschemes/xcschememanagement.plist +++ /dev/null @@ -1,62 +0,0 @@ - - - - - SchemeUserState - - All.xcscheme - - orderHint - 0 - - Build.xcscheme - - orderHint - 1 - - Index.xcscheme - - orderHint - 4 - - Serial.xcscheme - - orderHint - 2 - - Upload.xcscheme - - orderHint - 3 - - - SuppressBuildableAutocreation - - 7BA555F018ED087600E45020 - - primary - - - 7BA555F118ED087600E45020 - - primary - - - 7BA555F218ED087600E45020 - - primary - - - 7BA555F318ED087600E45020 - - primary - - - 7BA555F518ED087600E45020 - - primary - - - - - diff --git a/FastLED/FastLED/About/About.txt b/FastLED/FastLED/About/About.txt deleted file mode 100644 index d3d57cc8..00000000 --- a/FastLED/FastLED/About/About.txt +++ /dev/null @@ -1,15 +0,0 @@ - - embedXcode - embedXcode+ - ---------------------------------- - Embedded Computing on Xcode - - - © Rei VILO, 2010-2014 - All rights reserved - http://embedXcode.weebly.com/ - - -embedXcode • Mar 26, 2014 release 143 • Improved code sense for libraries -embedXcode+ • Mar 26, 2014 release 143 • Improved code sense for libraries - \ No newline at end of file diff --git a/FastLED/FastLED/Configurations/Arduino Due.xcconfig b/FastLED/FastLED/Configurations/Arduino Due.xcconfig deleted file mode 100755 index 1fdfe498..00000000 --- a/FastLED/FastLED/Configurations/Arduino Due.xcconfig +++ /dev/null @@ -1,45 +0,0 @@ -// -// Arduino Due.xcconfig -// Board configuration file -// ---------------------------------- -// Developed with embedXcode -// -// Part of embedXcode -// Embedded Computing on Xcode -// -// Created by Rei Vilo on Oct 23, 2012 -// Copyright (c) 2012-2014 http://embedxcode.weebly.com -// License All rigths reserved -// -// Last update: Feb 06, 2014 release 131 - -// Board identifier -// See Boards.txt for .name=Arduino Uno (16 MHz) -// -BOARD_TAG = arduino_due_x - -// Port (optionnal) -// most common are /dev/tty.usbserial*, /dev/tty.usbmodem* or /dev/tty.uart* -// Note: if /dev/tty.usbserial* doesn't work, try /dev/tty.usbmodem* -// -BOARD_PORT = /dev/tty.usbserial* -//BOARD_PORT = /dev/tty.usbmodem* - -// Warning: some users have reported /dev/cu.usb* - -// References for Xcode code-sense -// See Boards.txt for .build.mcu= -// -GCC_PREPROCESSOR_DEFINITIONS = __SAM3X8E__ ARDUINO - -// Specify the full path and name of the application -// with /Contents/Resources/Java/** after -// -HEADER_SEARCH_PATHS = /Applications/Arduino.app/Contents/Resources/Java/** - -// Maximum RAM size in bytes -// given by .upload.maximum_ram_size in boards.txt for Maple and Teensy -// given by .upload.maximum_data_size in boards.txt for Arduino 1.5.x -// -MAX_RAM_SIZE = 98304 - diff --git a/FastLED/FastLED/Configurations/Arduino Duemilanove.xcconfig b/FastLED/FastLED/Configurations/Arduino Duemilanove.xcconfig deleted file mode 100644 index 7aaea12e..00000000 --- a/FastLED/FastLED/Configurations/Arduino Duemilanove.xcconfig +++ /dev/null @@ -1,46 +0,0 @@ -// -// Duemilanove.xcconfig -// Board configuration file -// ---------------------------------- -// Developed with embedXcode -// -// Part of embedXcode -// Embedded Computing on Xcode -// -// Created by Joel Saltzman on 4/12/13 -// Copyright (c) 2013 joelsaltzman.com -// License All rigths reserved -// -// Maintained by Rei VILO on Mar 12, 2012 -// Copyright (c) 2012-2014 http://embedxcode.weebly.com -// License All rights reserved -// -// Last update: Feb 06, 2014 release 131 - -// Board identifier -// See Boards.txt for .name=Arduino Uno (16 MHz) -// -BOARD_TAG = uno - -// Port (optionnal) -// most common are /dev/tty.usbserial*, /dev/tty.usbmodem* or /dev/tty.uart* -// -BOARD_PORT = /dev/tty.usbserial* -AVRDUDE_BAUDRATE = 57600 - -// References for Xcode code-sense -// See Boards.txt for .build.mcu= -// -GCC_PREPROCESSOR_DEFINITIONS = AVR_ATmega328P ARDUINO - -// Specify the full path and name of the application -// with /Contents/Resources/Java/** after -// -HEADER_SEARCH_PATHS = /Applications/Arduino.app/Contents/Resources/Java/** - -// Maximum RAM size in bytes -// given by .upload.maximum_ram_size in boards.txt for Maple and Teensy -// given by .upload.maximum_data_size in boards.txt for Arduino 1.5.x -// -MAX_RAM_SIZE = 2048 - diff --git a/FastLED/FastLED/Configurations/Arduino Leonardo.xcconfig b/FastLED/FastLED/Configurations/Arduino Leonardo.xcconfig deleted file mode 100755 index 251be856..00000000 --- a/FastLED/FastLED/Configurations/Arduino Leonardo.xcconfig +++ /dev/null @@ -1,41 +0,0 @@ -// -// Arduino Leonardo.xcconfig -// Board configuration file -// ---------------------------------- -// Developed with embedXcode -// -// Part of embedXcode -// Embedded Computing on Xcode -// -// Created by Rei Vilo on Aug 29, 2012 -// Copyright (c) 2012-2014 http://embedxcode.weebly.com -// License All rigths reserved -// -// Last update: Feb 06, 2014 release 131 - -// Board identifier -// See Boards.txt for .name=Arduino Uno (16 MHz) -// -BOARD_TAG = leonardo - -// Port (optionnal) -// most common are /dev/tty.usbserial*, /dev/tty.usbmodem* or /dev/tty.uart* -// -BOARD_PORT = /dev/tty.usbmodem* - -// References for Xcode code-sense -// See Boards.txt for .build.mcu= -// -GCC_PREPROCESSOR_DEFINITIONS = __AVR_ATmega32U4__ ARDUINO - -// Specify the full path and name of the application -// with /Contents/Resources/Java/** after -// -HEADER_SEARCH_PATHS = /Applications/Arduino.app/Contents/Resources/Java/** - -// Maximum RAM size in bytes -// given by .upload.maximum_ram_size in boards.txt for Maple and Teensy -// given by .upload.maximum_data_size in boards.txt for Arduino 1.5.x -// -MAX_RAM_SIZE = 2560 - diff --git a/FastLED/FastLED/Configurations/Arduino Mega 2560.xcconfig b/FastLED/FastLED/Configurations/Arduino Mega 2560.xcconfig deleted file mode 100755 index 29a59417..00000000 --- a/FastLED/FastLED/Configurations/Arduino Mega 2560.xcconfig +++ /dev/null @@ -1,46 +0,0 @@ -// -// Arduino Mega 2560.xcconfig -// Board configuration file -// ---------------------------------- -// Developed with embedXcode -// -// Part of embedXcode -// Embedded Computing on Xcode -// -// Created by Rei VILO on Mar 12, 2012 -// Copyright (c) 2012-2014 http://embedxcode.weebly.com -// License All rigths reserved -// -// Last update: Feb 06, 2014 release 131 - -// Board identifier -// See Boards.txt for .name=Arduino Uno (16 MHz) -// -BOARD_TAG = mega2560 - -// For Arduino 1.5.x, if different from Arduino 1.0.x -// -BOARD_TAG1 = mega -BOARD_TAG2 = mega.menu.cpu.atmega2560 - -// Port (optionnal) -// most common are /dev/tty.usbserial*, /dev/tty.usbmodem* or /dev/tty.uart* -// -BOARD_PORT = /dev/tty.usbmodem* - -// References for Xcode code-sense -// See Boards.txt for .build.mcu= -// -GCC_PREPROCESSOR_DEFINITIONS = __AVR_ATmega2560__ ARDUINO - -// Specify the full path and name of the application -// with /Contents/Resources/Java/** after -// -HEADER_SEARCH_PATHS = /Applications/Arduino.app/Contents/Resources/Java/** - -// Maximum RAM size in bytes -// given by .upload.maximum_ram_size in boards.txt for Maple and Teensy -// given by .upload.maximum_data_size in boards.txt for Arduino 1.5.x -// -MAX_RAM_SIZE = 8196 - diff --git a/FastLED/FastLED/Configurations/Arduino Mini with ATmega328-3.3V.xcconfig b/FastLED/FastLED/Configurations/Arduino Mini with ATmega328-3.3V.xcconfig deleted file mode 100644 index c04f74a4..00000000 --- a/FastLED/FastLED/Configurations/Arduino Mini with ATmega328-3.3V.xcconfig +++ /dev/null @@ -1,45 +0,0 @@ -// -// Arduino Mini with ATmega328-3.3V.xcconfig -// Board configuration file -// ---------------------------------- -// Developed with embedXcode -// -// Part of embedXcode -// Embedded Computing on Xcode -// -// Created by Rei VILO on Mar 05, 2014 -// Copyright (c) 2014 http://embeddedcomputing.weebly.com -// License All rigths reserved -// -// Last update: Mar 06, 2014 release 138 - -// Board identifier -// See Boards.txt for .name=Arduino Uno (16 MHz) -// -BOARD_TAG = pro328 - -// For Arduino 1.5.x, if different from Arduino 1.0.x -// -BOARD_TAG1 = pro -BOARD_TAG2 = pro.menu.cpu.8MHzatmega328 - -// Port (optionnal) -// most common are /dev/tty.usbserial*, /dev/tty.usbmodem* or /dev/tty.uart* -// -BOARD_PORT = /dev/tty.usbmodem* - -// References for Xcode code-sense -// See Boards.txt for .build.mcu= -// -GCC_PREPROCESSOR_DEFINITIONS = __AVR_ATmega328P__ ARDUINO - -// Specify the full path and name of the application -// with /Contents/Resources/Java/** after -// -HEADER_SEARCH_PATHS = /Applications/Arduino.app/Contents/Resources/Java/** - -// Maximum RAM size in bytes -// given by .upload.maximum_ram_size in boards.txt for Maple and Teensy -// given by .upload.maximum_data_size in boards.txt for Arduino 1.5.x -// -MAX_RAM_SIZE = 2048 diff --git a/FastLED/FastLED/Configurations/Arduino Mini with ATmega328-5V.xcconfig b/FastLED/FastLED/Configurations/Arduino Mini with ATmega328-5V.xcconfig deleted file mode 100755 index 7d658cdb..00000000 --- a/FastLED/FastLED/Configurations/Arduino Mini with ATmega328-5V.xcconfig +++ /dev/null @@ -1,46 +0,0 @@ -// -// Arduino Mini with ATmega328-5V.xcconfig -// Board configuration file -// ---------------------------------- -// Developed with embedXcode -// -// Part of embedXcode -// Embedded Computing on Xcode -// -// Created by Rei VILO on Mar 12, 2012 -// Copyright (c) 2012-2014 http://embedxcode.weebly.com -// License All rigths reserved -// -// Last update: Mar 06, 2014 release 138 - -// Board identifier -// See Boards.txt for .name=Arduino Uno (16 MHz) -// -BOARD_TAG = pro5v328 - -// For Arduino 1.5.x, if different from Arduino 1.0.x -// -BOARD_TAG1 = pro -BOARD_TAG2 = menu.cpu.pro.16MHzatmega328 - -// Port (optionnal) -// most common are /dev/tty.usbserial*, /dev/tty.usbmodem* or /dev/tty.uart* -// -BOARD_PORT = /dev/tty.usbmodem* - -// References for Xcode code-sense -// See Boards.txt for .build.mcu= -// -GCC_PREPROCESSOR_DEFINITIONS = __AVR_ATmega328P__ ARDUINO - -// Specify the full path and name of the application -// with /Contents/Resources/Java/** after -// -HEADER_SEARCH_PATHS = /Applications/Arduino.app/Contents/Resources/Java/** - -// Maximum RAM size in bytes -// given by .upload.maximum_ram_size in boards.txt for Maple and Teensy -// given by .upload.maximum_data_size in boards.txt for Arduino 1.5.x -// -MAX_RAM_SIZE = 2048 - diff --git a/FastLED/FastLED/Configurations/Arduino Robot Control.xcconfig b/FastLED/FastLED/Configurations/Arduino Robot Control.xcconfig deleted file mode 100644 index 946cf0f8..00000000 --- a/FastLED/FastLED/Configurations/Arduino Robot Control.xcconfig +++ /dev/null @@ -1,40 +0,0 @@ -// -// Arduino Robot Control.xcconfig -// Board configuration file -// ---------------------------------- -// Developed with embedXcode -// -// Part of embedXcode -// Embedded Computing on Xcode -// -// Created by Rei VILO on Jun 21, 2013 -// Copyright (c) 2012-2014 http://embedxcode.weebly.com -// License All rigths reserved -// -// Last update: Feb 06, 2014 release 131 - -// Board identifier -// See Boards.txt for .name=Arduino Uno (16 MHz) -// -BOARD_TAG = robotControl - -// Port (optionnal) -// most common are /dev/tty.usbserial*, /dev/tty.usbmodem* or /dev/tty.uart* -// -BOARD_PORT = /dev/tty.usbmodem* - -// References for Xcode code-sense -// See Boards.txt for .build.mcu= -// -GCC_PREPROCESSOR_DEFINITIONS = __AVR_ATmega328P__ ARDUINO - -// Specify the full path and name of the application -// with /Contents/Resources/Java/** after -// -HEADER_SEARCH_PATHS = /Applications/Arduino.app/Contents/Resources/Java/** - -// Maximum RAM size in bytes -// given by .upload.maximum_ram_size in boards.txt for Maple and Teensy -// given by .upload.maximum_data_size in boards.txt for Arduino 1.5.x -// -MAX_RAM_SIZE = 2048 diff --git a/FastLED/FastLED/Configurations/Arduino Robot Motor.xcconfig b/FastLED/FastLED/Configurations/Arduino Robot Motor.xcconfig deleted file mode 100644 index dbc5d3f6..00000000 --- a/FastLED/FastLED/Configurations/Arduino Robot Motor.xcconfig +++ /dev/null @@ -1,40 +0,0 @@ -// -// Arduino Robot Control.xcconfig -// Board configuration file -// ---------------------------------- -// Developed with embedXcode -// -// Part of embedXcode -// Embedded Computing on Xcode -// -// Created by Rei VILO on Jun 21, 2013 -// Copyright (c) 2012-2014 http://embedxcode.weebly.com -// License All rigths reserved -// -// Last update: Feb 06, 2014 release 131 - -// Board identifier -// See Boards.txt for .name=Arduino Uno (16 MHz) -// -BOARD_TAG = robotMotor - -// Port (optionnal) -// most common are /dev/tty.usbserial*, /dev/tty.usbmodem* or /dev/tty.uart* -// -BOARD_PORT = /dev/tty.usbmodem* - -// References for Xcode code-sense -// See Boards.txt for .build.mcu= -// -GCC_PREPROCESSOR_DEFINITIONS = __AVR_ATmega328P__ ARDUINO - -// Specify the full path and name of the application -// with /Contents/Resources/Java/** after -// -HEADER_SEARCH_PATHS = /Applications/Arduino.app/Contents/Resources/Java/** - -// Maximum RAM size in bytes -// given by .upload.maximum_ram_size in boards.txt for Maple and Teensy -// given by .upload.maximum_data_size in boards.txt for Arduino 1.5.x -// -MAX_RAM_SIZE = 2048 diff --git a/FastLED/FastLED/Configurations/Arduino Uno.xcconfig b/FastLED/FastLED/Configurations/Arduino Uno.xcconfig deleted file mode 100755 index ac4cb60e..00000000 --- a/FastLED/FastLED/Configurations/Arduino Uno.xcconfig +++ /dev/null @@ -1,40 +0,0 @@ -// -// Arduino Uno.xcconfig -// Board configuration file -// ---------------------------------- -// Developed with embedXcode -// -// Part of embedXcode -// Embedded Computing on Xcode -// -// Created by Rei VILO on Mar 12, 2012 -// Copyright (c) 2012-2014 http://embedxcode.weebly.com -// License All rigths reserved -// -// Last update: Feb 06, 2014 release 131 - -// Board identifier -// See Boards.txt for .name=Arduino Uno (16 MHz) -// -BOARD_TAG = uno - -// Port (optionnal) -// most common are /dev/tty.usbserial*, /dev/tty.usbmodem* or /dev/tty.uart* -// -BOARD_PORT = /dev/tty.usbmodem* - -// References for Xcode code-sense -// See Boards.txt for .build.mcu= -// -GCC_PREPROCESSOR_DEFINITIONS = __AVR_ATmega328P__ ARDUINO - -// Specify the full path and name of the application -// with /Contents/Resources/Java/** after -// -HEADER_SEARCH_PATHS = /Applications/Arduino.app/Contents/Resources/Java/** - -// Maximum RAM size in bytes -// given by .upload.maximum_ram_size in boards.txt for Maple and Teensy -// given by .upload.maximum_data_size in boards.txt for Arduino 1.5.x -// -MAX_RAM_SIZE = 2048 diff --git a/FastLED/FastLED/Configurations/Arduino Yun.xcconfig b/FastLED/FastLED/Configurations/Arduino Yun.xcconfig deleted file mode 100755 index 88aa8393..00000000 --- a/FastLED/FastLED/Configurations/Arduino Yun.xcconfig +++ /dev/null @@ -1,40 +0,0 @@ -// -// Arduino Yun.xcconfig -// Board configuration file -// ---------------------------------- -// Developed with embedXcode -// -// Part of embedXcode -// Embedded Computing on Xcode -// -// Created by Rei VILO on Jan 22, 2014 -// Copyright (c) 2012-2014 http://embedxcode.weebly.com -// License All rigths reserved -// -// Last update: Feb 06, 2014 release 131 - -// Board identifier -// See Boards.txt for .name=Arduino Uno (16 MHz) -// -BOARD_TAG = yun - -// Port (optionnal) -// most common are /dev/tty.usbserial*, /dev/tty.usbmodem* or /dev/tty.uart* -// -BOARD_PORT = /dev/tty.usbmodem* - -// References for Xcode code-sense -// See Boards.txt for .build.mcu= -// -GCC_PREPROCESSOR_DEFINITIONS = __AVR_ATmega32U4__ ARDUINO - -// Specify the full path and name of the application -// with /Contents/Resources/Java/** after -// -HEADER_SEARCH_PATHS = /Applications/Arduino.app/Contents/Resources/Java/** - -// Maximum RAM size in bytes -// given by .upload.maximum_ram_size in boards.txt for Maple and Teensy -// given by .upload.maximum_data_size in boards.txt for Arduino 1.5.x -// - diff --git a/FastLED/FastLED/Configurations/DFRobot BLuno.xcconfig b/FastLED/FastLED/Configurations/DFRobot BLuno.xcconfig deleted file mode 100755 index 11db8186..00000000 --- a/FastLED/FastLED/Configurations/DFRobot BLuno.xcconfig +++ /dev/null @@ -1,40 +0,0 @@ -// -// DFRobot BLuno.xcconfig -// Board configuration file -// ---------------------------------- -// Developed with embedXcode -// -// Part of embedXcode -// Embedded Computing on Xcode -// -// Created by Rei VILO on Mar 12, 2012 -// Copyright (c) 2012-2014 http://embedxcode.weebly.com -// License All rigths reserved -// -// Last update: Feb 06, 2014 release 131 - -// Board identifier -// See Boards.txt for .name=Arduino Uno (16 MHz) -// -BOARD_TAG = uno - -// Port (optionnal) -// most common are /dev/tty.usbserial*, /dev/tty.usbmodem* or /dev/tty.uart* -// -BOARD_PORT = /dev/tty.usbmodem* - -// References for Xcode code-sense -// See Boards.txt for .build.mcu= -// -GCC_PREPROCESSOR_DEFINITIONS = __AVR_ATmega328P__ ARDUINO - -// Specify the full path and name of the application -// with /Contents/Resources/Java/** after -// -HEADER_SEARCH_PATHS = /Applications/Arduino.app/Contents/Resources/Java/** - -// Maximum RAM size in bytes -// given by .upload.maximum_ram_size in boards.txt for Maple and Teensy -// given by .upload.maximum_data_size in boards.txt for Arduino 1.5.x -// -MAX_RAM_SIZE = 2048 diff --git a/FastLED/FastLED/Configurations/Digispark Tiny Core.xcconfig b/FastLED/FastLED/Configurations/Digispark Tiny Core.xcconfig deleted file mode 100644 index f1aa6f76..00000000 --- a/FastLED/FastLED/Configurations/Digispark Tiny Core.xcconfig +++ /dev/null @@ -1,44 +0,0 @@ -// -// Digispark Tiny Core.xcconfig -// Board configuration file -// ---------------------------------- -// Developed with embedXcode -// -// Part of embedXcode -// Embedded Computing on Xcode -// -// Created by Rei VILO on Feb 14, 2013 -// Copyright (c) 2012-2014 http://embedxcode.weebly.com -// License All rigths reserved -// -// Last update: Feb 06, 2014 release 131 - -// Board identifier -// See Boards.txt for .name=Arduino Uno (16 MHz) -// -BOARD_TAG = digispark-tiny - -// Port (optionnal) -// most common are /dev/tty.usbserial*, /dev/tty.usbmodem* or /dev/tty.uart* -// -BOARD_PORT = /dev/tty.* - -// References for Xcode code-sense -// See Boards.txt for .build.mcu= -// -GCC_PREPROCESSOR_DEFINITIONS = __AVR_ATtinyX5__ DIGISPARK - -// Specify the full path and name of the application -// with /Contents/Resources/Java/** after -// -HEADER_SEARCH_PATHS = /Applications/DigisparkArduino.app/Contents/Resources/Java/** /Applications/Arduino.app/Contents/Resources/Java/** - -// Maximum RAM size in bytes -// given by .upload.maximum_ram_size in boards.txt for Maple and Teensy -// -MAX_RAM_SIZE = 512 - -// If the programmer provides no serial port, set AVRDUDE_NO_SERIAL_PORT = 1 -// Otherwise, comment or set AVRDUDE_NO_SERIAL_PORT = 0 with BOARD_PORT as serial port -// -AVRDUDE_NO_SERIAL_PORT = 1 diff --git a/FastLED/FastLED/Configurations/Experimeter Board with MSP430FR5739.xcconfig b/FastLED/FastLED/Configurations/Experimeter Board with MSP430FR5739.xcconfig deleted file mode 100755 index 911648b6..00000000 --- a/FastLED/FastLED/Configurations/Experimeter Board with MSP430FR5739.xcconfig +++ /dev/null @@ -1,40 +0,0 @@ -// -// Experimeter Board with MSP430FR5739.xcconfig -// Board configuration file -// ---------------------------------- -// Developed with embedXcode -// -// Part of embedXcode -// Embedded Computing on Xcode -// -// Created by Rei Vilo on Sep 20, 2012 -// Copyright (c) 2012-2014 http://embedxcode.weebly.com -// License All rigths reserved -// -// Last update: Feb 06, 2014 release 131 - -// Board identifier -// See Boards.txt for .name=Arduino Uno (16 MHz) -// -BOARD_TAG = lpmsp430fr5739 - -// Port (optionnal) -// most common are /dev/tty.usbserial*, /dev/tty.usbmodem* or /dev/tty.uart* -// -BOARD_PORT = /dev/tty.uart* - -// References for Xcode code-sense -// See Boards.txt for .build.mcu= -// -GCC_PREPROCESSOR_DEFINITIONS = __MSP430FR5739__ ENERGIA - -// Specify the full path and name of the application -// with /Contents/Resources/Java/** after -// -HEADER_SEARCH_PATHS = /Applications/Energia.app/Contents/Resources/Java/hardware/msp430/** - -// Maximum RAM size in bytes -// given by .upload.maximum_ram_size in boards.txt for Maple and Teensy -// -//MAX_RAM_SIZE = 1024 - diff --git a/FastLED/FastLED/Configurations/LaunchPad Stellaris with LM4F120.xcconfig b/FastLED/FastLED/Configurations/LaunchPad Stellaris with LM4F120.xcconfig deleted file mode 100755 index e59dfb4c..00000000 --- a/FastLED/FastLED/Configurations/LaunchPad Stellaris with LM4F120.xcconfig +++ /dev/null @@ -1,40 +0,0 @@ -// -// LaunchPad Stellaris with LM4F120.xcconfig -// Board configuration file -// ---------------------------------- -// Developed with embedXcode -// -// Part of embedXcode -// Embedded Computing on Xcode -// -// Created by Rei VILO on Oct 24, 2012 -// Copyright (c) 2012-2014 http://embedxcode.weebly.com -// License All rigths reserved -// -// Last update: Feb 06, 2014 release 131 - -// Board identifier -// See Boards.txt for .name=Arduino Uno (16 MHz) -// -BOARD_TAG = lplm4f120h5qr - -// Port (optionnal) -// most common are /dev/tty.usbserial*, /dev/tty.usbmodem* or /dev/tty.uart* -// -BOARD_PORT = /dev/tty.usbmodem0E* - -// References for Xcode code-sense -// See Boards.txt for .build.mcu= -// -GCC_PREPROCESSOR_DEFINITIONS = __LM4F120H5QR__ ENERGIA - -// Specify the full path and name of the application -// with /Contents/Resources/Java/** after -// -HEADER_SEARCH_PATHS = /Applications/Energia.app/Contents/Resources/Java/hardware/lm4f/** - -// Maximum RAM size in bytes -// given by .upload.maximum_ram_size in boards.txt for Maple and Teensy -// -//MAX_RAM_SIZE = 32768 - diff --git a/FastLED/FastLED/Configurations/LaunchPad Tiva C with TM4C123.xcconfig b/FastLED/FastLED/Configurations/LaunchPad Tiva C with TM4C123.xcconfig deleted file mode 100644 index f4a1c783..00000000 --- a/FastLED/FastLED/Configurations/LaunchPad Tiva C with TM4C123.xcconfig +++ /dev/null @@ -1,44 +0,0 @@ -// -// LaunchPad Tiva C with TM4C123.xcconfig -// Board configuration file -// ---------------------------------- -// Developed with embedXcode -// -// Part of embedXcode -// Embedded Computing on Xcode -// -// Created by Rei VILO on 24/10/12 -// Copyright (c) 2012-2014 http://embedxcode.weebly.com -// License All rigths reserved -// -// Last update: Feb 06, 2014 release 131 - -// Board identifier -// See Boards.txt for .name=Arduino Uno (16 MHz) -// -BOARD_TAG = lptm4c1230c3pm - -// TM4C123GH6PM as http://www.ti.com/ww/en/launchpad/launchpads-tivac.html#tabs -// lptm4c1233h6pm -// lptm4c1230c3pm as boards.txt - -// Port (optionnal) -// most common are /dev/tty.usbserial*, /dev/tty.usbmodem* or /dev/tty.uart* -// -BOARD_PORT = /dev/tty.usbmodem0E* - -// References for Xcode code-sense -// See Boards.txt for .build.mcu= -// -GCC_PREPROCESSOR_DEFINITIONS = __TM4C123GH6PM__ ENERGIA - -// Specify the full path and name of the application -// with /Contents/Resources/Java/** after -// -HEADER_SEARCH_PATHS = /Applications/Energia.app/Contents/Resources/Java/hardware/lm4f/** - -// Maximum RAM size in bytes -// given by .upload.maximum_ram_size in boards.txt for Maple and Teensy -// -//MAX_RAM_SIZE = 32768 - diff --git a/FastLED/FastLED/Configurations/LaunchPad with MSP430F5529.xcconfig b/FastLED/FastLED/Configurations/LaunchPad with MSP430F5529.xcconfig deleted file mode 100644 index 580b1de6..00000000 --- a/FastLED/FastLED/Configurations/LaunchPad with MSP430F5529.xcconfig +++ /dev/null @@ -1,39 +0,0 @@ -// -// LaunchPad with MSP430F5529.xcconfig -// Board configuration file -// ---------------------------------- -// Developed with embedXcode -// -// Part of embedXcode -// Embedded Computing on Xcode -// -// Created by Rei VILO on Sep 05, 2013 -// Copyright (c) 2012-2014 http://embedxcode.weebly.com -// License All rigths reserved -// -// Last update: Feb 06, 2014 release 131 - -// Board identifier -// See Boards.txt for .name=Arduino Uno (16 MHz) -// -BOARD_TAG = lpmsp430f5529_25 - -// Port (optionnal) -// most common are /dev/tty.usbserial*, /dev/tty.usbmodem* or /dev/tty.uart* -// -BOARD_PORT = /dev/tty.usbmodem* - -// References for Xcode code-sense -// See Boards.txt for .build.mcu= -// -GCC_PREPROCESSOR_DEFINITIONS = __MSP430F5529__ ENERGIA - -// Specify the full path and name of the application -// with /Contents/Resources/Java/** after -// -HEADER_SEARCH_PATHS = /Applications/Energia.app/Contents/Resources/Java/hardware/msp430/** - -// Maximum RAM size in bytes -// given by .upload.maximum_ram_size in boards.txt for Maple and Teensy -// -//MAX_RAM_SIZE = 8096 diff --git a/FastLED/FastLED/Configurations/LaunchPad with MSP430G2231.xcconfig b/FastLED/FastLED/Configurations/LaunchPad with MSP430G2231.xcconfig deleted file mode 100755 index aa0ff285..00000000 --- a/FastLED/FastLED/Configurations/LaunchPad with MSP430G2231.xcconfig +++ /dev/null @@ -1,40 +0,0 @@ -// -// LaunchPad with MSP430G2231.xcconfig -// Board configuration file -// ---------------------------------- -// Developed with embedXcode -// -// Part of embedXcode -// Embedded Computing on Xcode -// -// Created by Rei VILO on Apr 05, 2012 -// Copyright (c) 2012-2014 http://embedxcode.weebly.com -// License All rigths reserved -// -// Last update: Feb 06, 2014 release 131 - -// Board identifier -// See Boards.txt for .name=Arduino Uno (16 MHz) -// -BOARD_TAG = lpmsp430g2231 - -// Port (optionnal) -// most common are /dev/tty.usbserial*, /dev/tty.usbmodem* or /dev/tty.uart* -// -BOARD_PORT = /dev/tty.uart* - -// References for Xcode code-sense -// See Boards.txt for .build.mcu= -// -GCC_PREPROCESSOR_DEFINITIONS = __MSP430G2231__ ENERGIA - -// Specify the full path and name of the application -// with /Contents/Resources/Java/** after -// -HEADER_SEARCH_PATHS = /Applications/Energia.app/Contents/Resources/Java/hardware/msp430/** - -// Maximum RAM size in bytes -// given by .upload.maximum_ram_size in boards.txt for Maple and Teensy -// -//MAX_RAM_SIZE = 128 - diff --git a/FastLED/FastLED/Configurations/LaunchPad with MSP430G2452.xcconfig b/FastLED/FastLED/Configurations/LaunchPad with MSP430G2452.xcconfig deleted file mode 100755 index 2e68e278..00000000 --- a/FastLED/FastLED/Configurations/LaunchPad with MSP430G2452.xcconfig +++ /dev/null @@ -1,40 +0,0 @@ -// -// LaunchPad with MSP430G2452.xcconfig -// Board configuration file -// ---------------------------------- -// Developed with embedXcode -// -// Part of embedXcode -// Embedded Computing on Xcode -// -// Created by Rei VILO on Apr 05, 2012 -// Copyright (c) 2012-2014 http://embedxcode.weebly.com -// License All rigths reserved -// -// Last update: Feb 06, 2014 release 131 - -// Board identifier -// See Boards.txt for .name=Arduino Uno (16 MHz) -// -BOARD_TAG = lpmsp430g2452 - -// Port (optionnal) -// most common are /dev/tty.usbserial*, /dev/tty.usbmodem* or /dev/tty.uart* -// -BOARD_PORT = /dev/tty.uart* - -// References for Xcode code-sense -// See Boards.txt for .build.mcu= -// -GCC_PREPROCESSOR_DEFINITIONS = __MSP430G2452__ ENERGIA - -// Specify the full path and name of the application -// with /Contents/Resources/Java/** after -// -HEADER_SEARCH_PATHS = /Applications/Energia.app/Contents/Resources/Java/hardware/msp430/** - -// Maximum RAM size in bytes -// given by .upload.maximum_ram_size in boards.txt for Maple and Teensy -// -//MAX_RAM_SIZE = 256 - diff --git a/FastLED/FastLED/Configurations/LaunchPad with MSP430G2553.xcconfig b/FastLED/FastLED/Configurations/LaunchPad with MSP430G2553.xcconfig deleted file mode 100755 index c080ff1b..00000000 --- a/FastLED/FastLED/Configurations/LaunchPad with MSP430G2553.xcconfig +++ /dev/null @@ -1,40 +0,0 @@ -// -// LaunchPad with MSP430G2553.xcconfig -// Board configuration file -// ---------------------------------- -// Developed with embedXcode -// -// Part of embedXcode -// Embedded Computing on Xcode -// -// Created by Rei VILO on Apr 05, 2012 -// Copyright (c) 2012-2014 http://embedxcode.weebly.com -// License All rigths reserved -// -// Last update: Feb 06, 2014 release 131 - -// Board identifier -// See Boards.txt for .name=Arduino Uno (16 MHz) -// -BOARD_TAG = lpmsp430g2553 - -// Port (optionnal) -// most common are /dev/tty.usbserial*, /dev/tty.usbmodem* or /dev/tty.uart* -// -BOARD_PORT = /dev/tty.uart* - -// References for Xcode code-sense -// See Boards.txt for .build.mcu= -// -GCC_PREPROCESSOR_DEFINITIONS = __MSP430G2553__ ENERGIA - -// Specify the full path and name of the application -// with /Contents/Resources/Java/** after -// -HEADER_SEARCH_PATHS = /Applications/Energia.app/Contents/Resources/Java/hardware/msp430/** - -// Maximum RAM size in bytes -// given by .upload.maximum_ram_size in boards.txt for Maple and Teensy -// -//MAX_RAM_SIZE = 512 - diff --git a/FastLED/FastLED/Configurations/Maple Flash revision 3+.xcconfig b/FastLED/FastLED/Configurations/Maple Flash revision 3+.xcconfig deleted file mode 100755 index 9edd3186..00000000 --- a/FastLED/FastLED/Configurations/Maple Flash revision 3+.xcconfig +++ /dev/null @@ -1,39 +0,0 @@ -// -// Maple Flash revision 3+.xcconfig -// Board configuration file -// ---------------------------------- -// Developed with embedXcode -// -// Part of embedXcode -// Embedded Computing on Xcode -// -// Created by Rei VILO on May 23, 2012 -// Copyright (c) 2012-2014 http://embedxcode.weebly.com -// License All rigths reserved -// -// Last update: Feb 06, 2014 release 131 - -// Board identifier -// See Boards.txt for .name=Arduino Uno (16 MHz) -// -BOARD_TAG = maple - -// Port (optionnal) -// most common are /dev/tty.usbserial*, /dev/tty.usbmodem* or /dev/tty.uart* -// -BOARD_PORT = /dev/tty.usbmodem* - -// References for Xcode code-sense -// See Boards.txt for .build.mcu= -// -GCC_PREPROCESSOR_DEFINITIONS = MCU_STM32F103RB MAPLE_IDE - -// Specify the full path and name of the application -// with /Contents/Resources/Java/** after -// -HEADER_SEARCH_PATHS = /Applications/MapleIDE.app/Contents/Resources/Java/** - -// Maximum RAM size in bytes -// given by .upload.maximum_ram_size in boards.txt for Maple and Teensy -// -//MAX_RAM_SIZE = diff --git a/FastLED/FastLED/Configurations/Microduino Core with ATmega328-5V.xcconfig b/FastLED/FastLED/Configurations/Microduino Core with ATmega328-5V.xcconfig deleted file mode 100644 index 196a49a6..00000000 --- a/FastLED/FastLED/Configurations/Microduino Core with ATmega328-5V.xcconfig +++ /dev/null @@ -1,39 +0,0 @@ -// -// Microduino Core with ATmega328-5V.xcconfig -// Board configuration file -// ---------------------------------- -// Developed with embedXcode -// -// Part of embedXcode -// Embedded Computing on Xcode -// -// Created by Rei VILO on Jan 04, 2014 -// Copyright (c) 2012-2014 http://embedxcode.weebly.com -// License All rigths reserved -// -// Last update: Feb 06, 2014 release 131 - -// Board identifier -// See Boards.txt for .name=Arduino Uno (16 MHz) -// -BOARD_TAG = 328p16m - -// Port (optionnal) -// most common are /dev/tty.usbserial*, /dev/tty.usbmodem* or /dev/tty.uart* -// -BOARD_PORT = /dev/tty.usbserial-* - -// References for Xcode code-sense -// See Boards.txt for .build.mcu= -// -GCC_PREPROCESSOR_DEFINITIONS = __AVR_ATmega328P__ MICRODUINO - -// Specify the full path and name of the application -// with /Contents/Resources/Java/** after -// -HEADER_SEARCH_PATHS = /Applications/Arduino.app/Contents/Resources/Java/** /Applications/Microduino.app/Contents/Resources/Java/** - -// Maximum RAM size in bytes -// given by .upload.maximum_ram_size in boards.txt for Maple and Teensy -// -MAX_RAM_SIZE = 2048 diff --git a/FastLED/FastLED/Configurations/Microduino Core+ with ATmega644-5V.xcconfig b/FastLED/FastLED/Configurations/Microduino Core+ with ATmega644-5V.xcconfig deleted file mode 100644 index 79054d3a..00000000 --- a/FastLED/FastLED/Configurations/Microduino Core+ with ATmega644-5V.xcconfig +++ /dev/null @@ -1,39 +0,0 @@ -// -// Microduino Core+ with ATmega644-5V.xcconfig -// Board configuration file -// ---------------------------------- -// Developed with embedXcode -// -// Part of embedXcode -// Embedded Computing on Xcode -// -// Created by Rei VILO on Jan 04, 2014 -// Copyright (c) 2012-2014 http://embedxcode.weebly.com -// License All rigths reserved -// -// Last update: Feb 06, 2014 release 131 - -// Board identifier -// See Boards.txt for .name=Arduino Uno (16 MHz) -// -BOARD_TAG = 644pa16m - -// Port (optionnal) -// most common are /dev/tty.usbserial*, /dev/tty.usbmodem* or /dev/tty.uart* -// -BOARD_PORT = /dev/tty.usbserial-* - -// References for Xcode code-sense -// See Boards.txt for .build.mcu= -// -GCC_PREPROCESSOR_DEFINITIONS = __AVR_ATmega644P__ MICRODUINO - -// Specify the full path and name of the application -// with /Contents/Resources/Java/** after -// -HEADER_SEARCH_PATHS = /Applications/Arduino.app/Contents/Resources/Java/** /Applications/Microduino.app/Contents/Resources/Java/** - -// Maximum RAM size in bytes -// given by .upload.maximum_ram_size in boards.txt for Maple and Teensy -// -MAX_RAM_SIZE = 4096 diff --git a/FastLED/FastLED/Configurations/Sparkfun Uno.xcconfig b/FastLED/FastLED/Configurations/Sparkfun Uno.xcconfig deleted file mode 100755 index e397bd72..00000000 --- a/FastLED/FastLED/Configurations/Sparkfun Uno.xcconfig +++ /dev/null @@ -1,45 +0,0 @@ -// -// Sparkfun Uno.xcconfig -// Board configuration file -// ---------------------------------- -// Developed with embedXcode -// -// Part of embedXcode -// Embedded Computing on Xcode -// -// Created by Rei VILO on Mar 12, 2012 -// Copyright (c) 2012-2014 http://embedxcode.weebly.com -// License All rigths reserved -// -// Last update: Feb 06, 2014 release 131 - -// Board identifier -// See Boards.txt for .name=Arduino Uno (16 MHz) -// -BOARD_TAG = pro5v328 - -// For Arduino 1.5, if different from Arduino 1.0 -// -BOARD_TAG1 = pro -BOARD_TAG2 = menu.cpu.pro.16MHzatmega328 - -// Port (optionnal) -// most common are /dev/tty.usbserial*, /dev/tty.usbmodem* or /dev/tty.uart* -// -BOARD_PORT = /dev/tty.usbserial-* - -// References for Xcode code-sense -// See Boards.txt for .build.mcu= -// -GCC_PREPROCESSOR_DEFINITIONS = __AVR_ATmega328P__ ARDUINO - -// Specify the full path and name of the application -// with /Contents/Resources/Java/** after -// -HEADER_SEARCH_PATHS = /Applications/Arduino.app/Contents/Resources/Java/** - -// Maximum RAM size in bytes -// given by .upload.maximum_ram_size in boards.txt for Maple and Teensy -// -MAX_RAM_SIZE = 2048 - diff --git a/FastLED/FastLED/Configurations/Teensy 2.0.xcconfig b/FastLED/FastLED/Configurations/Teensy 2.0.xcconfig deleted file mode 100755 index b89e07c1..00000000 --- a/FastLED/FastLED/Configurations/Teensy 2.0.xcconfig +++ /dev/null @@ -1,39 +0,0 @@ -// -// Teensy 2.0.xcconfig -// Board configuration file -// ---------------------------------- -// Developed with embedXcode -// -// Part of embedXcode -// Embedded Computing on Xcode -// -// Created by Rei VILO on Nov 04, 2012 -// Copyright (c) 2012-2014 http://embedxcode.weebly.com -// License All rigths reserved -// -// Last update: Feb 06, 2014 release 131 - -// Board identifier -// See Boards.txt for .name=Arduino Uno (16 MHz) -// -BOARD_TAG = teensy2 - -// Port (optionnal) -// most common are /dev/tty.usbserial*, /dev/tty.usbmodem* or /dev/tty.uart* -// -BOARD_PORT = /dev/tty.usbserial* - -// References for Xcode code-sense -// See Boards.txt for .build.mcu= -// -GCC_PREPROCESSOR_DEFINITIONS = __AVR_ATmega32U4__ TEENSYDUINO - -// Specify the full path and name of the application -// with /Contents/Resources/Java/** after -// -HEADER_SEARCH_PATHS = /Applications/Teensyduino.app/Contents/Resources/Java/** /Applications/Arduino.app/Contents/Resources/Java/** - -// Maximum RAM size in bytes -// given by .upload.maximum_ram_size in boards.txt for Maple and Teensy -// -//MAX_RAM_SIZE = diff --git a/FastLED/FastLED/Configurations/Teensy 3.0.xcconfig b/FastLED/FastLED/Configurations/Teensy 3.0.xcconfig deleted file mode 100755 index cc13111a..00000000 --- a/FastLED/FastLED/Configurations/Teensy 3.0.xcconfig +++ /dev/null @@ -1,39 +0,0 @@ -// -// Teensy 3.0.xcconfig -// Board configuration file -// ---------------------------------- -// Developed with embedXcode -// -// Part of embedXcode -// Embedded Computing on Xcode -// -// Created by Rei VILO on Nov 04, 2012 -// Copyright (c) 2012-2014 http://embedxcode.weebly.com -// License All rigths reserved -// -// Last update: Feb 06, 2014 release 131 - -// Board identifier -// See Boards.txt for .name=Arduino Uno (16 MHz) -// -BOARD_TAG = teensy3 - -// Port (optionnal) -// most common are /dev/tty.usbserial*, /dev/tty.usbmodem* or /dev/tty.uart* -// -BOARD_PORT = /dev/tty.usbmodem* - -// References for Xcode code-sense -// See Boards.txt for .build.mcu= -// -GCC_PREPROCESSOR_DEFINITIONS = __MK20DX128__ TEENSYDUINO - -// Specify the full path and name of the application -// with /Contents/Resources/Java/** after -// -HEADER_SEARCH_PATHS = /Applications/Teensyduino.app/Contents/Resources/Java/** /Applications/Arduino.app/Contents/Resources/Java/** - -// Maximum RAM size in bytes -// given by .upload.maximum_ram_size in boards.txt for Maple and Teensy -// -//MAX_RAM_SIZE = diff --git a/FastLED/FastLED/Configurations/Teensy 3.1.xcconfig b/FastLED/FastLED/Configurations/Teensy 3.1.xcconfig deleted file mode 100755 index 9396ecb3..00000000 --- a/FastLED/FastLED/Configurations/Teensy 3.1.xcconfig +++ /dev/null @@ -1,39 +0,0 @@ -// -// Teensy 3.1.xcconfig -// Board configuration file -// ---------------------------------- -// Developed with embedXcode -// -// Part of embedXcode -// Embedded Computing on Xcode -// -// Created by Rei VILO on Nov 04, 2012 -// Copyright (c) 2012-2014 http://embedxcode.weebly.com -// License All rigths reserved -// -// Last update: Feb 06, 2014 release 131 - -// Board identifier -// See Boards.txt for .name=Arduino Uno (16 MHz) -// -BOARD_TAG = teensy31 - -// Port (optionnal) -// most common are /dev/tty.usbserial*, /dev/tty.usbmodem* or /dev/tty.uart* -// -BOARD_PORT = /dev/tty.usbmodem* - -// References for Xcode code-sense -// See Boards.txt for .build.mcu= -// -GCC_PREPROCESSOR_DEFINITIONS = __MK20DX256__ TEENSYDUINO - -// Specify the full path and name of the application -// with /Contents/Resources/Java/** after -// -HEADER_SEARCH_PATHS = /Applications/Teensyduino.app/Contents/Resources/Java/** /Applications/Arduino.app/Contents/Resources/Java/** - -// Maximum RAM size in bytes -// given by .upload.maximum_ram_size in boards.txt for Maple and Teensy -// -//MAX_RAM_SIZE = diff --git a/FastLED/FastLED/Configurations/Wiring S.xcconfig b/FastLED/FastLED/Configurations/Wiring S.xcconfig deleted file mode 100755 index 17e892f3..00000000 --- a/FastLED/FastLED/Configurations/Wiring S.xcconfig +++ /dev/null @@ -1,40 +0,0 @@ -// -// Wiring S.xcconfig -// Board configuration file -// ---------------------------------- -// Developed with embedXcode -// -// Part of embedXcode -// Embedded Computing on Xcode -// -// Created by Rei VILO on Apr 05, 2012 -// Copyright (c) 2012-2014 http://embedxcode.weebly.com -// License All rights reserved -// -// Last update: Feb 06, 2014 release 131 - -// Board identifier -// See Boards.txt for .name=Arduino Uno (16 MHz) -// -BOARD_TAG = WiringS - -// Port (optionnal) -// most common are /dev/tty.usbserial*, /dev/tty.usbmodem* or /dev/tty.uart* -// -BOARD_PORT = /dev/tty.usbserial* - -// References for Xcode code-sense -// See Boards.txt for .build.mcu= -// -GCC_PREPROCESSOR_DEFINITIONS = __AVR_ATmega644P__ WIRING - -// Specify the full path and name of the application -// with /Contents/Resources/Java/** after -// -HEADER_SEARCH_PATHS = /Applications/Wiring.app/Contents/Resources/Java/** - -// Maximum RAM size in bytes -// given by .upload.maximum_ram_size in boards.txt for Maple and Teensy -// -MAX_RAM_SIZE = 4096 - diff --git a/FastLED/FastLED/Configurations/chipKIT Max32.xcconfig b/FastLED/FastLED/Configurations/chipKIT Max32.xcconfig deleted file mode 100644 index abef05a1..00000000 --- a/FastLED/FastLED/Configurations/chipKIT Max32.xcconfig +++ /dev/null @@ -1,40 +0,0 @@ -// -// chipKIT Max32.xcconfig -// Board configuration file -// ---------------------------------- -// Developed with embedXcode -// -// Part of embedXcode -// Embedded Computing on Xcode -// -// Created by Rei VILO on Apr 21, 2013 -// Copyright (c) 2012-2014 http://embedxcode.weebly.com -// License All rigths reserved -// -// Last update: Feb 06, 2014 release 131 - -// Board identifier -// See Boards.txt for .name=Arduino Uno (16 MHz) -// -BOARD_TAG = mega_pic32 - -// Port (optionnal) -// most common are /dev/tty.usbserial*, /dev/tty.usbmodem* or /dev/tty.uart* -// -BOARD_PORT = /dev/tty.usbserial* - -// References for Xcode code-sense -// See Boards.txt for .build.mcu= -// -GCC_PREPROCESSOR_DEFINITIONS = __32MX795F512L__ MPIDE - -// Specify the full path and name of the application -// with /Contents/Resources/Java/** after -// -HEADER_SEARCH_PATHS = /Applications/Mpide.app/Contents/Resources/Java/** - -// Maximum RAM size in bytes -// given by .upload.maximum_ram_size in boards.txt for Maple and Teensy -// -MAX_RAM_SIZE = 131072 - diff --git a/FastLED/FastLED/Configurations/chipKIT Uno32.xcconfig b/FastLED/FastLED/Configurations/chipKIT Uno32.xcconfig deleted file mode 100755 index a2664d9c..00000000 --- a/FastLED/FastLED/Configurations/chipKIT Uno32.xcconfig +++ /dev/null @@ -1,40 +0,0 @@ -// -// chipKIT Uno32.xcconfig -// Board configuration file -// ---------------------------------- -// Developed with embedXcode -// -// Part of embedXcode -// Embedded Computing on Xcode -// -// Created by Rei VILO on Apr 08, 2012 -// Copyright (c) 2012-2014 http://embedxcode.weebly.com -// License All rigths reserved -// -// Last update: Feb 06, 2014 release 131 - -// Board identifier -// See Boards.txt for .name=Arduino Uno (16 MHz) -// -BOARD_TAG = uno_pic32 - -// Port (optionnal) -// most common are /dev/tty.usbserial*, /dev/tty.usbmodem* or /dev/tty.uart* -// -BOARD_PORT = /dev/tty.usbserial* - -// References for Xcode code-sense -// See Boards.txt for .build.mcu= -// -GCC_PREPROCESSOR_DEFINITIONS = __32MX320F128H__ MPIDE - -// Specify the full path and name of the application -// with /Contents/Resources/Java/** after -// -HEADER_SEARCH_PATHS = /Applications/Mpide.app/Contents/Resources/Java/** - -// Maximum RAM size in bytes -// given by .upload.maximum_ram_size in boards.txt for Maple and Teensy -// -MAX_RAM_SIZE = 16384 - diff --git a/FastLED/FastLED/Configurations/chipKIT uC32.xcconfig b/FastLED/FastLED/Configurations/chipKIT uC32.xcconfig deleted file mode 100644 index 4637a0bc..00000000 --- a/FastLED/FastLED/Configurations/chipKIT uC32.xcconfig +++ /dev/null @@ -1,45 +0,0 @@ -// -// chipKIT Uno32.xcconfig -// Board configuration file -// ---------------------------------- -// Developed with embedXcode -// -// Part of embedXcode -// Embedded Computing on Xcode -// -// Created by John James on Apr 20, 2013 -// License All rigths reserved -// -// Maintained by Rei VILO on May 10, 2013 -// Copyright (c) 2012-2014 http://embedxcode.weebly.com -// License All rigths reserved -// -// Last update: Feb 06, 2014 release 131 - -// Board identifier -// See Boards.txt for .name=Arduino Uno (16 MHz) -// -BOARD_TAG = chipkit_uc32 - -// Port (optionnal) -// most common are /dev/tty.usbserial*, /dev/tty.usbmodem* or /dev/tty.uart* -// -BOARD_PORT = /dev/tty.usbserial* - -// References for Xcode code-sense -// See Boards.txt for .build.mcu= -// -GCC_PREPROCESSOR_DEFINITIONS = __32MX340F512H__ MPIDE - -// Specify the full path and name of the application -// with /Contents/Resources/Java/** after -// -HEADER_SEARCH_PATHS = /Applications/Mpide.app/Contents/Resources/Java/** - -// Maximum RAM size in bytes -// given by .upload.maximum_ram_size in boards.txt for Maple and Teensy -// -// Thanks Sinus! http://chipkit.net/forum/viewtopic.php?p=10932#p10932 -// -MAX_RAM_SIZE = 32768 - diff --git a/FastLED/FastLED/FastLED.ino b/FastLED/FastLED/FastLED.ino deleted file mode 100644 index 137eed39..00000000 --- a/FastLED/FastLED/FastLED.ino +++ /dev/null @@ -1,91 +0,0 @@ -// -// FastLED -// -// FastLED library drivers -// Developed with [embedXcode](http://embedXcode.weebly.com) -// -// Author Daniel Garcia -// Daniel Garcia -// -// Date 4/2/14 8:09 PM -// Version <#version#> -// -// Copyright © Daniel Garcia, 2014 -// License <#license#> -// -// See ReadMe.txt for references -// - -// Core library for code-sense -#if defined(WIRING) // Wiring specific -#include "Wiring.h" -#elif defined(MAPLE_IDE) // Maple specific -#include "WProgram.h" -#elif defined(MICRODUINO) // Microduino specific -#include "Arduino.h" -#elif defined(MPIDE) // chipKIT specific -#include "WProgram.h" -#elif defined(DIGISPARK) // Digispark specific -#include "Arduino.h" -#elif defined(ENERGIA) // LaunchPad MSP430, Stellaris and Tiva, Experimeter Board FR5739 specific -#include "Energia.h" -#elif defined(TEENSYDUINO) // Teensy specific -#include "Arduino.h" -#elif defined(ARDUINO) // Arduino 1.0 and 1.5 specific -#include "Arduino.h" -#else // error -#error Platform not defined -#endif - -// Include application, user and local libraries -#include "LocalLibrary.h" - - -// Prototypes - - -// Define variables and constants -// -// Brief Name of the LED -// Details Each board has a LED but connected to a different pin -// -uint8_t myLED; - - -// -// Brief Setup -// Details Define the pin the LED is connected to -// -// Add setup code -void setup() { - // myLED pin number -#if defined(__AVR_ATmega328P__) || defined(__AVR_ATmega2560__) || defined(__AVR_ATmega32U4__) || defined(__SAM3X8E__) // Arduino specific - myLED = 13; -#elif defined(__PIC32MX__) // chipKIT specific - myLED = 13; -#elif defined(__AVR_ATtinyX5__) // Digispark specific - myLED = 1; // assuming model A -#elif defined(__AVR_ATmega644P__) // Wiring specific - myLED = 15; -#elif defined(__MSP430G2452__) || defined(__MSP430G2553__) || defined(__MSP430G2231__) || defined(__MSP430F5529__) || defined(__MSP430FR5739__) // LaunchPad MSP430 and Experimeter Board FR5739 specific - myLED = RED_LED; -#elif defined(__LM4F120H5QR__) || defined(__TM4C1230C3PM__) // LaunchPad Stellaris and Tiva specific - myLED = RED_LED; -#elif defined(MCU_STM32F103RB) || defined(MCU_STM32F103ZE) || defined(MCU_STM32F103CB) || defined(MCU_STM32F103RE) // Maple specific - myLED = BOARD_LED_PIN; -#elif defined(__MK20DX128__) // Teensy 3.0 specific - myLED = 13; -#endif - - pinMode(myLED, OUTPUT); -} - -// -// Brief Loop -// Details Call blink -// -// Add loop code -void loop() { - blink(myLED, 3, 333); - delay(1000); -} diff --git a/FastLED/FastLED/LocalLibrary.cpp b/FastLED/FastLED/LocalLibrary.cpp deleted file mode 100644 index d2b89b65..00000000 --- a/FastLED/FastLED/LocalLibrary.cpp +++ /dev/null @@ -1,29 +0,0 @@ -// -// LocalLibrary.cpp -// Library C++ code -// ---------------------------------- -// Developed with embedXcode -// http://embedXcode.weebly.com -// -// Project FastLED -// -// Created by Daniel Garcia, 4/2/14 8:09 PM -// Daniel Garcia -// -// Copyright © Daniel Garcia, 2014 -// License <#license#> -// -// See LocalLibrary.cpp.h and ReadMe.txt for references -// - - -#include "LocalLibrary.h" - -void blink(uint8_t pin, uint8_t times, uint16_t ms) { - for (uint8_t i=0; i> 1); - digitalWrite(pin, LOW); - delay(ms >> 1); - } -} diff --git a/FastLED/FastLED/LocalLibrary.h b/FastLED/FastLED/LocalLibrary.h deleted file mode 100644 index ed0dc614..00000000 --- a/FastLED/FastLED/LocalLibrary.h +++ /dev/null @@ -1,55 +0,0 @@ -// -// File LocalLibrary.h -// Brief Library header -// -// Project FastLED -// Developed with [embedXcode](http://embedXcode.weebly.com) -// -// Author Daniel Garcia -// Daniel Garcia -// Date 4/2/14 8:09 PM -// Version <#version#> -// -// Copyright © Daniel Garcia, 2014 -// License <#license#> -// -// See ReadMe.txt for references -// - - -// Core library - IDE-based -#if defined(WIRING) // Wiring specific -#include "Wiring.h" -#elif defined(MAPLE_IDE) // Maple specific -#include "WProgram.h" -#elif defined(MPIDE) // chipKIT specific -#include "WProgram.h" -#elif defined(DIGISPARK) // Digispark specific -#include "Arduino.h" -#elif defined(ENERGIA) // LaunchPad MSP430 G2 and F5529, Stellaris and Tiva, Experimeter Board FR5739 specific -#include "Energia.h" -#elif defined(MICRODUINO) // Microduino specific -#include "Arduino.h" -#elif defined(TEENSYDUINO) // Teensy specific -#include "Arduino.h" -#elif defined(ARDUINO) // Arduino 1.0 and 1.5 specific -#include "Arduino.h" -#else // error -#error Platform not defined -#endif // end IDE - -#ifndef FastLED_LocalLibrary_h -#define FastLED_LocalLibrary_h - -// -// Brief Blink a LED -// Details LED attached to pin is light on then light off -// Total cycle duration = ms -// Parameters: -// pin pin to which the LED is attached -// times number of times -// ms cycle duration in ms -// -void blink(uint8_t pin, uint8_t times, uint16_t ms); - -#endif diff --git a/FastLED/FastLED/Makefile b/FastLED/FastLED/Makefile deleted file mode 100644 index 355c5d17..00000000 --- a/FastLED/FastLED/Makefile +++ /dev/null @@ -1,80 +0,0 @@ -# -# embedXcode -# ---------------------------------- -# Embedded Computing on Xcode -# -# Copyright © Rei VILO, 2010-2014 -# All rights reserved -# http://embedxcode.weebly.com -# -# Last update: Mar 01, 2014 release 136 - - -# Libraries -# ---------------------------------- -# Declare application Arduino/chipKIT/Digispark/Energia/Maple/Microduino/Teensy/Wiring -# and user's libraries used -# Short-listing libraries speeds-up building -# Typing = 0 takes none (default for application and user) -# Otherwise, leaving empty considers all - -# List application Arduino/chipKIT/Digispark/Energia/Maple/Microduino/Teensy/Wiring libraries here -# default = 0 = none -# -APP_LIBS_LIST = 0 - -# List user's libraries here -# default = 0 = none -# -USER_LIBS_LIST = 0 - -# List core, application and user's libraries to be excluded -# For example, WiFi may crash on Arduino 1.0.2, Esplora on Arduino 1.0.3, Firmata on Teensy 3.0, -# OneWire on MPIDE 0023, HardwareSerial may conflict with MarlinSerial -# -#EXCLUDE_LIBS = Firmata WiFi Esplora OneWire Robot_Control Robot_Control/utility Robot_Motor - - -# Parameters -# ---------------------------------- -# Xcode takes BOARD_TAG and BOARD_PORT from the .xcconfig file -# For other IDEs than Xcode, - -# BOARD_TAG is required -# If not defined, error BOARD_TAG not defined -# -#BOARD_TAG = mega2560 - -# BOARD_PORT is optional -# If not defined, BOARD_PORT = /dev/tty.usb* (default) -# -#BOARD_PORT = /dev/tty.usbmodem* - -# Xcode takes SKETCHBOOK_DIR from preferences.txt -# If not defined, each IDE has its own SKETCHBOOK_DIR (default) -# To share the same SKETCHBOOK_DIR along all IDEs, define -# -#SKETCHBOOK_DIR = - -# SERIAL_BAUDRATE for the serial console, 9600 by default -# Uncomment and specify another speed -# -#SERIAL_BAUDRATE = 19200 - - -# Miscellaneous -# ---------------------------------- -# Manage path with space in the name -# -CURRENT_DIR := $(shell pwd) -CURRENT_DIR := $(shell echo '$(CURRENT_DIR)' | sed 's/ /\\\ /g') - -# C-compliant project name -# -PROJECT_NAME_AS_IDENTIFIER = FastLED - -MAKEFILE_PATH = $(CURRENT_DIR)/Makefiles -UTILITIES_PATH = $(CURRENT_DIR)/Utilities - -include $(MAKEFILE_PATH)/Step1.mk - diff --git a/FastLED/FastLED/Makefiles/Arduino.mk b/FastLED/FastLED/Makefiles/Arduino.mk deleted file mode 100755 index 5d7dd4fc..00000000 --- a/FastLED/FastLED/Makefiles/Arduino.mk +++ /dev/null @@ -1,24 +0,0 @@ -# -# embedXcode -# ---------------------------------- -# Embedded Computing on Xcode -# -# Copyright © Rei VILO, 2010-2014 -# http://embedxcode.weebly.com -# All rights reserved -# -# -# Last update: Jun 21, 2013 release 54 - - - -# Arduino specifics -# ---------------------------------- -# Automatic 0023 or 1.x.x selection based on version.txt -# -ifneq ($(shell grep 1. $(ARDUINO_PATH)/lib/version.txt),) - include $(MAKEFILE_PATH)/Arduino1.mk -else - include $(MAKEFILE_PATH)/Arduino23.mk -endif - diff --git a/FastLED/FastLED/Makefiles/Arduino1.mk b/FastLED/FastLED/Makefiles/Arduino1.mk deleted file mode 100755 index 67cd6490..00000000 --- a/FastLED/FastLED/Makefiles/Arduino1.mk +++ /dev/null @@ -1,91 +0,0 @@ -# -# embedXcode -# ---------------------------------- -# Embedded Computing on Xcode -# -# Copyright © Rei VILO, 2010-2014 -# http://embedxcode.weebly.com -# All rights reserved -# -# -# Last update: Jun 21, 2013 release 54 - - - -# Arduino 1.0.x specifics -# ---------------------------------- -# -PLATFORM := Arduino -PLATFORM_TAG = ARDUINO=105 EMBEDXCODE=$(RELEASE_NOW) -APPLICATION_PATH := $(ARDUINO_PATH) - -APP_TOOLS_PATH := $(APPLICATION_PATH)/hardware/tools/avr/bin -CORE_LIB_PATH := $(APPLICATION_PATH)/hardware/arduino/cores/arduino -APP_LIB_PATH := $(APPLICATION_PATH)/libraries -BOARDS_TXT := $(APPLICATION_PATH)/hardware/arduino/boards.txt - -# Sketchbook/Libraries path -# wildcard required for ~ management -# -ifeq ($(USER_PATH)/Library/Arduino/preferences.txt,) - $(error Error: run Arduino once and define the sketchbook path) -endif - -ifeq ($(wildcard $(SKETCHBOOK_DIR)),) - SKETCHBOOK_DIR = $(shell grep sketchbook.path $(USER_PATH)/Library/Arduino/preferences.txt | cut -d = -f 2) -endif -ifeq ($(wildcard $(SKETCHBOOK_DIR)),) - $(error Error: sketchbook path not found) -endif -USER_LIB_PATH = $(wildcard $(SKETCHBOOK_DIR)/?ibraries) - -# Rules for making a c++ file from the main sketch (.pde) -# -PDEHEADER = \\\#include \"Arduino.h\" - -# Tool-chain names -# -CC = $(APP_TOOLS_PATH)/avr-gcc -CXX = $(APP_TOOLS_PATH)/avr-g++ -AR = $(APP_TOOLS_PATH)/avr-ar -OBJDUMP = $(APP_TOOLS_PATH)/avr-objdump -OBJCOPY = $(APP_TOOLS_PATH)/avr-objcopy -SIZE = $(APP_TOOLS_PATH)/avr-size -NM = $(APP_TOOLS_PATH)/avr-nm - -# Specific AVRDUDE location and options -# -AVRDUDE_COM_OPTS = -D -p$(MCU) -C$(AVRDUDE_CONF) - -BOARD = $(call PARSE_BOARD,$(BOARD_TAG),board) -#LDSCRIPT = $(call PARSE_BOARD,$(BOARD_TAG),ldscript) -VARIANT = $(call PARSE_BOARD,$(BOARD_TAG),build.variant) -VARIANT_PATH = $(APPLICATION_PATH)/hardware/arduino/variants/$(VARIANT) - -MCU_FLAG_NAME = mmcu -EXTRA_LDFLAGS = -EXTRA_CPPFLAGS = -MMD -I$(VARIANT_PATH) $(addprefix -D, $(PLATFORM_TAG)) - -# Leonardo USB PID VID -# -USB_TOUCH := $(call PARSE_BOARD,$(BOARD_TAG),upload.protocol) -USB_VID := $(call PARSE_BOARD,$(BOARD_TAG),build.vid) -USB_PID := $(call PARSE_BOARD,$(BOARD_TAG),build.pid) - -ifneq ($(USB_PID),) - USB_FLAGS += -DUSB_PID=$(USB_PID) -else - USB_FLAGS += -DUSB_PID=null -endif - -ifneq ($(USB_VID),) - USB_FLAGS += -DUSB_VID=$(USB_VID) -else - USB_FLAGS += -DUSB_VID=null -endif - -# Serial 1200 reset -# -ifeq ($(USB_TOUCH),avr109) - USB_RESET = $(UTILITIES_PATH)/serial1200.py -endif diff --git a/FastLED/FastLED/Makefiles/Arduino15avr.mk b/FastLED/FastLED/Makefiles/Arduino15avr.mk deleted file mode 100755 index f3b6d836..00000000 --- a/FastLED/FastLED/Makefiles/Arduino15avr.mk +++ /dev/null @@ -1,199 +0,0 @@ -# -# embedXcode -# ---------------------------------- -# Embedded Computing on Xcode -# -# Copyright © Rei VILO, 2010-2014 -# http://embedxcode.weebly.com -# All rights reserved -# -# -# Last update: Feb 10, 2014 release 132 - -# ARDUINO 1.5.X IS STILL IN BETA, UNSTABLE AND PRONE TO BUGS -WARNING_MESSAGE = 'ARDUINO 1.5.X IS STILL IN BETA, UNSTABLE AND PRONE TO BUGS' - - -# Arduino 1.5.x AVR specifics -# ---------------------------------- -# -PLATFORM := Arduino -BUILD_CORE := avr -PLATFORM_TAG = ARDUINO=155 ARDUINO_ARCH_AVR EMBEDXCODE=$(RELEASE_NOW) -APPLICATION_PATH := $(ARDUINO_PATH) - -APP_TOOLS_PATH := $(APPLICATION_PATH)/hardware/tools/avr/bin -CORE_LIB_PATH := $(APPLICATION_PATH)/hardware/arduino/avr/cores/arduino -APP_LIB_PATH := $(APPLICATION_PATH)/libraries -BOARDS_TXT := $(APPLICATION_PATH)/hardware/arduino/avr/boards.txt - -# Sketchbook/Libraries path -# wildcard required for ~ management -# ?ibraries required for libraries and Libraries -# -ifeq ($(USER_PATH)/Library/Arduino/preferences.txt,) - $(error Error: run Arduino once and define the sketchbook path) -endif - -ifeq ($(wildcard $(SKETCHBOOK_DIR)),) - SKETCHBOOK_DIR = $(shell grep sketchbook.path $(USER_PATH)/Library/Arduino15/preferences.txt | cut -d = -f 2) -endif -ifeq ($(wildcard $(SKETCHBOOK_DIR)),) - $(error Error: sketchbook path not found) -endif -USER_LIB_PATH = $(wildcard $(SKETCHBOOK_DIR)/?ibraries) - -# Rules for making a c++ file from the main sketch (.pde) -# -PDEHEADER = \\\#include \"Arduino.h\" - -# Tool-chain names -# -CC = $(APP_TOOLS_PATH)/avr-gcc -CXX = $(APP_TOOLS_PATH)/avr-g++ -AR = $(APP_TOOLS_PATH)/avr-ar -OBJDUMP = $(APP_TOOLS_PATH)/avr-objdump -OBJCOPY = $(APP_TOOLS_PATH)/avr-objcopy -SIZE = $(APP_TOOLS_PATH)/avr-size -NM = $(APP_TOOLS_PATH)/avr-nm - - -# Complicated menu system for Arduino 1.5 -# Another example of Arduino's quick and dirty job -# -MCU := $(call PARSE_BOARD,$(BOARD_TAG),build.mcu) -ifeq ($(MCU),) - MCU := $(call PARSE_BOARD,$(BOARD_TAG1),build.mcu) - ifeq ($(MCU),) - MCU := $(call PARSE_BOARD,$(BOARD_TAG2),build.mcu) - endif -endif - -F_CPU := $(call PARSE_BOARD,$(BOARD_TAG),build.f_cpu) -ifeq ($(F_CPU),) - F_CPU := $(call PARSE_BOARD,$(BOARD_TAG1),build.f_cpu) - ifeq ($(F_CPU),) - F_CPU := $(call PARSE_BOARD,$(BOARD_TAG2),build.f_cpu) - endif -endif - -BOARD_NAME := $(call PARSE_BOARD,$(BOARD_TAG),name) -ifeq ($(BOARD_NAME),) - BOARD_NAME := $(call PARSE_BOARD,$(BOARD_TAG1),name) - ifeq ($(BOARD_NAME),) - BOARD_NAME := $(call PARSE_BOARD,$(BOARD_TAG2),name) - endif -endif - -MAX_FLASH_SIZE := $(call PARSE_BOARD,$(BOARD_TAG),upload.maximum_size) -ifeq ($(MAX_FLASH_SIZE),) - MAX_FLASH_SIZE := $(call PARSE_BOARD,$(BOARD_TAG1),upload.maximum_size) - ifeq ($(MAX_FLASH_SIZE),) - MAX_FLASH_SIZE := $(call PARSE_BOARD,$(BOARD_TAG2),upload.maximum_size) - endif -endif - -AVRDUDE_BAUDRATE := $(call PARSE_BOARD,$(BOARD_TAG),upload.speed) -ifeq ($(AVRDUDE_BAUDRATE),) - AVRDUDE_BAUDRATE := $(call PARSE_BOARD,$(BOARD_TAG1),upload.speed) - ifeq ($(AVRDUDE_BAUDRATE),) - AVRDUDE_BAUDRATE := $(call PARSE_BOARD,$(BOARD_TAG2),upload.speed) - endif -endif - -AVRDUDE_PROGRAMMER := $(call PARSE_BOARD,$(BOARD_TAG),upload.protocol) -ifeq ($(AVRDUDE_PROGRAMMER),) - AVRDUDE_PROGRAMMER := $(call PARSE_BOARD,$(BOARD_TAG1),upload.protocol) - ifeq ($(AVRDUDE_PROGRAMMER),) - AVRDUDE_PROGRAMMER := $(call PARSE_BOARD,$(BOARD_TAG2),upload.protocol) - endif -endif - - - -#ifeq ($(BOARD_TAG2),) -# MCU = $(call PARSE_BOARD,$(BOARD_TAG),build.mcu) -# F_CPU = $(call PARSE_BOARD,$(BOARD_TAG),build.f_cpu) -#else -# MCU = $(call PARSE_BOARD,$(BOARD_TAG2),build.mcu) -# F_CPU = $(call PARSE_BOARD,$(BOARD_TAG2),build.f_cpu) -#endif - -# Specific AVRDUDE location and options -# -AVRDUDE_COM_OPTS = -D -p$(MCU) -C$(AVRDUDE_CONF) - -ifneq ($(BOARD_TAG1),) -#BOARD = $(call PARSE_BOARD,$(BOARD_TAG1),board) -#LDSCRIPT = $(call PARSE_BOARD,$(BOARD_TAG1),ldscript) -VARIANT = $(call PARSE_BOARD,$(BOARD_TAG1),build.variant) -VARIANT_PATH = $(APPLICATION_PATH)/hardware/arduino/avr/variants/$(VARIANT) -else -#BOARD = $(call PARSE_BOARD,$(BOARD_TAG),board) -#LDSCRIPT = $(call PARSE_BOARD,$(BOARD_TAG),ldscript) -VARIANT = $(call PARSE_BOARD,$(BOARD_TAG),build.variant) -VARIANT_PATH = $(APPLICATION_PATH)/hardware/arduino/avr/variants/$(VARIANT) -endif - -# Two locations for Arduino libraries -# -BUILD_APP_LIB_PATH = $(APPLICATION_PATH)/hardware/arduino/$(BUILD_CORE)/libraries - -ifndef APP_LIBS_LIST - w1 = $(realpath $(sort $(dir $(wildcard $(APP_LIB_PATH)/*/*.h $(APP_LIB_PATH)/*/*/*.h)))) # */ - APP_LIBS_LIST = $(subst $(APP_LIB_PATH)/,,$(filter-out $(EXCLUDE_LIST),$(w1))) - - w2 = $(realpath $(sort $(dir $(wildcard $(BUILD_APP_LIB_PATH)/*/*.h $(BUILD_APP_LIB_PATH)/*/*/*.h)))) # */ - BUILD_APP_LIBS_LIST = $(subst $(BUILD_APP_LIB_PATH)/,,$(filter-out $(EXCLUDE_LIST),$(w2))) -else - w2 = $(realpath $(sort $(dir $(wildcard $(BUILD_APP_LIB_PATH)/*/*.h $(BUILD_APP_LIB_PATH)/*/*/*.h)))) # */ - BUILD_APP_LIBS_LIST = $(subst $(BUILD_APP_LIB_PATH)/,,$(filter-out $(EXCLUDE_LIST),$(w2))) -endif - - -# Arduino 1.5.x nightmare with src and arch/sam or arch/avr -# -ifneq ($(APP_LIBS_LIST),0) - APP_LIBS = $(patsubst %,$(APP_LIB_PATH)/%/src,$(APP_LIBS_LIST)) - APP_LIBS += $(patsubst %,$(APP_LIB_PATH)/%/arch/$(BUILD_CORE),$(APP_LIBS_LIST)) - - APP_LIB_CPP_SRC = $(wildcard $(patsubst %,%/*.cpp,$(APP_LIBS))) # */ - APP_LIB_C_SRC = $(wildcard $(patsubst %,%/*.c,$(APP_LIBS))) # */ - - APP_LIB_OBJS = $(patsubst $(APP_LIB_PATH)/%.cpp,$(OBJDIR)/libs/%.o,$(APP_LIB_CPP_SRC)) - APP_LIB_OBJS += $(patsubst $(APP_LIB_PATH)/%.c,$(OBJDIR)/libs/%.o,$(APP_LIB_C_SRC)) - - BUILD_APP_LIBS = $(patsubst %,$(BUILD_APP_LIB_PATH)/%,$(BUILD_APP_LIBS_LIST)) - - BUILD_APP_LIB_CPP_SRC = $(wildcard $(patsubst %,%/*.cpp,$(BUILD_APP_LIBS))) # */ - BUILD_APP_LIB_C_SRC = $(wildcard $(patsubst %,%/*.c,$(BUILD_APP_LIBS))) # */ - - BUILD_APP_LIB_OBJS = $(patsubst $(BUILD_APP_LIB_PATH)/%.cpp,$(OBJDIR)/libs/%.o,$(BUILD_APP_LIB_CPP_SRC)) - BUILD_APP_LIB_OBJS += $(patsubst $(BUILD_APP_LIB_PATH)/%.c,$(OBJDIR)/libs/%.o,$(BUILD_APP_LIB_C_SRC)) -endif - - -MCU_FLAG_NAME = mmcu -EXTRA_LDFLAGS = -EXTRA_CPPFLAGS = -I$(VARIANT_PATH) $(addprefix -D, $(PLATFORM_TAG)) - - -# Arduino Leonardo USB PID VID -# -USB_VID := $(call PARSE_BOARD,$(BOARD_TAG),build.vid) -USB_PID := $(call PARSE_BOARD,$(BOARD_TAG),build.pid) - -ifneq ($(USB_PID),) -ifneq ($(USB_VID),) - USB_FLAGS = -DUSB_VID=$(USB_VID) - USB_FLAGS += -DUSB_PID=$(USB_PID) -endif -endif - -# Arduino Leonardo serial 1200 reset -# -USB_TOUCH := $(call PARSE_BOARD,$(BOARD_TAG),upload.protocol) - -ifeq ($(USB_TOUCH),avr109) - USB_RESET = $(UTILITIES_PATH)/serial1200.py -endif diff --git a/FastLED/FastLED/Makefiles/Arduino15sam.mk b/FastLED/FastLED/Makefiles/Arduino15sam.mk deleted file mode 100755 index 4ac899eb..00000000 --- a/FastLED/FastLED/Makefiles/Arduino15sam.mk +++ /dev/null @@ -1,157 +0,0 @@ -# -# embedXcode -# ---------------------------------- -# Embedded Computing on Xcode -# -# Copyright © Rei VILO, 2010-2014 -# http://embedxcode.weebly.com -# All rights reserved -# -# -# Last update: Feb 10, 2014 release 132 - -# ARDUINO 1.5.X IS STILL IN BETA, UNSTABLE AND PRONE TO BUGS -WARNING_MESSAGE = 'ARDUINO 1.5.X IS STILL IN BETA, UNSTABLE AND PRONE TO BUGS' - - -# Arduino 1.5.x SAM specifics -# ---------------------------------- -# -PLATFORM := Arduino -BUILD_CORE := sam -PLATFORM_TAG = ARDUINO=155 ARDUINO_ARCH_SAM EMBEDXCODE=$(RELEASE_NOW) -APPLICATION_PATH := $(ARDUINO_PATH) - -APP_TOOLS_PATH := $(APPLICATION_PATH)/hardware/tools/g++_arm_none_eabi/bin -CORE_LIB_PATH := $(APPLICATION_PATH)/hardware/arduino/sam/cores/arduino -APP_LIB_PATH := $(APPLICATION_PATH)/libraries -BOARDS_TXT := $(APPLICATION_PATH)/hardware/arduino/sam/boards.txt - -# -# Uploader bossac -# Tested by Mike Roberts -# -UPLOADER = bossac -BOSSAC_PATH = $(APPLICATION_PATH)/hardware/tools -BOSSAC = $(BOSSAC_PATH)/bossac -BOSSAC_PORT = $(subst /dev/,,$(AVRDUDE_PORT)) -BOSSAC_OPTS = --port=$(BOSSAC_PORT) -U false -e -w -v -b - -# Sketchbook/Libraries path -# wildcard required for ~ management -# ?ibraries required for libraries and Libraries -# -ifeq ($(USER_PATH)/Library/Arduino/preferences.txt,) - $(error Error: run Arduino once and define the sketchbook path) -endif - -ifeq ($(wildcard $(SKETCHBOOK_DIR)),) - SKETCHBOOK_DIR = $(shell grep sketchbook.path $(USER_PATH)/Library/Arduino15/preferences.txt | cut -d = -f 2) -endif - -ifeq ($(wildcard $(SKETCHBOOK_DIR)),) - $(error Error: sketchbook path not found) -endif - -USER_LIB_PATH = $(wildcard $(SKETCHBOOK_DIR)/?ibraries) - -# Rules for making a c++ file from the main sketch (.pde) -# -PDEHEADER = \\\#include \"Arduino.h\" - -# Tool-chain names -# -CC = $(APP_TOOLS_PATH)/arm-none-eabi-gcc -CXX = $(APP_TOOLS_PATH)/arm-none-eabi-g++ -AR = $(APP_TOOLS_PATH)/arm-none-eabi-ar -OBJDUMP = $(APP_TOOLS_PATH)/arm-none-eabi-objdump -OBJCOPY = $(APP_TOOLS_PATH)/arm-none-eabi-objcopy -SIZE = $(APP_TOOLS_PATH)/arm-none-eabi-size -NM = $(APP_TOOLS_PATH)/arm-none-eabi-nm - -# Specific AVRDUDE location and options -# -AVRDUDE_COM_OPTS = -D -p$(MCU) -C$(AVRDUDE_CONF) - -BOARD = $(call PARSE_BOARD,$(BOARD_TAG),board) -LDSCRIPT = $(call PARSE_BOARD,$(BOARD_TAG),build.ldscript) -VARIANT = $(call PARSE_BOARD,$(BOARD_TAG),build.variant) -VARIANT_PATH = $(APPLICATION_PATH)/hardware/arduino/sam/variants/$(VARIANT) -VARIANT_CPP_SRCS = $(wildcard $(VARIANT_PATH)/*.cpp) # */ $(VARIANT_PATH)/*/*.cpp #*/ -VARIANT_OBJ_FILES = $(VARIANT_CPP_SRCS:.cpp=.o) -VARIANT_OBJS = $(patsubst $(VARIANT_PATH)/%,$(OBJDIR)/%,$(VARIANT_OBJ_FILES)) - -SYSTEM_LIB = $(call PARSE_BOARD,$(BOARD_TAG),build.variant_system_lib) -SYSTEM_PATH = $(VARIANT_PATH) -SYSTEM_OBJS = $(SYSTEM_PATH)/$(SYSTEM_LIB) - - -# Two locations for Arduino libraries -# -BUILD_APP_LIB_PATH = $(APPLICATION_PATH)/hardware/arduino/$(BUILD_CORE)/libraries - -ifndef APP_LIBS_LIST - w1 = $(realpath $(sort $(dir $(wildcard $(APP_LIB_PATH)/*/*.h $(APP_LIB_PATH)/*/*/*.h)))) # */ - APP_LIBS_LIST = $(subst $(APP_LIB_PATH)/,,$(filter-out $(EXCLUDE_LIST),$(w1))) - - w2 = $(realpath $(sort $(dir $(wildcard $(BUILD_APP_LIB_PATH)/*/*.h $(BUILD_APP_LIB_PATH)/*/*/*.h)))) # */ - BUILD_APP_LIBS_LIST = $(subst $(BUILD_APP_LIB_PATH)/,,$(filter-out $(EXCLUDE_LIST),$(w2))) -else - w2 = $(realpath $(sort $(dir $(wildcard $(BUILD_APP_LIB_PATH)/*/*.h $(BUILD_APP_LIB_PATH)/*/*/*.h)))) # */ - BUILD_APP_LIBS_LIST = $(subst $(BUILD_APP_LIB_PATH)/,,$(filter-out $(EXCLUDE_LIST),$(w2))) -endif - - -# Arduino 1.5.x nightmare with src and arch/sam or arch/avr -# Another example of Arduino's quick and dirty job -# -ifneq ($(APP_LIBS_LIST),0) - APP_LIBS = $(patsubst %,$(APP_LIB_PATH)/%/src,$(APP_LIBS_LIST)) - APP_LIBS += $(patsubst %,$(APP_LIB_PATH)/%/arch/$(BUILD_CORE),$(APP_LIBS_LIST)) - - APP_LIB_CPP_SRC = $(wildcard $(patsubst %,%/*.cpp,$(APP_LIBS))) # */ - APP_LIB_C_SRC = $(wildcard $(patsubst %,%/*.c,$(APP_LIBS))) # */ - - APP_LIB_OBJS = $(patsubst $(APP_LIB_PATH)/%.cpp,$(OBJDIR)/libs/%.o,$(APP_LIB_CPP_SRC)) - APP_LIB_OBJS += $(patsubst $(APP_LIB_PATH)/%.c,$(OBJDIR)/libs/%.o,$(APP_LIB_C_SRC)) - - BUILD_APP_LIBS = $(patsubst %,$(BUILD_APP_LIB_PATH)/%,$(BUILD_APP_LIBS_LIST)) - - BUILD_APP_LIB_CPP_SRC = $(wildcard $(patsubst %,%/*.cpp,$(BUILD_APP_LIBS))) # */ - BUILD_APP_LIB_C_SRC = $(wildcard $(patsubst %,%/*.c,$(BUILD_APP_LIBS))) # */ - - BUILD_APP_LIB_OBJS = $(patsubst $(BUILD_APP_LIB_PATH)/%.cpp,$(OBJDIR)/libs/%.o,$(BUILD_APP_LIB_CPP_SRC)) - BUILD_APP_LIB_OBJS += $(patsubst $(BUILD_APP_LIB_PATH)/%.c,$(OBJDIR)/libs/%.o,$(BUILD_APP_LIB_C_SRC)) -endif - -SYSTEM_FLAGS = -I$(APPLICATION_PATH)/hardware/arduino/sam/system/libsam -SYSTEM_FLAGS += -I$(APPLICATION_PATH)/hardware/arduino/sam/system/libsam/include -SYSTEM_FLAGS += -I$(APPLICATION_PATH)/hardware/arduino/sam/system/CMSIS/CMSIS/Include/ -SYSTEM_FLAGS += -I$(APPLICATION_PATH)/hardware/arduino/sam/system/CMSIS/Device/ATMEL/ - -MCU_FLAG_NAME = mcpu -EXTRA_LDFLAGS = -T$(VARIANT_PATH)/$(LDSCRIPT) -Wl,-Map,Builds/embeddedcomputing.map $(VARIANT_OBJS) -EXTRA_LDFLAGS += -lgcc -mthumb -Wl,--cref -Wl,--check-sections -Wl,--gc-sections -Wl,--entry=Reset_Handler -EXTRA_LDFLAGS += -Wl,--unresolved-symbols=report-all -Wl,--warn-common -Wl,--warn-section-align -EXTRA_LDFLAGS += -Wl,--warn-unresolved-symbols - -EXTRA_CPPFLAGS = -I$(VARIANT_PATH) $(addprefix -D, $(PLATFORM_TAG)) -D__SAM3X8E__ -mthumb -fno-rtti -EXTRA_CPPFLAGS += -nostdlib --param max-inline-insns-single=500 -Dprintf=iprintf $(SYSTEM_FLAGS) - -OBJCOPYFLAGS = -v -Obinary -TARGET_HEXBIN = $(TARGET_BIN) - -# Arduino Due USB PID VID -# -USB_VID := $(call PARSE_BOARD,$(BOARD_TAG),build.vid) -USB_PID := $(call PARSE_BOARD,$(BOARD_TAG),build.pid) - -USB_FLAGS = -DUSB_VID=$(USB_VID) -USB_FLAGS += -DUSB_PID=$(USB_PID) -USB_FLAGS += -DUSBCON - -# Arduino Due serial 1200 reset -# -USB_TOUCH := $(call PARSE_BOARD,$(BOARD_TAG),upload.protocol) -USB_RESET = $(UTILITIES_PATH)/serial1200.py - diff --git a/FastLED/FastLED/Makefiles/Arduino23.mk b/FastLED/FastLED/Makefiles/Arduino23.mk deleted file mode 100755 index 828fbbe1..00000000 --- a/FastLED/FastLED/Makefiles/Arduino23.mk +++ /dev/null @@ -1,69 +0,0 @@ -# -# embedXcode -# ---------------------------------- -# Embedded Computing on Xcode -# -# Copyright © Rei VILO, 2010-2014 -# http://embedxcode.weebly.com -# All rights reserved -# -# -# Last update: Apr 28, 2013 release 47 - -# ARDUINO 0023 IS NO LONGER SUPPORTED -WARNING_MESSAGE = 'WARNING_MESSAGE - ARDUINO 0023 IS NO LONGER SUPPORTED' - - -# Arduino 0023 specifics -# ---------------------------------- -# -PLATFORM := Arduino -PLATFORM_TAG = ARDUINO=23 EMBEDXCODE=$(RELEASE_NOW) -APPLICATION_PATH := $(ARDUINO_PATH) - -APP_TOOLS_PATH := $(APPLICATION_PATH)/hardware/tools/avr/bin -CORE_LIB_PATH := $(APPLICATION_PATH)/hardware/arduino/cores/arduino -APP_LIB_PATH := $(APPLICATION_PATH)/libraries -BOARDS_TXT := $(APPLICATION_PATH)/hardware/arduino/boards.txt - -# Sketchbook/Libraries path -# wildcard required for ~ management -# ?ibraries required for libraries and Libraries -# -ifeq ($(USER_PATH)/Library/Arduino/preferences.txt,) - $(error Error: run Arduino once and define the sketchbook path) -endif - -ifeq ($(wildcard $(SKETCHBOOK_DIR)),) - SKETCHBOOK_DIR = $(shell grep sketchbook.path $(USER_PATH)/Library/Arduino/preferences.txt | cut -d = -f 2) -endif -ifeq ($(wildcard $(SKETCHBOOK_DIR)),) - $(error Error: sketchbook path not found) -endif -USER_LIB_PATH = $(wildcard $(SKETCHBOOK_DIR)/?ibraries) - -# Rules for making a c++ file from the main sketch (.pde) -# -PDEHEADER = \\\#include \"WProgram.h\" - -# Tool-chain names -# -CC = $(APP_TOOLS_PATH)/avr-gcc -CXX = $(APP_TOOLS_PATH)/avr-g++ -AR = $(APP_TOOLS_PATH)/avr-ar -OBJDUMP = $(APP_TOOLS_PATH)/avr-objdump -OBJCOPY = $(APP_TOOLS_PATH)/avr-objcopy -SIZE = $(APP_TOOLS_PATH)/avr-size -NM = $(APP_TOOLS_PATH)/avr-nm - - -BOARD = $(call PARSE_BOARD,$(BOARD_TAG),board) -#LDSCRIPT = $(call PARSE_BOARD,$(BOARD_TAG),ldscript) -#VARIANT = $(call PARSE_BOARD,$(BOARD_TAG),build.variant) - -MCU_FLAG_NAME = mmcu -EXTRA_LDFLAGS = -EXTRA_CPPFLAGS = $(addprefix -D, $(PLATFORM_TAG)) - - - diff --git a/FastLED/FastLED/Makefiles/Avrdude.mk b/FastLED/FastLED/Makefiles/Avrdude.mk deleted file mode 100755 index 9ec70336..00000000 --- a/FastLED/FastLED/Makefiles/Avrdude.mk +++ /dev/null @@ -1,93 +0,0 @@ -# -# embedXcode -# ---------------------------------- -# Embedded Computing on Xcode -# -# Copyright © Rei VILO, 2010-2014 -# http://embedxcode.weebly.com -# All rights reserved -# -# -# Last update: Nov 04, 2013 release 112 - - - -# AVRDUDE -# ---------------------------------- -# -# First /dev port -# -# Port is no longer managed here but AVRDUDE_PORT is required for serial console -# -AVRDUDE_PORT = $(firstword $(wildcard $(BOARD_PORT))) - -ifndef AVRDUDE_PATH - AVRDUDE_PATH = $(APPLICATION_PATH)/hardware/tools/avr -endif - -ifndef AVRDUDE - AVRDUDE_EXEC = $(AVRDUDE_PATH)/bin/avrdude -endif - -ifndef AVRDUDE_CONF - AVRDUDE_CONF = $(AVRDUDE_PATH)/etc/avrdude.conf -endif - -ifndef AVRDUDE_COM_OPTS - AVRDUDE_COM_OPTS = -q -V -F -p$(MCU) -C$(AVRDUDE_CONF) -endif - -ifndef AVRDUDE_OPTS -# AVRDUDE_OPTS = -c$(AVRDUDE_PROGRAMMER) -b$(AVRDUDE_BAUDRATE) -P$(AVRDUDE_PORT) - AVRDUDE_OPTS = -c$(AVRDUDE_PROGRAMMER) -b$(AVRDUDE_BAUDRATE) -endif - -ifndef AVRDUDE_MCU - AVRDUDE_MCU = $(MCU) -endif - -ifndef ISP_PROG - ISP_PROG = -c stk500v2 -endif - -ifneq ($(ISP_PORT),) - AVRDUDE_ISP_OPTS = -P $(ISP_PORT) $(ISP_PROG) -else - AVRDUDE_ISP_OPTS = $(ISP_PROG) -endif - -# normal programming info -# -ifndef AVRDUDE_PROGRAMMER - AVRDUDE_PROGRAMMER = $(call PARSE_BOARD,$(BOARD_TAG),upload.protocol) -endif - -ifndef AVRDUDE_BAUDRATE - AVRDUDE_BAUDRATE = $(call PARSE_BOARD,$(BOARD_TAG),upload.speed) -endif - -# fuses if you're using e.g. ISP -# -ifndef ISP_LOCK_FUSE_PRE - ISP_LOCK_FUSE_PRE = $(call PARSE_BOARD,$(BOARD_TAG),bootloader.unlock_bits) -endif - -ifndef ISP_LOCK_FUSE_POST - ISP_LOCK_FUSE_POST = $(call PARSE_BOARD,$(BOARD_TAG),bootloader.lock_bits) -endif - -ifndef ISP_HIGH_FUSE - ISP_HIGH_FUSE = $(call PARSE_BOARD,$(BOARD_TAG),bootloader.high_fuses) -endif - -ifndef ISP_LOW_FUSE - ISP_LOW_FUSE = $(call PARSE_BOARD,$(BOARD_TAG),bootloader.low_fuses) -endif - -ifndef ISP_EXT_FUSE - ISP_EXT_FUSE = $(call PARSE_BOARD,$(BOARD_TAG),bootloader.extended_fuses) -endif - -ifndef VARIANT - VARIANT = $(call PARSE_BOARD,$(BOARD_TAG),build.variant) -endif diff --git a/FastLED/FastLED/Makefiles/Digispark.mk b/FastLED/FastLED/Makefiles/Digispark.mk deleted file mode 100755 index 8c6003fa..00000000 --- a/FastLED/FastLED/Makefiles/Digispark.mk +++ /dev/null @@ -1,132 +0,0 @@ -# -# embedXcode -# ---------------------------------- -# Embedded Computing on Xcode -# -# Copyright © Rei VILO, 2010-2014 -# http://embedxcode.weebly.com -# All rights reserved -# -# -# Last update: Apr 28, 2013 release 47 - - - -# Digistark 1.04 AVR specifics -# ---------------------------------- -# -PLATFORM := Digistark -BUILD_CORE := avr -PLATFORM_TAG = ARDUINO=105 DIGISPARK EMBEDXCODE=$(RELEASE_NOW) -APPLICATION_PATH := $(DIGISPARK_PATH) - -APP_TOOLS_PATH := $(APPLICATION_PATH)/hardware/tools/avr/bin -CORE_LIB_PATH := $(APPLICATION_PATH)/hardware/digispark/cores/tiny -APP_LIB_PATH := $(APPLICATION_PATH)/libraries -BOARDS_TXT := $(APPLICATION_PATH)/hardware/digispark/boards.txt - -# -# Uploader bossac -# -UPLOADER = micronucleus - - -# Sketchbook/Libraries path -# wildcard required for ~ management -# ?ibraries required for libraries and Libraries -# -ifeq ($(USER_PATH)/Library/Arduino/preferences.txt,) - $(error Error: run Arduino once and define the sketchbook path) -endif - -ifeq ($(wildcard $(SKETCHBOOK_DIR)),) - SKETCHBOOK_DIR = $(shell grep sketchbook.path $(USER_PATH)/Library/Arduino/preferences.txt | cut -d = -f 2) -endif -ifeq ($(wildcard $(SKETCHBOOK_DIR)),) - $(error Error: sketchbook path not found) -endif -USER_LIB_PATH = $(wildcard $(SKETCHBOOK_DIR)/?ibraries) - -# Rules for making a c++ file from the main sketch (.pde) -# -PDEHEADER = \\\#include \"Arduino.h\" - -# Tool-chain names -# -CC = $(APP_TOOLS_PATH)/avr-gcc -CXX = $(APP_TOOLS_PATH)/avr-g++ -AR = $(APP_TOOLS_PATH)/avr-ar -OBJDUMP = $(APP_TOOLS_PATH)/avr-objdump -OBJCOPY = $(APP_TOOLS_PATH)/avr-objcopy -SIZE = $(APP_TOOLS_PATH)/avr-size -NM = $(APP_TOOLS_PATH)/avr-nm - -# Specific AVRDUDE location and options -# -AVRDUDE_COM_OPTS = -D -p$(MCU) -C$(AVRDUDE_CONF) - -BOARD = $(call PARSE_BOARD,$(BOARD_TAG),board) -#LDSCRIPT = $(call PARSE_BOARD,$(BOARD_TAG),ldscript) -#VARIANT = $(call PARSE_BOARD,$(BOARD_TAG),build.variant) -#VARIANT_PATH = $(APPLICATION_PATH)/hardware/arduino/avr/variants/$(VARIANT) - - -# Two locations for Arduino libraries -# -BUILD_APP_LIB_PATH = $(APPLICATION_PATH)/hardware/arduino/$(BUILD_CORE)/libraries - -ifndef APP_LIBS_LIST - w1 = $(realpath $(sort $(dir $(wildcard $(APP_LIB_PATH)/*/*.h $(APP_LIB_PATH)/*/*/*.h)))) # */ - APP_LIBS_LIST = $(subst $(APP_LIB_PATH)/,,$(filter-out $(EXCLUDE_LIST),$(w1))) - - w2 = $(realpath $(sort $(dir $(wildcard $(BUILD_APP_LIB_PATH)/*/*.h $(BUILD_APP_LIB_PATH)/*/*/*.h)))) # */ - BUILD_APP_LIBS_LIST = $(subst $(BUILD_APP_LIB_PATH)/,,$(filter-out $(EXCLUDE_LIST),$(w2))) -else - BUILD_APP_LIBS_LIST = $(APP_LIBS_LIST) -endif - -ifneq ($(APP_LIBS_LIST),0) - APP_LIBS = $(patsubst %,$(APP_LIB_PATH)/%,$(APP_LIBS_LIST)) - APP_LIB_CPP_SRC = $(wildcard $(patsubst %,%/*.cpp,$(APP_LIBS))) # */ - APP_LIB_C_SRC = $(wildcard $(patsubst %,%/*.c,$(APP_LIBS))) # */ - - APP_LIB_OBJS = $(patsubst $(APP_LIB_PATH)/%.cpp,$(OBJDIR)/libs/%.o,$(APP_LIB_CPP_SRC)) - APP_LIB_OBJS += $(patsubst $(APP_LIB_PATH)/%.c,$(OBJDIR)/libs/%.o,$(APP_LIB_C_SRC)) - - BUILD_APP_LIBS = $(patsubst %,$(BUILD_APP_LIB_PATH)/%,$(BUILD_APP_LIBS_LIST)) - BUILD_APP_LIB_CPP_SRC = $(wildcard $(patsubst %,%/*.cpp,$(BUILD_APP_LIBS))) # */ - BUILD_APP_LIB_C_SRC = $(wildcard $(patsubst %,%/*.c,$(BUILD_APP_LIBS))) # */ - - BUILD_APP_LIB_OBJS = $(patsubst $(BUILD_APP_LIB_PATH)/%.cpp,$(OBJDIR)/libs/%.o,$(BUILD_APP_LIB_CPP_SRC)) - BUILD_APP_LIB_OBJS += $(patsubst $(BUILD_APP_LIB_PATH)/%.c,$(OBJDIR)/libs/%.o,$(BUILD_APP_LIB_C_SRC)) -endif - - -MCU_FLAG_NAME = mmcu -EXTRA_LDFLAGS = -EXTRA_CPPFLAGS = $(addprefix -D, $(PLATFORM_TAG)) - - -# Arduino Leonardo USB PID VID -# -USB_VID := $(call PARSE_BOARD,$(BOARD_TAG),build.vid) -USB_PID := $(call PARSE_BOARD,$(BOARD_TAG),build.pid) - -ifneq ($(USB_PID),) -ifneq ($(USB_VID),) - USB_FLAGS = -DUSB_VID=$(USB_VID) - USB_FLAGS += -DUSB_PID=$(USB_PID) -endif -endif - -# Arduino Leonardo serial 1200 reset -# -USB_TOUCH := $(call PARSE_BOARD,$(BOARD_TAG),upload.use_1200bps_touch) - -ifneq ($(USB_TOUCH),) - USB_RESET = $(UTILITIES_PATH)/serial1200.py -endif - -TARGET_EEP = $(OBJDIR)/$(TARGET).eep -AVRDUDE_OPTS = -cdigispark -Pusb - diff --git a/FastLED/FastLED/Makefiles/Energia430.mk b/FastLED/FastLED/Makefiles/Energia430.mk deleted file mode 100755 index 68520d77..00000000 --- a/FastLED/FastLED/Makefiles/Energia430.mk +++ /dev/null @@ -1,84 +0,0 @@ -# -# embedXcode -# ---------------------------------- -# Embedded Computing on Xcode -# -# Copyright © Rei VILO, 2010-2014 -# http://embedxcode.weebly.com -# All rights reserved -# -# -# Last update: Dec 10, 2013 release 119 - - - -# Energia LaunchPad MSP430 and FR5739 specifics -# ---------------------------------- -# -PLATFORM := Energia -PLATFORM_TAG = ENERGIA=9 ARDUINO=101 EMBEDXCODE=$(RELEASE_NOW) $(filter __%__ ,$(GCC_PREPROCESSOR_DEFINITIONS)) -#PLATFORM_TAG = ENERGIA=9 ARDUINO=101 EMBEDXCODE=$(RELEASE_NOW) $(filter-out ENERGIA,$(GCC_PREPROCESSOR_DEFINITIONS)) -APPLICATION_PATH := $(ENERGIA_PATH) - -UPLOADER = mspdebug -MSPDEBUG_PATH = $(APPLICATION_PATH)/hardware/tools/msp430/mspdebug -MSPDEBUG = $(MSPDEBUG_PATH)/mspdebug -MSPDEBUG_PROTOCOL = $(call PARSE_BOARD,$(BOARD_TAG),upload.protocol) -MSPDEBUG_OPTS = $(MSPDEBUG_PROTOCOL) --force-reset - -# FraunchPad MSP430FR5739 requires a specific command -# -ifeq ($(BOARD_TAG), lpmsp430fr5739) - MSPDEBUG_COMMAND = load -else - MSPDEBUG_COMMAND = prog -endif - -APP_TOOLS_PATH := $(APPLICATION_PATH)/hardware/tools/msp430/bin -CORE_LIB_PATH := $(APPLICATION_PATH)/hardware/msp430/cores/msp430 -APP_LIB_PATH := $(APPLICATION_PATH)/hardware/msp430/libraries -BOARDS_TXT := $(APPLICATION_PATH)/hardware/msp430/boards.txt - -# Sketchbook/Libraries path -# wildcard required for ~ management -# ?ibraries required for libraries and Libraries -# -ifeq ($(USER_PATH)/Library/Energia/preferences.txt,) - $(error Error: run Energia once and define the sketchbook path) -endif - -ifeq ($(wildcard $(SKETCHBOOK_DIR)),) - SKETCHBOOK_DIR = $(shell grep sketchbook.path $(wildcard ~/Library/Energia/preferences.txt) | cut -d = -f 2) -endif -ifeq ($(wildcard $(SKETCHBOOK_DIR)),) - $(error Error: sketchbook path not found) -endif -USER_LIB_PATH = $(wildcard $(SKETCHBOOK_DIR)/?ibraries) - - -# Rules for making a c++ file from the main sketch (.pde) -# -PDEHEADER = \\\#include \"Energia.h\" - - -# Tool-chain names -# -CC = $(APP_TOOLS_PATH)/msp430-gcc -CXX = $(APP_TOOLS_PATH)/msp430-g++ -AR = $(APP_TOOLS_PATH)/msp430-ar -OBJDUMP = $(APP_TOOLS_PATH)/msp430-objdump -OBJCOPY = $(APP_TOOLS_PATH)/msp430-objcopy -SIZE = $(APP_TOOLS_PATH)/msp430-size -NM = $(APP_TOOLS_PATH)/msp430-nm -GDB = $(APP_TOOLS_PATH)/msp430-gdb - -BOARD = $(call PARSE_BOARD,$(BOARD_TAG),board) -#LDSCRIPT = $(call PARSE_BOARD,$(BOARD_TAG),ldscript) -VARIANT = $(call PARSE_BOARD,$(BOARD_TAG),build.variant) -VARIANT_PATH = $(APPLICATION_PATH)/hardware/msp430/variants/$(VARIANT) - -MCU_FLAG_NAME = mmcu -EXTRA_LDFLAGS = -#EXTRA_LDFLAGS = -T$(CORE_LIB_PATH)/$(LDSCRIPT) -EXTRA_CPPFLAGS = $(addprefix -D, $(PLATFORM_TAG)) -I$(VARIANT_PATH) - diff --git a/FastLED/FastLED/Makefiles/EnergiaLM4F.mk b/FastLED/FastLED/Makefiles/EnergiaLM4F.mk deleted file mode 100755 index edb83e98..00000000 --- a/FastLED/FastLED/Makefiles/EnergiaLM4F.mk +++ /dev/null @@ -1,102 +0,0 @@ -# -# embedXcode -# ---------------------------------- -# Embedded Computing on Xcode -# -# Copyright © Rei VILO, 2010-2014 -# http://embedxcode.weebly.com -# All rights reserved -# -# -# Last update: Mar 01, 2014 release 136 - - - -# Energia LaunchPad Stellaris and Tiva C specifics -# ---------------------------------- -# -PLATFORM := Energia -PLATFORM_TAG = ENERGIA=9 ARDUINO=101 EMBEDXCODE=$(RELEASE_NOW) $(filter __%__ ,$(GCC_PREPROCESSOR_DEFINITIONS)) -#PLATFORM_TAG = ENERGIA=9 ARDUINO=101 EMBEDXCODE=$(RELEASE_NOW) $(filter-out ENERGIA,$(GCC_PREPROCESSOR_DEFINITIONS)) -APPLICATION_PATH := $(ENERGIA_PATH) - -UPLOADER = lm4flash -LM4FLASH_PATH = $(APPLICATION_PATH)/hardware/tools -LM4FLASH = $(LM4FLASH_PATH)/lm4f/bin/lm4flash -LM4FLASH_OPTS = - -# StellarPad requires a specific command -# -MSPDEBUG_COMMAND = prog - -APP_TOOLS_PATH := $(APPLICATION_PATH)/hardware/tools/lm4f/bin -CORE_LIB_PATH := $(APPLICATION_PATH)/hardware/lm4f/cores/lm4f -APP_LIB_PATH := $(APPLICATION_PATH)/hardware/lm4f/libraries -BOARDS_TXT := $(APPLICATION_PATH)/hardware/lm4f/boards.txt - -BUILD_CORE_LIB_PATH = $(APPLICATION_PATH)/hardware/lm4f/cores/lm4f/driverlib -BUILD_CORE_LIBS_LIST = $(subst .h,,$(subst $(BUILD_CORE_LIB_PATH)/,,$(wildcard $(BUILD_CORE_LIB_PATH)/*.h))) # */ - -BUILD_CORE_C_SRCS = $(wildcard $(BUILD_CORE_LIB_PATH)/*.c) # */ - -ifneq ($(strip $(NO_CORE_MAIN_FUNCTION)),) - BUILD_CORE_CPP_SRCS = $(filter-out %program.cpp %main.cpp,$(wildcard $(BUILD_CORE_LIB_PATH)/*.cpp)) # */ -else - BUILD_CORE_CPP_SRCS = $(filter-out %program.cpp, $(wildcard $(BUILD_CORE_LIB_PATH)/*.cpp)) # */ -endif - -BUILD_CORE_OBJ_FILES = $(BUILD_CORE_C_SRCS:.c=.o) $(BUILD_CORE_CPP_SRCS:.cpp=.o) -BUILD_CORE_OBJS = $(patsubst $(BUILD_CORE_LIB_PATH)/%,$(OBJDIR)/%,$(BUILD_CORE_OBJ_FILES)) - -# Sketchbook/Libraries path -# wildcard required for ~ management -# ?ibraries required for libraries and Libraries -# -ifeq ($(USER_PATH)/Library/Energia/preferences.txt,) - $(error Error: run Energia once and define the sketchbook path) -endif - -ifeq ($(wildcard $(SKETCHBOOK_DIR)),) - SKETCHBOOK_DIR = $(shell grep sketchbook.path $(wildcard ~/Library/Energia/preferences.txt) | cut -d = -f 2) -endif - -ifeq ($(wildcard $(SKETCHBOOK_DIR)),) - $(error Error: sketchbook path not found) -endif - -USER_LIB_PATH = $(wildcard $(SKETCHBOOK_DIR)/?ibraries) - - -# Rules for making a c++ file from the main sketch (.pde) -# -PDEHEADER = \\\#include \"Energia.h\" - - -# Tool-chain names -# -CC = $(APP_TOOLS_PATH)/arm-none-eabi-gcc -CXX = $(APP_TOOLS_PATH)/arm-none-eabi-g++ -AR = $(APP_TOOLS_PATH)/arm-none-eabi-ar -OBJDUMP = $(APP_TOOLS_PATH)/arm-none-eabi-objdump -OBJCOPY = $(APP_TOOLS_PATH)/arm-none-eabi-objcopy -SIZE = $(APP_TOOLS_PATH)/arm-none-eabi-size -NM = $(APP_TOOLS_PATH)/arm-none-eabi-nm -GDB = $(APP_TOOLS_PATH)/arm-none-eabi-gdb - - -BOARD = $(call PARSE_BOARD,$(BOARD_TAG),board) -LDSCRIPT = $(call PARSE_BOARD,$(BOARD_TAG),ldscript) -VARIANT = $(call PARSE_BOARD,$(BOARD_TAG),build.variant) -VARIANT_PATH = $(APPLICATION_PATH)/hardware/lm4f/variants/$(VARIANT) - -MCU_FLAG_NAME = mcpu -EXTRA_LDFLAGS = -nostartfiles -T$(CORE_LIB_PATH)/$(LDSCRIPT) -Wl,--gc-sections -Wl,-Map=$(OBJDIR)/lm4f.map -EXTRA_LDFLAGS += -mthumb --entry=ResetISR -EXTRA_LDFLAGS += -mfloat-abi=hard -mfpu=fpv4-sp-d16 -fsingle-precision-constant -nostdlib - -EXTRA_CPPFLAGS = $(addprefix -D, $(PLATFORM_TAG)) -I$(VARIANT_PATH) -EXTRA_CPPFLAGS += -fno-exceptions -fno-rtti -mthumb -EXTRA_CPPFLAGS += -mfloat-abi=hard -mfpu=fpv4-sp-d16 -fsingle-precision-constant - -OBJCOPYFLAGS = -v -Obinary -TARGET_HEXBIN = $(TARGET_BIN) diff --git a/FastLED/FastLED/Makefiles/MapleIDE.mk b/FastLED/FastLED/Makefiles/MapleIDE.mk deleted file mode 100755 index a1d3c154..00000000 --- a/FastLED/FastLED/Makefiles/MapleIDE.mk +++ /dev/null @@ -1,108 +0,0 @@ -# -# embedXcode -# ---------------------------------- -# Embedded Computing on Xcode -# -# Copyright © Rei VILO, 2010-2014 -# http://embedxcode.weebly.com -# All rights reserved -# -# -# Last update: Apr 28, 2013 release 47 - -# MAPLE SUPPORT IS PUT ON HOLD -WARNING_MESSAGE = 'MAPLE SUPPORT IS PUT ON HOLD' - - -# Leaflabs Maple specifics -# ---------------------------------- -# -# The Maple reset script —which sends control signals over -# the USB-serial connection to restart and enter the bootloader— -# is written in Python and requires the PySerial library. -# -# Instructions available at http://leaflabs.com/docs/unix-toolchain.html#os-x -# Download PySerial library from http://pypi.python.org/pypi/pyserial -# -# -PLATFORM := MapleIDE -PLATFORM_TAG = MAPLE_IDE EMBEDXCODE=$(RELEASE_NOW) -APPLICATION_PATH := $(MAPLE_PATH) - -UPLOADER = dfu-util -DFU_UTIL_PATH = $(APPLICATION_PATH)/hardware/tools/arm/bin -DFU_UTIL = $(DFU_UTIL_PATH)/dfu-util -DFU_UTIL_OPTS = -a$(call PARSE_BOARD,$(BOARD_TAG),upload.altID) -d $(call PARSE_BOARD,$(BOARD_TAG),upload.usbID) -DFU_RESET = $(UTILITIES_PATH)/reset.py - -APP_TOOLS_PATH := $(APPLICATION_PATH)/hardware/tools/arm/bin -CORE_LIB_PATH := $(APPLICATION_PATH)/hardware/leaflabs/cores/maple -APP_LIB_PATH := $(APPLICATION_PATH)/libraries -BOARDS_TXT := $(APPLICATION_PATH)/hardware/leaflabs/boards.txt - -# Sketchbook/Libraries path -# wildcard required for ~ management -# ?ibraries required for libraries and Libraries -# -ifeq ($(USER_PATH)/Library/MapleIDE/preferences.txt,) - $(error Error: run Mpide once and define the sketchbook path) -endif - -ifeq ($(wildcard $(SKETCHBOOK_DIR)),) - SKETCHBOOK_DIR = $(shell grep sketchbook.path $(USER_PATH)/Library/MapleIDE/preferences.txt | cut -d = -f 2) -endif - -ifeq ($(wildcard $(SKETCHBOOK_DIR)),) - $(error Error: sketchbook path not found) -endif - -USER_LIB_PATH = $(wildcard $(SKETCHBOOK_DIR)/?ibraries) -CORE_AS_SRCS = $(wildcard $(CORE_LIB_PATH)/*.S) # */ - - -# Rules for making a c++ file from the main sketch (.pde) -# -PDEHEADER = \\\#include \"WProgram.h\" - - -# Tool-chain names -# -CC = $(APP_TOOLS_PATH)/arm-none-eabi-gcc -CXX = $(APP_TOOLS_PATH)/arm-none-eabi-g++ -AR = $(APP_TOOLS_PATH)/arm-none-eabi-ar -OBJDUMP = $(APP_TOOLS_PATH)/arm-none-eabi-objdump -OBJCOPY = $(APP_TOOLS_PATH)/arm-none-eabi-objcopy -SIZE = $(APP_TOOLS_PATH)/arm-none-eabi-size -NM = $(APP_TOOLS_PATH)/arm-none-eabi-nm - -lplm4f120h5qr.build.mcu=cortex-m4 - -BOARD = $(call PARSE_BOARD,$(BOARD_TAG),build.board) -LDSCRIPT = $(call PARSE_BOARD,$(BOARD_TAG),build.linker) -VARIANT = $(call PARSE_BOARD,$(BOARD_TAG),build.mcu) -#VARIANT_PATH = $(APPLICATION_PATH)/hardware/leaflabs/cores/maples/$(VARIANT) - - -MCU = $(call PARSE_BOARD,$(BOARD_TAG),build.family) -MCU_FLAG_NAME = mcpu - -EXTRA_LDFLAGS = -T$(CORE_LIB_PATH)/$(LDSCRIPT) -L$(APPLICATION_PATH)/hardware/leaflabs/cores/maple -EXTRA_LDFLAGS += -mthumb -Xlinker --gc-sections --print-gc-sections --march=armv7-m - -EXTRA_CPPFLAGS = -fno-rtti -fno-exceptions -mthumb -march=armv7-m -nostdlib -EXTRA_CPPFLAGS += -DBOARD_$(BOARD) -DMCU_$(call PARSE_BOARD,$(BOARD_TAG),build.mcu) -EXTRA_CPPFLAGS += -D$(call PARSE_BOARD,$(BOARD_TAG),build.vect) -EXTRA_CPPFLAGS += -D$(call PARSE_BOARD,$(BOARD_TAG),build.density) -EXTRA_CPPFLAGS += -DERROR_LED_PORT=$(call PARSE_BOARD,$(BOARD_TAG),build.error_led_port) -EXTRA_CPPFLAGS += -DERROR_LED_PIN=$(call PARSE_BOARD,$(BOARD_TAG),build.error_led_pin) -EXTRA_CPPFLAGS += $(addprefix -D, $(PLATFORM_TAG)) - -OBJCOPYFLAGS = -v -Obinary -TARGET_HEXBIN = $(TARGET_BIN) - -MAX_RAM_SIZE = $(call PARSE_BOARD,$(BOARD_TAG),upload.ram.maximum_size) - - - - - diff --git a/FastLED/FastLED/Makefiles/Microduino.mk b/FastLED/FastLED/Makefiles/Microduino.mk deleted file mode 100755 index e4238383..00000000 --- a/FastLED/FastLED/Makefiles/Microduino.mk +++ /dev/null @@ -1,93 +0,0 @@ -# -# embedXcode -# ---------------------------------- -# Embedded Computing on Xcode -# -# Copyright © Rei VILO, 2010-2014 -# http://embedxcode.weebly.com -# All rights reserved -# -# -# Last update: Jan 04, 2014 release 122 - - - -# Microduino 1.0.x AVR specifics -# ---------------------------------- -# -PLATFORM := Microduino -BUILD_CORE := avr -PLATFORM_TAG = ARDUINO=105 MICRODUINO EMBEDXCODE=$(RELEASE_NOW) -APPLICATION_PATH := $(MICRODUINO_PATH) - -APP_TOOLS_PATH := $(APPLICATION_PATH)/hardware/tools/avr/bin -CORE_LIB_PATH := $(APPLICATION_PATH)/hardware/Microduino/cores/arduino -APP_LIB_PATH := $(APPLICATION_PATH)/libraries -BOARDS_TXT := $(APPLICATION_PATH)/hardware/Microduino/boards.txt - - -# Sketchbook/Libraries path -# wildcard required for ~ management -# -ifeq ($(USER_PATH)/Library/Arduino/preferences.txt,) - $(error Error: run Microduino or Arduino once and define the sketchbook path) -endif - -ifeq ($(wildcard $(SKETCHBOOK_DIR)),) - SKETCHBOOK_DIR = $(shell grep sketchbook.path $(USER_PATH)/Library/Arduino/preferences.txt | cut -d = -f 2) -endif -ifeq ($(wildcard $(SKETCHBOOK_DIR)),) - $(error Error: sketchbook path not found) -endif -USER_LIB_PATH = $(wildcard $(SKETCHBOOK_DIR)/?ibraries) - -# Rules for making a c++ file from the main sketch (.pde) -# -PDEHEADER = \\\#include \"Arduino.h\" - -# Tool-chain names -# -CC = $(APP_TOOLS_PATH)/avr-gcc -CXX = $(APP_TOOLS_PATH)/avr-g++ -AR = $(APP_TOOLS_PATH)/avr-ar -OBJDUMP = $(APP_TOOLS_PATH)/avr-objdump -OBJCOPY = $(APP_TOOLS_PATH)/avr-objcopy -SIZE = $(APP_TOOLS_PATH)/avr-size -NM = $(APP_TOOLS_PATH)/avr-nm - -# Specific AVRDUDE location and options -# -AVRDUDE_COM_OPTS = -D -p$(MCU) -C$(AVRDUDE_CONF) - -BOARD = $(call PARSE_BOARD,$(BOARD_TAG),board) -#LDSCRIPT = $(call PARSE_BOARD,$(BOARD_TAG),ldscript) -VARIANT = $(call PARSE_BOARD,$(BOARD_TAG),build.variant) -VARIANT_PATH = $(APPLICATION_PATH)/hardware/Microduino/variants/$(VARIANT) - -MCU_FLAG_NAME = mmcu -EXTRA_LDFLAGS = -EXTRA_CPPFLAGS = -MMD -I$(VARIANT_PATH) $(addprefix -D, $(PLATFORM_TAG)) - -# Leonardo USB PID VID -# -USB_TOUCH := $(call PARSE_BOARD,$(BOARD_TAG),upload.protocol) -USB_VID := $(call PARSE_BOARD,$(BOARD_TAG),build.vid) -USB_PID := $(call PARSE_BOARD,$(BOARD_TAG),build.pid) - -ifneq ($(USB_PID),) - USB_FLAGS += -DUSB_PID=$(USB_PID) -else - USB_FLAGS += -DUSB_PID=null -endif - -ifneq ($(USB_VID),) - USB_FLAGS += -DUSB_VID=$(USB_VID) -else - USB_FLAGS += -DUSB_VID=null -endif - -# Serial 1200 reset -# -ifeq ($(USB_TOUCH),avr109) - USB_RESET = $(UTILITIES_PATH)/serial1200.py -endif diff --git a/FastLED/FastLED/Makefiles/Mpide.mk b/FastLED/FastLED/Makefiles/Mpide.mk deleted file mode 100755 index a8a7979c..00000000 --- a/FastLED/FastLED/Makefiles/Mpide.mk +++ /dev/null @@ -1,77 +0,0 @@ -# -# embedXcode -# ---------------------------------- -# Embedded Computing on Xcode -# -# Copyright © Rei VILO, 2010-2014 -# http://embedxcode.weebly.com -# All rights reserved -# -# -# Last update: Jan 20, 2014 release 125 - - - -# chipKIT MPIDE specifics -# ---------------------------------- -# Dirty implementation for MPIDE release 0023-macosx-20130715 -# OPT_SYSTEM_INTERNAL is defined in main.cpp but used in wiring.h -# -PLATFORM := MPIDE -PLATFORM_TAG = ARDUINO=23 MPIDE=23 MPIDEVER=0x01000202 EMBEDXCODE=$(RELEASE_NOW) - -APPLICATION_PATH := $(MPIDE_PATH) - -APP_TOOLS_PATH := $(APPLICATION_PATH)/hardware/pic32/compiler/pic32-tools/bin -CORE_LIB_PATH := $(APPLICATION_PATH)/hardware/pic32/cores/pic32 -APP_LIB_PATH := $(APPLICATION_PATH)/hardware/pic32/libraries -BOARDS_TXT := $(APPLICATION_PATH)/hardware/pic32/boards.txt - -# Sketchbook/Libraries path -# wildcard required for ~ management -# ?ibraries required for libraries and Libraries -# -ifeq ($(wildcard $(USER_PATH)/Library/Mpide/preferences.txt),) - $(error Error: run Mpide once and define the sketchbook path) -endif - -ifeq ($(wildcard $(SKETCHBOOK_DIR)),) - SKETCHBOOK_DIR = $(shell grep sketchbook.path $(USER_PATH)/Library/Mpide/preferences.txt | cut -d = -f 2) -endif -ifeq ($(wildcard $(SKETCHBOOK_DIR)),) - $(error Error: sketchbook path not found) -endif -USER_LIB_PATH = $(wildcard $(SKETCHBOOK_DIR)/?ibraries) - - -# Rules for making a c++ file from the main sketch (.pde) -# -PDEHEADER = \\\#include \"WProgram.h\" - - -# Add .S files required by MPIDE release 0023-macosx-20130715 -# -CORE_AS_SRCS = $(wildcard $(CORE_LIB_PATH)/*.S) # */ - - -# Tool-chain names -# -CC = $(APP_TOOLS_PATH)/pic32-gcc -CXX = $(APP_TOOLS_PATH)/pic32-g++ -AR = $(APP_TOOLS_PATH)/pic32-ar -OBJDUMP = $(APP_TOOLS_PATH)/pic32-objdump -OBJCOPY = $(APP_TOOLS_PATH)/pic32-objcopy -SIZE = $(APP_TOOLS_PATH)/pic32-size -NM = $(APP_TOOLS_PATH)/pic32-nm - - -BOARD = $(call PARSE_BOARD,$(BOARD_TAG),board) -LDSCRIPT = $(call PARSE_BOARD,$(BOARD_TAG),ldscript) -VARIANT = $(call PARSE_BOARD,$(BOARD_TAG),build.variant) -VARIANT_PATH = $(APPLICATION_PATH)/hardware/pic32/variants/$(VARIANT) - -MCU_FLAG_NAME = mprocessor -# chipKIT-application-COMMON.ld added by MPIDE release 0023-macosx-20130715 -EXTRA_LDFLAGS = -T$(CORE_LIB_PATH)/$(LDSCRIPT) -T$(CORE_LIB_PATH)/chipKIT-application-COMMON.ld -EXTRA_CPPFLAGS = -mdebugger -Wcast-align -O2 -mno-smart-io -G1024 $(addprefix -D, $(PLATFORM_TAG)) -D$(BOARD) -I$(VARIANT_PATH) - diff --git a/FastLED/FastLED/Makefiles/Step1.mk b/FastLED/FastLED/Makefiles/Step1.mk deleted file mode 100755 index 6b64106c..00000000 --- a/FastLED/FastLED/Makefiles/Step1.mk +++ /dev/null @@ -1,229 +0,0 @@ -# -# embedXcode -# ---------------------------------- -# Embedded Computing on Xcode -# -# Copyright © Rei VILO, 2010-2014 -# http://embedxcode.weebly.com -# All rights reserved -# -# -# Last update: Dec 06, 2013 release 119 - - - -# Sketch unicity test and extension -# ---------------------------------- -# -ifndef SKETCH_EXTENSION - ifeq ($(words $(wildcard *.pde) $(wildcard *.ino)), 0) - $(error No pde or ino sketch) - endif - - ifneq ($(words $(wildcard *.pde) $(wildcard *.ino)), 1) - $(error More than 1 pde or ino sketch) - endif - - ifneq ($(wildcard *.pde),) - SKETCH_EXTENSION := pde - else ifneq ($(wildcard *.ino),) - SKETCH_EXTENSION := ino - else - $(error Extension error) - endif -endif - - -ifneq ($(SKETCH_EXTENSION),cpp) - ifeq ($(words $(wildcard *.$(SKETCH_EXTENSION))), 0) - $(error No $(SKETCH_EXTENSION) sketch) - endif - - ifneq ($(words $(wildcard *.$(SKETCH_EXTENSION))), 1) - $(error More than one $(SKETCH_EXTENSION) sketch) - endif -endif - - -# Board selection -# ---------------------------------- -# Board specifics defined in .xconfig file -# BOARD_TAG and AVRDUDE_PORT -# -ifneq ($(MAKECMDGOALS),boards) - ifneq ($(MAKECMDGOALS),clean) - ifndef BOARD_TAG - $(error BOARD_TAG not defined) - endif - endif -endif - -ifndef BOARD_PORT - BOARD_PORT = /dev/tty.usb* -endif - - -# Arduino.app Mpide.app Wiring.app Energia.app MapleIDE.app paths -# -ARDUINO_APP = /Applications/Arduino.app -MPIDE_APP = /Applications/Mpide.app -WIRING_APP = /Applications/Wiring.app -ENERGIA_APP = /Applications/Energia.app -MAPLE_APP = /Applications/MapleIDE.app - -# Teensyduino.app path -# -TEENSY_0 = /Applications/Teensyduino.app -ifneq ($(wildcard $(TEENSY_0)),) - TEENSY_APP = $(TEENSY_0) -else - TEENSY_APP = /Applications/Arduino.app -endif - -# DigisparkArduino.app path -# -DIGISPARK_0 = /Applications/DigisparkArduino.app -ifneq ($(wildcard $(DIGISPARK_0)),) - DIGISPARK_APP = $(DIGISPARK_0) -else - DIGISPARK_APP = /Applications/Arduino.app -endif - -# Microduino.app path -# -MICRODUINO_0 = /Applications/Microduino.app -ifneq ($(wildcard $(MICRODUINO_0)),) - MICRODUINO_APP = $(MICRODUINO_0) -else - MICRODUINO_APP = /Applications/Arduino.app -endif - - -ifeq ($(wildcard $(ARDUINO_APP)),) - ifeq ($(wildcard $(MPIDE_APP)),) - ifeq ($(wildcard $(WIRING_APP)),) - ifeq ($(wildcard $(ENERGIA_APP)),) - ifeq ($(wildcard $(MAPLE_APP)),) - ifeq ($(wildcard $(TEENSY_APP)),) - ifeq ($(wildcard $(DIGISPARK_APP)),) - ifeq ($(wildcard $(MICRODUINO_APP)),) - $(error Error: no application found) - endif - endif - endif - endif - endif - endif - endif -endif - -ARDUINO_PATH = $(ARDUINO_APP)/Contents/Resources/Java -MPIDE_PATH = $(MPIDE_APP)/Contents/Resources/Java -WIRING_PATH = $(WIRING_APP)/Contents/Resources/Java -ENERGIA_PATH = $(ENERGIA_APP)/Contents/Resources/Java -MAPLE_PATH = $(MAPLE_APP)/Contents/Resources/Java -TEENSY_PATH = $(TEENSY_APP)/Contents/Resources/Java -DIGISPARK_PATH = $(DIGISPARK_APP)/Contents/Resources/Java -MICRODUINO_PATH = $(MICRODUINO_APP)/Contents/Resources/Java - -# Miscellaneous -# ---------------------------------- -# Variables -# -TARGET := embeddedcomputing -USER_PATH := $(wildcard ~/) -TEMPLATE := ePsiEJEtRXnDNaFGpywBX9vzeNQP4vUb - -# main.cpp selection -# = 1 takes local main.cpp -# -NO_CORE_MAIN_FUNCTION := 1 - -# Builds directory -# -OBJDIR = Builds - -# Function PARSE_BOARD data retrieval from boards.txt -# result = $(call PARSE_BOARD 'boardname','parameter') -# -PARSE_BOARD = $(shell if [ -f $(BOARDS_TXT) ]; then grep ^$(1).$(2)= $(BOARDS_TXT) | cut -d = -f 2; fi; ) - -# Function PARSE_FILE data retrieval from specified file -# result = $(call PARSE_FILE 'boardname','parameter','filename') -# -PARSE_FILE = $(shell if [ -f $(3) ]; then grep ^$(1).$(2) $(3) | cut -d = -f 2; fi; ) - - -# Clean if new BOARD_TAG -# ---------------------------------- -# -NEW_TAG := $(strip $(OBJDIR)/$(BOARD_TAG)-TAG) # -OLD_TAG := $(strip $(wildcard $(OBJDIR)/*-TAG)) # */ - -ifneq ($(OLD_TAG),$(NEW_TAG)) - CHANGE_FLAG := 1 -else - CHANGE_FLAG := 0 -endif - - -# Identification and switch -# ---------------------------------- -# Look if BOARD_TAG is listed as a Arduino/Arduino board -# Look if BOARD_TAG is listed as a Arduino/Arduino/avr board *1.5 -# Look if BOARD_TAG is listed as a Arduino/Arduino/sam board *1.5 -# Look if BOARD_TAG is listed as a Mpide/PIC32 board -# Look if BOARD_TAG is listed as a Wiring/Wiring board -# Look if BOARD_TAG is listed as a Energia/MPS430 board -# Look if BOARD_TAG is listed as a MapleIDE/LeafLabs board -# Look if BOARD_TAG is listed as a Teensy/Teensy board -# Look if BOARD_TAG is listed as a Microduino/Microduino board -# Look if BOARD_TAG is listed as a Digispark/Digispark board -# Order matters! -# - -ifneq ($(MAKECMDGOALS),boards) - ifneq ($(MAKECMDGOALS),clean) - ifneq ($(call PARSE_FILE,$(BOARD_TAG),name,$(ARDUINO_PATH)/hardware/arduino/boards.txt),) - include $(MAKEFILE_PATH)/Arduino.mk - else ifneq ($(call PARSE_FILE,$(BOARD_TAG),name,$(ARDUINO_PATH)/hardware/arduino/avr/boards.txt),) - include $(MAKEFILE_PATH)/Arduino15avr.mk - else ifneq ($(call PARSE_FILE,$(BOARD_TAG1),name,$(ARDUINO_PATH)/hardware/arduino/avr/boards.txt),) - include $(MAKEFILE_PATH)/Arduino15avr.mk - else ifneq ($(call PARSE_FILE,$(BOARD_TAG),name,$(ARDUINO_PATH)/hardware/arduino/sam/boards.txt),) - include $(MAKEFILE_PATH)/Arduino15sam.mk - else ifneq ($(call PARSE_FILE,$(BOARD_TAG),name,$(ARDUINO_PATH)/hardware/arduino/boards.txt),) - include $(MAKEFILE_PATH)/Arduino.mk - else ifneq ($(call PARSE_FILE,$(BOARD_TAG),name,$(MPIDE_PATH)/hardware/pic32/boards.txt),) - include $(MAKEFILE_PATH)/Mpide.mk - else ifneq ($(call PARSE_FILE,$(BOARD_TAG),name,$(WIRING_PATH)/hardware/Wiring/boards.txt),) - include $(MAKEFILE_PATH)/Wiring.mk - else ifneq ($(call PARSE_FILE,$(BOARD_TAG),name,$(ENERGIA_PATH)/hardware/msp430/boards.txt),) - include $(MAKEFILE_PATH)/Energia430.mk - else ifneq ($(call PARSE_FILE,$(BOARD_TAG),name,$(ENERGIA_PATH)/hardware/lm4f/boards.txt),) - include $(MAKEFILE_PATH)/EnergiaLM4F.mk - else ifneq ($(call PARSE_FILE,$(BOARD_TAG),name,$(MAPLE_PATH)/hardware/leaflabs/boards.txt),) - include $(MAKEFILE_PATH)/MapleIDE.mk - else ifneq ($(call PARSE_FILE,$(BOARD_TAG),name,$(TEENSY_PATH)/hardware/teensy/boards.txt),) - include $(MAKEFILE_PATH)/Teensy.mk - else ifneq ($(call PARSE_FILE,$(BOARD_TAG),name,$(MICRODUINO_PATH)/hardware/Microduino/boards.txt),) - include $(MAKEFILE_PATH)/Microduino.mk - else ifneq ($(call PARSE_FILE,$(BOARD_TAG),name,$(DIGISPARK_PATH)/hardware/digispark/boards.txt),) - include $(MAKEFILE_PATH)/Digispark.mk - else - $(error $(BOARD_TAG) board is unknown) - endif - endif -endif - - -# List of sub-paths to be excluded -# -EXCLUDE_NAMES = Example example Examples examples Archive archive Archives archives Documentation documentation Reference reference -EXCLUDE_NAMES += ArduinoTestSuite -EXCLUDE_NAMES += $(EXCLUDE_LIBS) -EXCLUDE_LIST = $(addprefix %,$(EXCLUDE_NAMES)) - -# Step 2 -# -include $(MAKEFILE_PATH)/Step2.mk diff --git a/FastLED/FastLED/Makefiles/Step2.mk b/FastLED/FastLED/Makefiles/Step2.mk deleted file mode 100755 index 63bac5ba..00000000 --- a/FastLED/FastLED/Makefiles/Step2.mk +++ /dev/null @@ -1,1021 +0,0 @@ -# -# embedXcode -# ---------------------------------- -# Embedded Computing on Xcode -# -# Copyright © Rei VILO, 2010-2014 -# http://embedxcode.weebly.com -# All rights reserved -# -# -# Last update: Mar 14, 2014 release 141 - - - -# Serial port check and selection -# ---------------------------------- -# -include $(MAKEFILE_PATH)/Avrdude.mk - -ifeq ($(AVRDUDE_NO_SERIAL_PORT),1) -# -else ifeq ($(UPLOADER),teensy_flash) -# teensy uploader in charge -else ifneq ($(MAKECMDGOALS),boards) - ifneq ($(MAKECMDGOALS),build) - ifneq ($(MAKECMDGOALS),make) - ifneq ($(MAKECMDGOALS),document) - ifneq ($(MAKECMDGOALS),clean) - ifneq ($(MAKECMDGOALS),distribute) - ifneq ($(MAKECMDGOALS),info) - ifneq ($(MAKECMDGOALS),depends) - ifeq ($(AVRDUDE_PORT),) - $(error Serial port not available) - endif - endif - endif - endif - endif - endif - endif - endif -endif - -ifndef UPLOADER - UPLOADER = avrdude -endif - -ifndef BOARD_NAME - BOARD_NAME = $(call PARSE_BOARD,$(BOARD_TAG),name) -endif - -# Functions -# ---------------------------------- -# - -# Function TRACE action target source to ~/Library/Logs/embedXcode.log -# result = $(shell echo 'action',$(BOARD_TAG),'target','source' >> ~/Library/Logs/embedXcode.log) -# -TRACE = $(shell echo $(1)': '$(suffix $(2))' < '$(suffix $(3))' '$(BOARD_TAG)' '$(dir $(2))' '$(notdir $(3)) >> ~/Library/Logs/embedXcode.log) - -# Function SHOW action target source -# result = $(shell echo 'action',$(BOARD_TAG),'target','source') -# -SHOW = @echo $(1)': '$(suffix $(2))' < '$(suffix $(3))' '$(BOARD_TAG)' '$(dir $(2))' '$(notdir $(3)) -#SHOW = - - -# CORE libraries -# ---------------------------------- -# -ifndef CORE_LIB_PATH - CORE_LIB_PATH = $(APPLICATION_PATH)/hardware/arduino/cores/arduino -endif - -s5 = $(subst .h,,$(subst $(CORE_LIB_PATH)/,,$(wildcard $(CORE_LIB_PATH)/*.h))) # */ -CORE_LIBS_LIST = $(subst $(USER_LIB_PATH)/,,$(filter-out $(EXCLUDE_LIST),$(s5))) - - -# List of sources -# ---------------------------------- -# - -# CORE sources -# -ifdef CORE_LIB_PATH - CORE_C_SRCS = $(wildcard $(CORE_LIB_PATH)/*.c) # */ - - ifneq ($(strip $(NO_CORE_MAIN_FUNCTION)),) - CORE_CPP_SRCS = $(filter-out %main.cpp, $(wildcard $(CORE_LIB_PATH)/*.cpp $(CORE_LIB_PATH)/*/*.cpp)) # */ - else - CORE_CPP_SRCS = $(wildcard $(CORE_LIB_PATH)/*.cpp $(CORE_LIB_PATH)/*/*.cpp) # */ - endif - - CORE_OBJ_FILES = $(CORE_C_SRCS:.c=.o) $(CORE_CPP_SRCS:.cpp=.o) $(CORE_AS_SRCS:.S=.o) - CORE_OBJS = $(patsubst $(CORE_LIB_PATH)/%,$(OBJDIR)/%,$(CORE_OBJ_FILES)) -endif - - -# APPlication Arduino/chipKIT/Digispark/Energia/Maple/Microduino/Teensy/Wiring sources -# -ifndef APP_LIB_PATH - APP_LIB_PATH = $(APPLICATION_PATH)/libraries -endif - -ifeq ($(APP_LIBS_LIST),) - s1 = $(realpath $(sort $(dir $(wildcard $(APP_LIB_PATH)/*/*.h $(APP_LIB_PATH)/*/*/*.h)))) # */ - APP_LIBS_LIST = $(subst $(APP_LIB_PATH)/,,$(filter-out $(EXCLUDE_LIST),$(s1))) -endif - -ifndef APP_LIBS -ifneq ($(APP_LIBS_LIST),0) - s4 = $(patsubst %,$(APP_LIB_PATH)/%,$(APP_LIBS_LIST)) - APP_LIBS = $(realpath $(sort $(dir $(foreach dir,$(s4),$(wildcard $(dir)/*.h $(dir)/*/*.h $(dir)/*/*/*.h))))) -endif -endif - -ifndef APP_LIB_OBJS - FLAG = 1 - APP_LIB_C_SRC = $(wildcard $(patsubst %,%/*.c,$(APP_LIBS))) # */ - APP_LIB_CPP_SRC = $(wildcard $(patsubst %,%/*.cpp,$(APP_LIBS))) # */ - APP_LIB_OBJS = $(patsubst $(APP_LIB_PATH)/%.c,$(OBJDIR)/libs/%.o,$(APP_LIB_C_SRC)) - APP_LIB_OBJS += $(patsubst $(APP_LIB_PATH)/%.cpp,$(OBJDIR)/libs/%.o,$(APP_LIB_CPP_SRC)) -else - FLAG = 0 -endif - -# USER sources -# wildcard required for ~ management -# ?ibraries required for libraries and Libraries -# -ifndef USER_LIB_PATH - USER_LIB_PATH = $(wildcard $(SKETCHBOOK_DIR)/?ibraries) -endif - -ifndef USER_LIBS_LIST - s2 = $(realpath $(sort $(dir $(wildcard $(USER_LIB_PATH)/*/*.h)))) # */ - USER_LIBS_LIST = $(subst $(USER_LIB_PATH)/,,$(filter-out $(EXCLUDE_LIST),$(s2))) -endif - -ifneq ($(USER_LIBS_LIST),0) - s3 = $(patsubst %,$(USER_LIB_PATH)/%,$(USER_LIBS_LIST)) - USER_LIBS = $(realpath $(sort $(dir $(foreach dir,$(s3),$(wildcard $(dir)/*.h $(dir)/*/*.h $(dir)/*/*/*.h))))) - - USER_LIB_CPP_SRC = $(wildcard $(patsubst %,%/*.cpp,$(USER_LIBS))) # */ - USER_LIB_C_SRC = $(wildcard $(patsubst %,%/*.c,$(USER_LIBS))) # */ - - USER_OBJS = $(patsubst $(USER_LIB_PATH)/%.cpp,$(OBJDIR)/libs/%.o,$(USER_LIB_CPP_SRC)) - USER_OBJS += $(patsubst $(USER_LIB_PATH)/%.c,$(OBJDIR)/libs/%.o,$(USER_LIB_C_SRC)) -endif - -# LOCAL sources -# -LOCAL_C_SRCS = $(wildcard *.c) - -ifneq ($(strip $(NO_CORE_MAIN_FUNCTION)),) - LOCAL_CPP_SRCS = $(wildcard *.cpp) -else - LOCAL_CPP_SRCS = $(filter-out %main.cpp, $(wildcard *.cpp)) -endif - -LOCAL_CC_SRCS = $(wildcard *.cc) - -# Use of implicit rule for LOCAL_PDE_SRCS -# -#LOCAL_PDE_SRCS = $(wildcard *.$(SKETCH_EXTENSION)) -LOCAL_AS_SRCS = $(wildcard *.S) -LOCAL_OBJ_FILES = $(LOCAL_C_SRCS:.c=.o) $(LOCAL_CPP_SRCS:.cpp=.o) \ - $(LOCAL_PDE_SRCS:.$(SKETCH_EXTENSION)=.o) \ - $(LOCAL_CC_SRCS:.cc=.o) $(LOCAL_AS_SRCS:.S=.o) -#LOCAL_OBJS = $(patsubst %,$(OBJDIR)/%,$(LOCAL_OBJ_FILES)) -LOCAL_OBJS = $(patsubst %,$(OBJDIR)/%,$(filter-out $(PROJECT_NAME_AS_IDENTIFIER).o,$(LOCAL_OBJ_FILES))) - -# All the objects -# ??? Does order matter? -# -REMOTE_OBJS = $(CORE_OBJS) $(BUILD_CORE_OBJS) $(APP_LIB_OBJS) $(BUILD_APP_LIB_OBJS) $(VARIANT_OBJS) $(USER_OBJS) -OBJS = $(REMOTE_OBJS) $(LOCAL_OBJS) - -# Dependency files -# -#DEPS = $(LOCAL_OBJS:.o=.d) -DEPS = $(OBJS:.o=.d) - - -# Processor model and frequency -# ---------------------------------- -# -ifndef MCU - MCU = $(call PARSE_BOARD,$(BOARD_TAG),build.mcu) -endif - -ifndef F_CPU - F_CPU = $(call PARSE_BOARD,$(BOARD_TAG),build.f_cpu) -endif - - -# Rules -# ---------------------------------- -# - -# Main targets -# -TARGET_A = $(OBJDIR)/$(TARGET).a -TARGET_HEX = $(OBJDIR)/$(TARGET).hex -TARGET_ELF = $(OBJDIR)/$(TARGET).elf -TARGET_BIN = $(OBJDIR)/$(TARGET).bin -TARGETS = $(OBJDIR)/$(TARGET).* - -ifndef TARGET_HEXBIN - TARGET_HEXBIN = $(TARGET_HEX) -endif - -ifndef TARGET_EEP - TARGET_EEP = -endif - -# List of dependencies -# -DEP_FILE = $(OBJDIR)/depends.mk - -# Executables -# -REMOVE = rm -r -MV = mv -f -CAT = cat -ECHO = echo - -# General arguments -# -SYS_INCLUDES = $(patsubst %,-I%,$(APP_LIBS)) -SYS_INCLUDES += $(patsubst %,-I%,$(BUILD_APP_LIBS)) -SYS_INCLUDES += $(patsubst %,-I%,$(USER_LIBS)) - -SYS_OBJS = $(wildcard $(patsubst %,%/*.o,$(APP_LIBS))) # */ -SYS_OBJS += $(wildcard $(patsubst %,%/*.o,$(BUILD_APP_LIBS))) # */ -SYS_OBJS += $(wildcard $(patsubst %,%/*.o,$(USER_LIBS))) # */ - -CPPFLAGS = -$(MCU_FLAG_NAME)=$(MCU) -DF_CPU=$(F_CPU) -I$(CORE_LIB_PATH) -CPPFLAGS += $(SYS_INCLUDES) -g -Os -w -Wall -ffunction-sections -fdata-sections -CPPFLAGS += $(EXTRA_CPPFLAGS) - -ifdef USB_FLAGS - CPPFLAGS += $(USB_FLAGS) -endif - -ifdef USE_GNU99 - CFLAGS = -std=gnu99 -endif - -SCOPE_FLAG := -$(PLATFORM) - -# CXX = flags for C++ only -# CPP = flags for both C and C++ -# -ifndef EXTRA_CXXFLAGS - CXXFLAGS = -fno-exceptions -else - CXXFLAGS = $(EXTRA_CXXFLAGS) -endif - -ASFLAGS = -$(MCU_FLAG_NAME)=$(MCU) -x assembler-with-cpp -ifeq ($(BUILD_CORE),sam) - LDFLAGS = -$(MCU_FLAG_NAME)=$(MCU) -lm -Wl,--gc-sections,-u,main -Os $(EXTRA_LDFLAGS) -else - LDFLAGS = -$(MCU_FLAG_NAME)=$(MCU) -Wl,--gc-sections -Os $(EXTRA_LDFLAGS) -endif - -ifndef OBJCOPYFLAGS - OBJCOPYFLAGS = -Oihex -R .eeprom -endif - -# Implicit rules for building everything (needed to get everything in -# the right directory) -# -# Rather than mess around with VPATH there are quasi-duplicate rules -# here for building e.g. a system C++ file and a local C++ -# file. Besides making things simpler now, this would also make it -# easy to change the build options in future - - -# 1-6 Build -# ---------------------------------- -# - -# 2- APPlication Arduino/chipKIT/Digispark/Energia/Maple/Microduino/Teensy/Wiring library sources -# -$(OBJDIR)/libs/%.o: $(APP_LIB_PATH)/%.c - $(call SHOW,"2.1-APP",$@,$<) - $(call TRACE,"2-APP",$@,$<) - @mkdir -p $(dir $@) - $(CC) -c $(CPPFLAGS) $(CFLAGS) $< -o $@ - -$(OBJDIR)/libs/%.o: $(APP_LIB_PATH)/%.cpp - $(call SHOW,"2.2-APP",$@,$<) - $(call TRACE,"2-APP",$@,$<) - @mkdir -p $(dir $@) - $(CXX) -c $(CPPFLAGS) $(CXXFLAGS) $(CFLAGS) $< -o $@ - -$(OBJDIR)/libs/%.o: $(BUILD_APP_LIB_PATH)/%.cpp - $(call SHOW,"2.3-APP",$@,$<) - $(call TRACE,"2-APP",$@,$<) - @mkdir -p $(dir $@) - $(CXX) -c $(CPPFLAGS) $(CFLAGS) $< -o $@ - -$(OBJDIR)/libs/%.o: $(BUILD_APP_LIB_PATH)/%.c - $(call SHOW,"2.4-APP",$@,$<) - $(call TRACE,"2-APP",$@,$<) - @mkdir -p $(dir $@) - $(CC) -c $(CPPFLAGS) $(CFLAGS) $< -o $@ - -$(OBJDIR)/libs/%.d: $(APP_LIB_PATH)/%.cpp - $(call SHOW,"2.5-APP",$@,$<) - $(call TRACE,"2-APP",$@,$<) - @mkdir -p $(dir $@) - $(CXX) -MM $(CPPFLAGS) $(CXXFLAGS) $(CFLAGS) $< -MF $@ -MT $(@:.d=.o) - -$(OBJDIR)/libs/%.d: $(APP_LIB_PATH)/%.c - $(call SHOW,"2.6-APP",$@,$<) - $(call TRACE,"2-APP",$@,$<) - @mkdir -p $(dir $@) - $(CC) -MM $(CPPFLAGS) $(CFLAGS) $< -MF $@ -MT $(@:.d=.o) - -$(OBJDIR)/libs/%.d: $(BUILD_APP_LIB_PATH)/%.cpp - $(call SHOW,"2.7-APP",$@,$<) - $(call TRACE,"2-APP",$@,$<) - @mkdir -p $(dir $@) - $(CXX) -MM $(CPPFLAGS) $(CXXFLAGS) $(CFLAGS) $< -MF $@ -MT $(@:.d=.o) - -$(OBJDIR)/libs/%.d: $(BUILD_APP_LIB_PATH)/%.c - $(call SHOW,"2.8-APP",$@,$<) - $(call TRACE,"2-APP",$@,$<) - @mkdir -p $(dir $@) - $(CC) -MM $(CPPFLAGS) $(CFLAGS) $< -MF $@ -MT $(@:.d=.o) - - -# 3- USER library sources -# -$(OBJDIR)/libs/%.o: $(USER_LIB_PATH)/%.cpp - $(call SHOW,"3.1-USER",$@,$<) - $(call TRACE,"3-USER",$@,$<) - @mkdir -p $(dir $@) - $(CXX) -c $(CPPFLAGS) $(CXXFLAGS) $(CFLAGS) $< -o $@ - -$(OBJDIR)/libs/%.o: $(USER_LIB_PATH)/%.c - $(call SHOW,"3.2-USER",$@,$<) - $(call TRACE,"3-USER",$@,$<) - @mkdir -p $(dir $@) - $(CC) -c $(CPPFLAGS) $(CFLAGS) $< -o $@ - -$(OBJDIR)/libs/%.d: $(USER_LIB_PATH)/%.cpp - $(call SHOW,"3.1-USER",$@,$<) - $(call TRACE,"3-USER",$@,$<) - @mkdir -p $(dir $@) - $(CXX) -MM $(CPPFLAGS) $(CXXFLAGS) $(CFLAGS) $< -MF $@ -MT $(@:.d=.o) - -$(OBJDIR)/libs/%.d: $(USER_LIB_PATH)/%.c - $(call SHOW,"3.2-USER",$@,$<) - $(call TRACE,"3-USER",$@,$<) - @mkdir -p $(dir $@) - $(CC) -MM $(CPPFLAGS) $(CFLAGS) $< -MF $@ -MT $(@:.d=.o) - - -# 4- LOCAL sources -# .o rules are for objects, .d for dependency tracking -# -$(OBJDIR)/%.o: %.c - $(call SHOW,"4.1-LOCAL",$@,$<) - $(call TRACE,"4-LOCAL",$@,$<) - $(CC) -c $(CPPFLAGS) $(CFLAGS) $< -o $@ - -$(OBJDIR)/%.o: %.cc - $(call SHOW,"4.2-LOCAL",$@,$<) - $(call TRACE,"4-LOCAL",$@,$<) - $(CXX) -c $(CPPFLAGS) $(CXXFLAGS) $< -o $@ - -$(OBJDIR)/%.o: %.cpp - $(call SHOW,"4.3-LOCAL",$@,$<) - $(call TRACE,"4-LOCAL",$@,$<) - $(CXX) -c $(CPPFLAGS) $(CXXFLAGS) $< -o $@ - -$(OBJDIR)/%.o: %.S - $(call SHOW,"4.4-LOCAL",$@,$<) - $(call TRACE,"4-LOCAL",$@,$<) - $(CC) -c $(CPPFLAGS) $(ASFLAGS) $< -o $@ - -$(OBJDIR)/%.o: %.s - $(call SHOW,"4.5-LOCAL",$@,$<) - $(call TRACE,"4-LOCAL",$@,$<) - $(CC) -c $(CPPFLAGS) $(ASFLAGS) $< -o $@ - -$(OBJDIR)/%.d: %.c - $(call SHOW,"4.6-LOCAL",$@,$<) - $(call TRACE,"4-LOCAL",$@,$<) - $(CC) -MM $(CPPFLAGS) $(CFLAGS) $< -MF $@ -MT $(@:.d=.o) - -$(OBJDIR)/%.d: %.cpp - $(call SHOW,"4.7-LOCAL",$@,$<) - $(call TRACE,"4-LOCAL",$@,$<) - $(CXX) -MM $(CPPFLAGS) $(CXXFLAGS) $< -MF $@ -MT $(@:.d=.o) - -$(OBJDIR)/%.d: %.S - $(call SHOW,"4.8-LOCAL",$@,$<) - $(call TRACE,"4-LOCAL",$@,$<) - $(CC) -MM $(CPPFLAGS) $(ASFLAGS) $< -MF $@ -MT $(@:.d=.o) - -$(OBJDIR)/%.d: %.s - $(call SHOW,"4.9-LOCAL",$@,$<) - $(call TRACE,"4-LOCAL",$@,$<) - $(CC) -MM $(CPPFLAGS) $(ASFLAGS) $< -MF $@ -MT $(@:.d=.o) - - -# 5- SKETCH pde/ino -> cpp -> o file -# -$(OBJDIR)/%.cpp: %.$(SKETCH_EXTENSION) - $(call SHOW,"5.1-SKETCH",$@,$<) - $(call TRACE,"5-SKETCH",$@,$<) - @$(ECHO) $(PDEHEADER) > $@ - @$(CAT) $< >> $@ -# @$(ECHO) $(PDEHEADER) > $(OBJDIR)/text.txt -# @$(CAT) $< >> $(OBJDIR)/text.txt - -$(OBJDIR)/%.o: $(OBJDIR)/%.cpp - $(call SHOW,"5.2-SKETCH",$@,$<) - $(call TRACE,"5-SKETCH",$@,$<) - $(CXX) -c $(CPPFLAGS) $(CXXFLAGS) -I. $< -o $@ - -$(OBJDIR)/%.d: $(OBJDIR)/%.cpp - $(call SHOW,"5.3-SKETCH",$@,$<) - $(call TRACE,"5-SKETCH",$@,$<) - $(CXX) -MM $(CPPFLAGS) $(CXXFLAGS) -I. $< -MF $@ -MT $(@:.d=.o) - - -# 6- VARIANT files -# -$(OBJDIR)/libs/%.o: $(VARIANT_PATH)/%.cpp - $(call SHOW,"6.1-VARIANT",$@,$<) - $(call TRACE,"6-VARIANT",$@,$<) - @mkdir -p $(dir $@) - $(CXX) -c $(CPPFLAGS) $(CXXFLAGS) $(CFLAGS) $< -o $@ - -$(OBJDIR)/%.o: $(VARIANT_PATH)/%.cpp - $(call SHOW,"6.2-VARIANT",$@,$<) - $(call TRACE,"6-VARIANT",$@,$<) - @mkdir -p $(dir $@) - $(CXX) -c $(CPPFLAGS) $(CXXFLAGS) $(CFLAGS) $< -o $@ - -$(OBJDIR)/libs/%.d: $(VARIANT_PATH)/%.cpp - $(call SHOW,"6.3-VARIANT",$@,$<) - $(call TRACE,"6-VARIANT",$@,$<) - @mkdir -p $(dir $@) - $(CXX) -MM $(CPPFLAGS) $(CXXFLAGS) $(CFLAGS) $< -MF $@ -MT $(@:.d=.o) - -$(OBJDIR)/%.d: $(VARIANT_PATH)/%.cpp - $(call SHOW,"6.4-VARIANT",$@,$<) - $(call TRACE,"6-VARIANT",$@,$<) - @mkdir -p $(dir $@) - $(CXX) -c $(CPPFLAGS) $(CXXFLAGS) $(CFLAGS) $< -MF $@ -MT $(@:.d=.o) - - -# 1- CORE files -# -$(OBJDIR)/%.o: $(CORE_LIB_PATH)/%.c - $(call SHOW,"1.1-CORE",$@,$<) - $(call TRACE,"1-CORE",$@,$<) - $(CC) -c $(CPPFLAGS) $(CFLAGS) $< -o $@ - -$(OBJDIR)/%.o: $(CORE_LIB_PATH)/%.S - $(call SHOW,"1.2-CORE",$@,$<) - $(call TRACE,"1-CORE",$@,$<) - $(CC) -c $(CPPFLAGS) $(CFLAGS) $< -o $@ - -$(OBJDIR)/%.o: $(CORE_LIB_PATH)/%.cpp - $(call SHOW,"1.3-CORE",$@,$<) - $(call TRACE,"1-CORE",$@,$<) - @mkdir -p $(dir $@) - $(CXX) -c $(CPPFLAGS) $(CXXFLAGS) $< -o $@ - -$(OBJDIR)/%.o: $(BUILD_CORE_LIB_PATH)/%.c - $(call SHOW,"1.4-CORE",$@,$<) - $(call TRACE,"1-CORE",$@,$<) - $(CC) -c $(CPPFLAGS) $(CFLAGS) $< -o $@ - -$(OBJDIR)/%.o: $(BUILD_CORE_LIB_PATH)/%.cpp - $(call SHOW,"1.5-CORE",$@,$<) - $(call TRACE,"1-CORE",$@,$<) - $(CXX) -c $(CPPFLAGS) $(CXXFLAGS) $< -o $@ - -$(OBJDIR)/%.d: $(CORE_LIB_PATH)/%.c - $(call SHOW,"1.6-CORE",$@,$<) - $(call TRACE,"1-CORE",$@,$<) - $(CC) -MM $(CPPFLAGS) $(CFLAGS) $< -MF $@ -MT $(@:.d=.o) - -$(OBJDIR)/%.d: $(CORE_LIB_PATH)/%.cpp - $(call SHOW,"1.7-CORE",$@,$<) - $(call TRACE,"1-CORE",$@,$<) - $(CXX) -MM $(CPPFLAGS) $(CXXFLAGS) $(CFLAGS) $< -MF $@ -MT $(@:.d=.o) - -$(OBJDIR)/%.d: $(BUILD_CORE_LIB_PATH)/%.c - $(call SHOW,"1.8-CORE",$@,$<) - $(call TRACE,"1-CORE",$@,$<) - $(CC) -MM $(CPPFLAGS) $(CFLAGS) $< -MF $@ -MT $(@:.d=.o) - -$(OBJDIR)/%.d: $(BUILD_CORE_LIB_PATH)/%.cpp - $(call SHOW,"1.9-CORE",$@,$<) - $(call TRACE,"1-CORE",$@,$<) - $(CXX) -MM $(CPPFLAGS) $(CXXFLAGS) $< -MF $@ -MT $(@:.d=.o) - - -# 7- Link -# ---------------------------------- -# -$(TARGET_ELF): $(OBJS) - @echo "---- Link ---- " - -ifneq ($(BOARD_TAG),teensy3) -ifneq ($(BOARD_TAG),teensy31) - $(call SHOW,"7.1-ARCHIVE",$@,.) - $(call TRACE,"7-ARCHIVE",$@,.) - $(AR) rcs $(TARGET_A) $(REMOTE_OBJS) -endif -endif - $(call SHOW,"7.2-LINK",$@,.) - $(call TRACE,"7-LINK",$@,.) - -ifeq ($(BUILD_CORE),sam) -# Builds/syscalls_sam3.c.o needs to be mentioned again - $(CXX) $(LDFLAGS) -o $@ -L$(OBJDIR) -Wl,--start-group Builds/syscalls_sam3.o $(SYSTEM_OBJS) $(LOCAL_OBJS) $(TARGET_A) -Wl,--end-group -else ifeq ($(VARIANT),stellarpad) -# -lc -lm -lgcc need to be at the end of the sentence -# $(CXX) $(LDFLAGS) -o $@ $(SYSTEM_OBJS) $(LOCAL_OBJS) $(TARGET_A) -L$(OBJDIR) -lc -lm -lgcc -# arm-none-eabi-ar doesn't seem to work with release 4.7.1 -# $(CXX) $(LDFLAGS) -o $@ $(LOCAL_OBJS) $(REMOTE_OBJS) -L$(OBJDIR) -lm -lc -lgcc - $(CXX) $(LDFLAGS) -o $@ $(SYSTEM_OBJS) $(LOCAL_OBJS) $(TARGET_A) -L$(OBJDIR) -lm -lc -lgcc - -else ifeq ($(PLATFORM),MapleIDE) - $(CXX) $(LDFLAGS) -o $@ $(LOCAL_OBJS) $(TARGET_A) -L$(OBJDIR) - -else ifeq ($(PLATFORM),MPIDE) -# compatible with MPIDE release 0023-macosx-20130715 - $(CXX) $(LDFLAGS) -o $@ $(LOCAL_OBJS) $(TARGET_A) -L$(OBJDIR) -lm - -else ifeq ($(BOARD_TAG),teensy3) -# arm-none-eabi-ar doesn't work with release 4.7.1 -# $(CXX) $(LDFLAGS) -o $@ $(LOCAL_OBJS) $(TARGET_A) -lc -L$(OBJDIR) -lm -# $(CXX) $(LDFLAGS) -o $@ $(TARGET_A) $(LOCAL_OBJS) -L$(OBJDIR) -larm_cortexM4l_math -lm -# alternative without archive - $(CXX) $(LDFLAGS) -o $@ $(REMOTE_OBJS) $(LOCAL_OBJS) -L$(OBJDIR) -larm_cortexM4l_math -lm -# $(CC) $(LDFLAGS) -o $@ $(LOCAL_OBJS) $(REMOTE_OBJS) -L$(OBJDIR) -lm -# $(CXX) $(LDFLAGS) -o $@ $(OBJS) -L$(OBJDIR) -lm - -else ifeq ($(BOARD_TAG),teensy31) -# arm-none-eabi-ar doesn't work with release 4.7.1 - $(CXX) $(LDFLAGS) -o $@ $(REMOTE_OBJS) $(LOCAL_OBJS) -L$(OBJDIR) -larm_cortexM4l_math -lm - -else - $(CC) $(LDFLAGS) -o $@ $(LOCAL_OBJS) $(TARGET_A) -lm -endif - - -# 8- Final conversions -# ---------------------------------- -# -$(OBJDIR)/%.hex: $(OBJDIR)/%.elf - $(call SHOW,"8.1-COPY",$@,$<) - $(call TRACE,"8-COPY",$@,$<) - $(OBJCOPY) -Oihex -R .eeprom $< $@ - -$(OBJDIR)/%.bin: $(OBJDIR)/%.elf - $(call SHOW,"8.2-COPY",$@,$<) - $(call TRACE,"8-COPY",$@,$<) - $(OBJCOPY) -Obinary -v $< $@ - -$(OBJDIR)/%.eep: $(OBJDIR)/%.elf - $(call SHOW,"8.3-COPY",$@,$<) - $(call TRACE,"8-COPY",$@,$<) - -$(OBJCOPY) -Oihex -j .eeprom --set-section-flags=.eeprom=alloc,load --no-change-warnings --change-section-lma .eeprom=0 $< $@ - -$(OBJDIR)/%.lss: $(OBJDIR)/%.elf - $(call SHOW,"8.4-COPY",$@,$<) - $(call TRACE,"8-COPY",$@,$<) - $(OBJDUMP) -h -S $< > $@ - -$(OBJDIR)/%.sym: $(OBJDIR)/%.elf - $(call SHOW,"8.5-COPY",$@,$<) - $(call TRACE,"8-COPY",$@,$<) - $(NM) -n $< > $@ - - -# Size of file -# ---------------------------------- -# -ifeq ($(TARGET_HEXBIN),$(TARGET_HEX)) - HEXSIZE = $(SIZE) --target=ihex --totals $(CURRENT_DIR)/$(TARGET_HEX) | grep TOTALS | tr '\t' . | cut -d. -f2 | tr -d ' ' -else ifeq ($(TARGET_HEXBIN),$(TARGET_BIN)) - BINSIZE = $(SIZE) --target=binary --totals $(CURRENT_DIR)/$(TARGET_BIN) | grep TOTALS | tr '\t' . | cut -d. -f2 | tr -d ' ' -endif - -ifndef MAX_FLASH_SIZE - MAX_FLASH_SIZE = $(call PARSE_BOARD,$(BOARD_TAG),upload.maximum_size) -endif -ifndef MAX_RAM_SIZE - MAX_RAM_SIZE = $(call PARSE_BOARD,$(BOARD_TAG),upload.maximum_data_size) -endif -ELFSIZE = $(SIZE) $(CURRENT_DIR)/$(TARGET_ELF) -RAMSIZE = $(SIZE) $(CURRENT_DIR)/$(TARGET_ELF) | sed '1d' | awk '{t=$$3 + $$2} END {print t}' - -#PROGRAM_SIZE = $(SIZE) $(CURRENT_DIR)/$(TARGET_ELF) -C | grep Program: | cut -d: -f2 | sed -e 's/^[ \t]*//' - -#DATA_SIZE = $(SIZE) $(CURRENT_DIR)/$(TARGET_ELF) -C | grep Data: | cut -d: -f2 | sed -e 's/^[ \t]*//' - - -ifneq ($(MAX_FLASH_SIZE),) - MAX_FLASH_BYTES = 'bytes (of a '$(MAX_FLASH_SIZE)' byte maximum)' -else - MAX_FLASH_BYTES = bytes -endif - -ifneq ($(MAX_RAM_SIZE),) - MAX_RAM_BYTES = 'bytes (of a '$(MAX_RAM_SIZE)' byte maximum)' -else - MAX_RAM_BYTES = bytes -endif - - -# Serial monitoring -# ---------------------------------- -# - -# First /dev port -# -ifndef SERIAL_PORT - SERIAL_PORT = $(firstword $(wildcard $(BOARD_PORT))) -endif - -ifndef SERIAL_BAUDRATE - SERIAL_BAUDRATE = 9600 -endif - -ifndef SERIAL_COMMAND - SERIAL_COMMAND = screen -endif - -STARTCHRONO = $(shell $(UTILITIES_PATH)/embedXcode_chrono) -STOPCHRONO = $(shell $(UTILITIES_PATH)/embedXcode_chrono -s) - -ifeq ($(PLATFORM),Energia) - USED_SERIAL_PORT = $(lastword $(wildcard $(BOARD_PORT))) -# $(shell ls -1 $(BOARD_PORT) | tail -1 > $(UTILITIES_PATH)/serial.txt) -# $(shell ls -1 $(BOARD_PORT) | head -1 > $(UTILITIES_PATH)/serial.txt) -else - USED_SERIAL_PORT = $(firstword $(wildcard $(BOARD_PORT))) -endif - -#BOARD_PORT := $(shell $(UTILITIES_PATH)/embedXcode_serial $(BOARD_PORT)) - - -# Info for debugging -# ---------------------------------- -# -# 0- Info -# -info: - @if [ -f $(CURRENT_DIR)/About/About.txt ]; then $(CAT) $(CURRENT_DIR)/About/About.txt; fi; - @if [ -f $(UTILITIES_PATH)/embedXcode_check ]; then $(UTILITIES_PATH)/embedXcode_check; fi - @echo $(STARTCHRONO) - $(call TRACE,"0-START",) - -ifneq ($(MAKECMDGOALS),boards) -ifneq ($(MAKECMDGOALS),clean) - - @echo ==== Info ==== - @echo ---- Project ---- - @echo 'Target '$(MAKECMDGOALS) - @echo 'Name '$(PROJECT_NAME) - @echo 'Tag '$(BOARD_TAG) - @echo 'Extension '$(SKETCH_EXTENSION) - - @echo 'User '$(USER_PATH) - -ifneq ($(PLATFORM),Wiring) - @echo ---- Platform ---- - @echo 'IDE '$(PLATFORM) - -ifneq ($(PLATFORM),MapleIDE) - @echo 'Version '$(shell cat $(APPLICATION_PATH)/lib/version.txt) -else - @echo 'Version '$(shell cat $(APPLICATION_PATH)/lib/build-version.txt) -endif -endif - -ifneq ($(WARNING_MESSAGE),) - @echo 'WARNING ''$(WARNING_MESSAGE)' -endif - -ifneq ($(BUILD_CORE),) - @echo 'Platform '$(BUILD_CORE) -endif - -ifneq ($(VARIANT),) - @echo 'Variant '$(VARIANT) -endif - -ifneq ($(USB_VID),) - @echo 'USB VID '$(USB_VID) -endif - -ifneq ($(USB_PID),) - @echo 'USB PID '$(USB_PID) -endif - - @echo ---- Board ---- - @echo 'Name ''$(BOARD_NAME)' - @echo 'Frequency '$(F_CPU) - @echo 'MCU '$(MCU) -ifneq ($(MAX_FLASH_SIZE),) - @echo 'Flash memory '$(MAX_FLASH_SIZE)' bytes' -endif -ifneq ($(MAX_RAM_SIZE),) - @echo 'SRAM memory '$(MAX_RAM_SIZE)' bytes' -endif - - @echo ---- Port ---- - @echo 'Uploader '$(UPLOADER) - -ifeq ($(UPLOADER),avrdude) - @echo 'AVRdude '$(AVRDUDE_PORT) - ifneq ($(AVRDUDE_PROGRAMMER),) - @echo 'Programmer '$(AVRDUDE_PROGRAMMER) - endif -endif -ifeq ($(UPLOADER),mspdebug) - @echo 'Protocol '$(MSPDEBUG_PROTOCOL) -endif - -ifeq ($(AVRDUDE_NO_SERIAL_PORT),1) - @echo 'Serial no serial port' -else - @echo 'Serial '$(USED_SERIAL_PORT) -endif - - @echo ---- Libraries ---- - @echo . Core libraries from $(CORE_LIB_PATH) | cut -d. -f1,2 - @echo $(CORE_LIBS_LIST) - - @echo . Application libraries from $(basename $(APP_LIB_PATH)) | cut -d. -f1,2 - @echo $(APP_LIBS_LIST) - - @echo . User libraries from $(SKETCHBOOK_DIR) - @echo $(USER_LIBS_LIST) - - @echo . Local libraries from $(CURRENT_DIR) - -ifneq ($(wildcard *.h),) - @echo $(subst .h,,$(wildcard *.h)) -else - @echo 0 -endif - - @echo ==== Info done ==== -endif -endif - - -# Release management -# ---------------------------------- -# -RELEASE_NOW := 141 - - -# Rules -# ---------------------------------- -# -all: info message_all clean compile reset raw_upload serial end_all prepare - -build: info message_build clean compile end_build prepare - -compile: info message_compile $(OBJDIR) $(TARGET_HEXBIN) $(TARGET_EEP) size - @echo $(BOARD_TAG) > $(NEW_TAG) - -prepare: - @if [ -f $(UTILITIES_PATH)/embedXcode_prepare ]; then $(UTILITIES_PATH)/embedXcode_prepare $(SCOPE_FLAG) "$(USER_LIB_PATH)"; rm -r $(UTILITIES_PATH)/embedXcode_prepare; fi; - -$(OBJDIR): - @echo "---- Build ---- " - @mkdir $(OBJDIR) - -#$(TARGET_ELF): $(OBJS) -# @echo "7-" $< -#ifeq ($(PLATFORM),MapleIDE) -# $(CXX) $(LDFLAGS) -o $@ $(OBJS) $(SYS_OBJS) -L$(OBJDIR) -#else -# $(CC) $(LDFLAGS) -o $@ $(OBJS) $(SYS_OBJS) -lc -#endif - -$(DEP_FILE): $(OBJDIR) $(DEPS) - @echo "9-" $< - @cat $(DEPS) > $(DEP_FILE) - - -upload: message_upload reset raw_upload - @echo "==== upload done ==== " - - -reset: - @echo "---- Reset ---- " - -screen -X kill - sleep 1 -ifeq ($(UPLOADER),dfu-util) - $(call SHOW,"9.1-RESET",$(DFU_RESET)) - $(call TRACE,"9-RESET",$(DFU_RESET)) - $(DFU_RESET) - sleep 1 -endif - -ifdef USB_RESET -# Method 1 - $(call SHOW,"9.2-RESET",USB_RESET 1200) - $(call TRACE,"9-RESET",USB_RESET 1200) - stty -f $(AVRDUDE_PORT) 1200 - sleep 2 -# Method 2 -# $(USB_RESET) $(AVRDUDE_PORT) -# sleep 2 -endif - -# stty on MacOS likes -F, but on Debian it likes -f redirecting -# stdin/out appears to work but generates a spurious error on MacOS at -# least. Perhaps it would be better to just do it in perl ? -# @if [ -z "$(AVRDUDE_PORT)" ]; then \ -# echo "No Arduino-compatible TTY device found -- exiting"; exit 2; \ -# fi -# for STTYF in 'stty --file' 'stty -f' 'stty <' ; \ -# do $$STTYF /dev/tty >/dev/null 2>/dev/null && break ; \ -# done ;\ -# $$STTYF $(AVRDUDE_PORT) hupcl ;\ -# (sleep 0.1 || sleep 1) ;\ -# $$STTYF $(AVRDUDE_PORT) -hupcl - - -raw_upload: - @echo "---- Upload ---- " - -ifeq ($(UPLOADER),micronucleus) - osascript -e 'tell application "System Events" to display dialog "Click OK and plug the Digispark into the USB port." buttons {"OK"} with icon POSIX file ("$(UTILITIES_PATH)/TemplateIcon.icns") with title "embedXcode"' - $(call SHOW,"9.1-UPLOAD",$(UPLOADER)) - $(call TRACE,"9-UPLOAD",$(UPLOADER)) - $(AVRDUDE_EXEC) $(AVRDUDE_COM_OPTS) $(AVRDUDE_OPTS) -P$(USED_SERIAL_PORT) -Uflash:w:$(TARGET_HEX):i - -else ifeq ($(UPLOADER),avrdude) - $(call SHOW,"9.3-UPLOAD",$(UPLOADER)) - $(call TRACE,"9-UPLOAD",$(UPLOADER)) - $(AVRDUDE_EXEC) $(AVRDUDE_COM_OPTS) $(AVRDUDE_OPTS) -P$(USED_SERIAL_PORT) -Uflash:w:$(TARGET_HEX):i - - ifeq ($(AVRDUDE_PROGRAMMER),avr109) - sleep 2 - endif - -else ifeq ($(UPLOADER),bossac) - $(call SHOW,"9.4-UPLOAD",$(UPLOADER)) - $(call TRACE,"9-UPLOAD",$(UPLOADER)) - $(BOSSAC) $(BOSSAC_OPTS) $(TARGET_BIN) -R - -else ifeq ($(UPLOADER),mspdebug) - $(call SHOW,"9.5-UPLOAD",$(UPLOADER)) - $(call TRACE,"9-UPLOAD",$(UPLOADER)) - -ifeq ($(MSPDEBUG_PROTOCOL),tilib) -# libmsp430.so needs to be in the current directory -# Solution 1: change directory doesn't work -# cd $(MSPDEBUG_PATH) -# $(MSPDEBUG) $(MSPDEBUG_OPTS) "$(MSPDEBUG_COMMAND) $(TARGET_HEX)" -# cd $(CURRENT_DIR) - -# Solution 2: make a copy of libmsp430.so in the current directory - @cp $(MSPDEBUG_PATH)/libmsp430.so . - $(MSPDEBUG) $(MSPDEBUG_OPTS) "$(MSPDEBUG_COMMAND) $(TARGET_HEX)" - @rm libmsp430.so - @rm comm.log - -else - $(MSPDEBUG) $(MSPDEBUG_OPTS) "$(MSPDEBUG_COMMAND) $(TARGET_HEX)" -endif - -else ifeq ($(UPLOADER),lm4flash) - $(call SHOW,"9.6-UPLOAD",$(UPLOADER)) - $(call TRACE,"9-UPLOAD",$(UPLOADER)) - $(LM4FLASH) $(LM4FLASH_OPTS) $(TARGET_BIN) - -else ifeq ($(UPLOADER),dfu-util) - $(call SHOW,"9.7-UPLOAD",$(UPLOADER)) - $(call TRACE,"9-UPLOAD",$(UPLOADER)) - $(DFU_UTIL) $(DFU_UTIL_OPTS) -D $(TARGET_BIN) -R - sleep 4 - $(info .) - -else ifeq ($(UPLOADER),teensy_flash) - $(call SHOW,"9.8-UPLOAD",$(UPLOADER)) - $(call TRACE,"9-UPLOAD",$(UPLOADER)) - $(TEENSY_POST_COMPILE) -file=$(basename $(notdir $(TARGET_HEX))) -path=$(dir $(abspath $(TARGET_HEX))) -tools=$(abspath $(TEENSY_FLASH_PATH))/ - sleep 2 - $(TEENSY_REBOOT) - sleep 2 - -else - $(error No valid uploader) -endif - - -ispload: $(TARGET_HEX) - @echo "---- ISP upload ---- " -ifeq ($(UPLOADER),avrdude) - $(call SHOW,"9.9-UPLOAD",$(UPLOADER)) - $(call TRACE,"9-UPLOAD",$(UPLOADER)) - $(AVRDUDE_EXEC) $(AVRDUDE_COM_OPTS) $(AVRDUDE_ISP_OPTS) -e \ - -U lock:w:$(ISP_LOCK_FUSE_PRE):m \ - -U hfuse:w:$(ISP_HIGH_FUSE):m \ - -U lfuse:w:$(ISP_LOW_FUSE):m \ - -U efuse:w:$(ISP_EXT_FUSE):m - $(AVRDUDE_EXEC) $(AVRDUDE_COM_OPTS) $(AVRDUDE_ISP_OPTS) -D \ - -U flash:w:$(TARGET_HEX):i - $(AVRDUDE_EXEC) $(AVRDUDE_COM_OPTS) $(AVRDUDE_ISP_OPTS) \ - -U lock:w:$(ISP_LOCK_FUSE_POST):m -endif - -serial: reset - @echo "---- Serial ---- " -ifeq ($(AVRDUDE_NO_SERIAL_PORT),1) - @echo "The programmer provides no serial port" -else - osascript -e 'tell application "Terminal" to do script "$(SERIAL_COMMAND) $(USED_SERIAL_PORT) $(SERIAL_BAUDRATE)"' -endif - -# echo "$@" -# echo "-- " -# export TERM="vt100" -# echo "#!/bin/sh" /tmp/arduino.command -# echo "$(SERIAL_COMMAND) $(SERIAL_PORT) $(SERIAL_BAUDRATE)" > /tmp/arduino.command -# chmod 0755 /tmp/arduino.command -# open /tmp/arduino.command - -size: - @echo "---- Size ----" -# echo 'PROGRAM_SIZE ' $(shell $(PROGRAM_SIZE)) -# echo 'DATA_SIZE ' $(shell $(DATA_SIZE)) - @if [ -f $(TARGET_HEX) ]; then echo 'Binary sketch size: ' $(shell $(HEXSIZE)) $(MAX_FLASH_BYTES); echo; fi -# @if [ -f $(TARGET_ELF) ]; then $(ELFSIZE); echo; fi - @if [ -f $(TARGET_BIN) ]; then echo 'Binary sketch size:' $(shell $(BINSIZE)) $(MAX_FLASH_BYTES); echo; fi - @if [ -f $(TARGET_ELF) ]; then echo 'Estimated SRAM used:' $(shell $(RAMSIZE)) $(MAX_RAM_BYTES); echo; fi -# @echo PROGRAM_SIZE $(PROGRAM_SIZE) -# @echo DATA_SIZE $(DATA_SIZE) - @echo 'Elapsed time:' $(STOPCHRONO) -# @if [ -n '$(MESSAGE_LINE)' ]; then echo 'Message: $(MESSAGE_LINE)'; fi; - -clean: - @if [ ! -d $(OBJDIR) ]; then mkdir $(OBJDIR); fi - @echo "nil" > $(OBJDIR)/nil - @echo "---- Clean ----" - -@rm -r $(OBJDIR)/* # */ - -changed: - @echo "---- Clean changed ----" -ifeq ($(CHANGE_FLAG),1) - @if [ ! -d $(OBJDIR) ]; then mkdir $(OBJDIR); fi - @echo "nil" > $(OBJDIR)/nil - $(REMOVE) $(OBJDIR)/* # */ -else -# $(REMOVE) $(LOCAL_OBJS) - for f in $(LOCAL_OBJS); do if [ -f $$f ]; then rm $$f; fi; done -endif - -depends: $(DEPS) - @echo "---- Depends ---- " - @cat $(DEPS) > $(DEP_FILE) - -boards: - @echo "==== Boards ====" - @echo "Tag=Name" - @if [ -f $(ARDUINO_PATH)/hardware/arduino/boards.txt ]; then echo "---- $(notdir $(basename $(ARDUINO_APP))) ---- "; \ - grep .name $(ARDUINO_PATH)/hardware/arduino/boards.txt; echo; fi - @if [ -d $(ARDUINO_PATH)/hardware/arduino/sam ]; then echo "---- $(notdir $(basename $(ARDUINO_APP))) SAM ---- "; \ - grep .name $(ARDUINO_PATH)/hardware/arduino/sam/boards.txt; echo; fi - @if [ -d $(ARDUINO_PATH)/hardware/arduino/avr ]; then echo "---- $(notdir $(basename $(ARDUINO_APP))) AVR ---- "; \ - grep .name $(ARDUINO_PATH)/hardware/arduino/avr/boards.txt; echo; fi - @if [ -d $(MPIDE_APP) ]; then echo "---- $(notdir $(basename $(MPIDE_APP))) ---- "; \ - grep .name $(MPIDE_PATH)/hardware/pic32/boards.txt; echo; fi - @if [ -d $(DIGISPARK_APP) ]; then echo "---- $(notdir $(basename $(DIGISPARK_APP))) ---- "; \ - grep .name $(DIGISPARK_PATH)/hardware/digispark/boards.txt; echo; fi - @if [ -d $(ENERGIA_APP) ]; then echo "---- $(notdir $(basename $(ENERGIA_APP))) MSP430 ---- "; \ - grep .name $(ENERGIA_PATH)/hardware/msp430/boards.txt; echo; fi - @if [ -d $(ENERGIA_PATH)/hardware/lm4f ]; then echo "---- $(notdir $(basename $(ENERGIA_APP))) LM4F ---- "; \ - grep .name $(ENERGIA_PATH)/hardware/lm4f/boards.txt; echo; fi - @if [ -d $(MAPLE_APP) ]; then echo "---- $(notdir $(basename $(MAPLE_APP))) ---- "; \ - grep .name $(MAPLE_PATH)/hardware/leaflabs/boards.txt; echo; fi - @if [ -d $(MICRODUINO_APP) ]; then echo "---- $(notdir $(basename $(MICRODUINO_APP))) ---- "; \ - grep .name $(MICRODUINO_PATH)/hardware/Microduino/boards.txt; echo; fi - @if [ -d $(TEENSY_APP) ]; then echo "---- $(notdir $(basename $(TEENSY_APP))) ---- "; \ - grep .name $(TEENSY_PATH)/hardware/teensy/boards.txt | grep -v menu; echo; fi - @if [ -d $(WIRING_APP) ]; then echo "---- $(notdir $(basename $(WIRING_APP))) ---- "; \ - grep .name $(WIRING_PATH)/hardware/Wiring/boards.txt; echo; fi - @echo "==== Boards done ==== " - -message_all: - @echo "==== All ====" - -message_build: - @echo "==== Build ====" - -message_compile: - @echo "---- Compile ----" - -message_upload: - @echo "==== Upload ====" - -end_all: - @echo "==== All done ==== " - -end_build: - @echo "==== Build done ==== " - - -.PHONY: all clean depends upload raw_upload reset serial show_boards headers size document diff --git a/FastLED/FastLED/Makefiles/Teensy.mk b/FastLED/FastLED/Makefiles/Teensy.mk deleted file mode 100755 index 331388a5..00000000 --- a/FastLED/FastLED/Makefiles/Teensy.mk +++ /dev/null @@ -1,57 +0,0 @@ -# -# embedXcode -# ---------------------------------- -# Embedded Computing on Xcode -# -# Copyright © Rei VILO, 2010-2014 -# http://embedxcode.weebly.com -# All rights reserved -# -# -# Last update: Feb 01, 2014 release 129 - - - -# Teensy specifics -# ---------------------------------- -# -PLATFORM := Teensy -PLATFORM_TAG = ARDUINO=105 TEENSYDUINO=117 EMBEDXCODE=$(RELEASE_NOW) -APPLICATION_PATH := $(TEENSY_PATH) - - -# Automatic Teensy2 or Teensy 3 selection based on build.core -# -BOARDS_TXT := $(APPLICATION_PATH)/hardware/teensy/boards.txt -BUILD_CORE = $(call PARSE_BOARD,$(BOARD_TAG),build.core) - -ifeq ($(BUILD_CORE),teensy) - include $(MAKEFILE_PATH)/Teensy2.mk -else ifeq ($(BUILD_CORE),teensy3) - include $(MAKEFILE_PATH)/Teensy3.mk -else - $(error $(BUILD_CORE) unknown) -endif - -# Teensy USB PID VID -# -USB_VID := $(call PARSE_BOARD,$(BOARD_TAG),build.vid) -USB_PID := $(call PARSE_BOARD,$(BOARD_TAG),build.pid) - -ifneq ($(USB_PID),) -ifneq ($(USB_VID),) - USB_FLAGS = -DUSB_VID=$(USB_VID) - USB_FLAGS += -DUSB_PID=$(USB_PID) -endif -endif - -ifeq ($(USB_FLAGS),) - USB_FLAGS = -DUSB_VID=null -DUSB_PID=null -endif - -USB_FLAGS += -DUSB_SERIAL -DLAYOUT_US_ENGLISH -DTIME_T=$(shell date +%s) - -MAX_RAM_SIZE = $(call PARSE_BOARD,$(BOARD_TAG),upload.maximum_ram_size) - - - diff --git a/FastLED/FastLED/Makefiles/Teensy2.mk b/FastLED/FastLED/Makefiles/Teensy2.mk deleted file mode 100755 index 851d8eaa..00000000 --- a/FastLED/FastLED/Makefiles/Teensy2.mk +++ /dev/null @@ -1,99 +0,0 @@ -# -# embedXcode -# ---------------------------------- -# Embedded Computing on Xcode -# -# Copyright © Rei VILO, 2010-2014 -# http://embedxcode.weebly.com -# All rights reserved -# -# -# Last update: Mar 01, 2014 release 136 - - - -# Teensy 2.0 specifics -# ---------------------------------- -# -BUILD_CORE := avr - -UPLOADER = teensy_flash -TEENSY_FLASH_PATH = $(APPLICATION_PATH)/hardware/tools/avr/bin -TEENSY_POST_COMPILE = $(TEENSY_FLASH_PATH)/teensy_post_compile -TEENSY_REBOOT = $(TEENSY_FLASH_PATH)/teensy_reboot - -APP_TOOLS_PATH := $(APPLICATION_PATH)/hardware/tools/avr/bin -CORE_LIB_PATH := $(APPLICATION_PATH)/hardware/teensy/cores/teensy -APP_LIB_PATH := $(APPLICATION_PATH)/libraries - -BUILD_CORE_LIB_PATH = $(APPLICATION_PATH)/hardware/teensy/cores/teensy3/avr -BUILD_CORE_LIBS_LIST = $(subst .h,,$(subst $(BUILD_CORE_LIB_PATH)/,,$(wildcard $(BUILD_CORE_LIB_PATH)/*.h))) # */ -BUILD_CORE_C_SRCS = $(wildcard $(BUILD_CORE_LIB_PATH)/*.c) # */ - -ifneq ($(strip $(NO_CORE_MAIN_FUNCTION)),) - BUILD_CORE_CPP_SRCS = $(filter-out %program.cpp %main.cpp,$(wildcard $(BUILD_CORE_LIB_PATH)/*.cpp)) # */ -else - BUILD_CORE_CPP_SRCS = $(filter-out %program.cpp, $(wildcard $(BUILD_CORE_LIB_PATH)/*.cpp)) # */ -endif - -BUILD_CORE_OBJ_FILES = $(BUILD_CORE_C_SRCS:.c=.o) $(BUILD_CORE_CPP_SRCS:.cpp=.o) -BUILD_CORE_OBJS = $(patsubst $(BUILD_CORE_LIB_PATH)/%,$(OBJDIR)/%,$(BUILD_CORE_OBJ_FILES)) - -# Sketchbook/Libraries path -# wildcard required for ~ management -# ?ibraries required for libraries and Libraries -# -ifeq ($(USER_PATH)/Library/Arduino/preferences.txt,) - $(error Error: run Teensy once and define the sketchbook path) -endif - -ifeq ($(wildcard $(SKETCHBOOK_DIR)),) - SKETCHBOOK_DIR = $(shell grep sketchbook.path $(wildcard ~/Library/Arduino/preferences.txt) | cut -d = -f 2) -endif - -ifeq ($(wildcard $(SKETCHBOOK_DIR)),) - $(error Error: sketchbook path not found) -endif - -USER_LIB_PATH = $(wildcard $(SKETCHBOOK_DIR)/?ibraries) - - -# Rules for making a c++ file from the main sketch (.pde) -# -PDEHEADER = \\\#include \"WProgram.h\" - - -# Tool-chain names -# -CC = $(APP_TOOLS_PATH)/avr-gcc -CXX = $(APP_TOOLS_PATH)/avr-g++ -AR = $(APP_TOOLS_PATH)/avr-ar -OBJDUMP = $(APP_TOOLS_PATH)/avr-objdump -OBJCOPY = $(APP_TOOLS_PATH)/avr-objcopy -SIZE = $(APP_TOOLS_PATH)/avr-size -NM = $(APP_TOOLS_PATH)/avr-nm - - -#LDSCRIPT = $(call PARSE_BOARD,$(BOARD_TAG),build.linkscript) -#VARIANT = $(call PARSE_BOARD,$(BOARD_TAG),build.variant) -#VARIANT_PATH = $(APPLICATION_PATH)/hardware/lm4f/variants/$(VARIANT) - -MCU_FLAG_NAME = mmcu -MCU = atmega32u4 -F_CPU = 16000000 - -#EXTRA_LDFLAGS = -T$(CORE_LIB_PATH)/$(LDSCRIPT) -mthumb - -# CXX = flags for C++ only -# CPP = flags for both C and C++ -# -EXTRA_CPPFLAGS = $(addprefix -D, $(PLATFORM_TAG)) -D__AVR_ATmega32U4__ -nostdlib -MMD -EXTRA_CXXFLAGS = -fno-rtti -felide-constructors -std=c++0x - - -#EXTRA_CPPFLAGS += $(call PARSE_BOARD,$(BOARD_TAG),build.option3) # -D__MK20DX128__ - -OBJCOPYFLAGS = -R .eeprom -Oihex -TARGET_HEXBIN = $(TARGET_HEX) -TARGET_EEP = $(OBJDIR)/$(TARGET).eep - diff --git a/FastLED/FastLED/Makefiles/Teensy3.mk b/FastLED/FastLED/Makefiles/Teensy3.mk deleted file mode 100755 index 9d3b8d82..00000000 --- a/FastLED/FastLED/Makefiles/Teensy3.mk +++ /dev/null @@ -1,96 +0,0 @@ -# -# embedXcode -# ---------------------------------- -# Embedded Computing on Xcode -# -# Copyright © Rei VILO, 2010-2014 -# http://embedxcode.weebly.com -# All rights reserved -# -# -# Last update: Mar 01, 2014 release 136 - - - -# Teensy 3.0 specifics -# ---------------------------------- -# -BUILD_CORE := arm - -UPLOADER = teensy_flash -TEENSY_FLASH_PATH = $(APPLICATION_PATH)/hardware/tools -TEENSY_POST_COMPILE = $(TEENSY_FLASH_PATH)/teensy_post_compile -TEENSY_REBOOT = $(TEENSY_FLASH_PATH)/teensy_reboot - -APP_TOOLS_PATH := $(APPLICATION_PATH)/hardware/tools/arm-none-eabi/bin -CORE_LIB_PATH := $(APPLICATION_PATH)/hardware/teensy/cores/teensy3 -APP_LIB_PATH := $(APPLICATION_PATH)/libraries - -BUILD_CORE_LIB_PATH = $(APPLICATION_PATH)/hardware/teensy/cores/teensy3/avr -BUILD_CORE_LIBS_LIST = $(subst .h,,$(subst $(BUILD_CORE_LIB_PATH)/,,$(wildcard $(BUILD_CORE_LIB_PATH)/*/*.h))) # */ -BUILD_CORE_C_SRCS = $(wildcard $(BUILD_CORE_LIB_PATH)/*.c) # */ - -ifneq ($(strip $(NO_CORE_MAIN_FUNCTION)),) - BUILD_CORE_CPP_SRCS = $(filter-out %program.cpp %main.cpp,$(wildcard $(BUILD_CORE_LIB_PATH)/*.cpp)) # */ -else - BUILD_CORE_CPP_SRCS = $(filter-out %program.cpp, $(wildcard $(BUILD_CORE_LIB_PATH)/*.cpp)) # */ -endif - -BUILD_CORE_OBJ_FILES = $(BUILD_CORE_C_SRCS:.c=.o) $(BUILD_CORE_CPP_SRCS:.cpp=.o) -BUILD_CORE_OBJS = $(patsubst $(BUILD_CORE_LIB_PATH)/%,$(OBJDIR)/%,$(BUILD_CORE_OBJ_FILES)) - -# Sketchbook/Libraries path -# wildcard required for ~ management -# ?ibraries required for libraries and Libraries -# -ifeq ($(USER_PATH)/Library/Arduino/preferences.txt,) - $(error Error: run Arduino with Teensy plug-in once and define the sketchbook path) -endif - -ifeq ($(wildcard $(SKETCHBOOK_DIR)),) - SKETCHBOOK_DIR = $(shell grep sketchbook.path $(wildcard ~/Library/Arduino/preferences.txt) | cut -d = -f 2) -endif - -ifeq ($(wildcard $(SKETCHBOOK_DIR)),) - $(error Error: sketchbook path not found) -endif - -USER_LIB_PATH = $(wildcard $(SKETCHBOOK_DIR)/?ibraries) - - -# Rules for making a c++ file from the main sketch (.pde) -# -PDEHEADER = \\\#include \"WProgram.h\" - - -# Tool-chain names -# -CC = $(APP_TOOLS_PATH)/arm-none-eabi-gcc -CXX = $(APP_TOOLS_PATH)/arm-none-eabi-g++ -AR = $(APP_TOOLS_PATH)/arm-none-eabi-ar -OBJDUMP = $(APP_TOOLS_PATH)/arm-none-eabi-objdump -OBJCOPY = $(APP_TOOLS_PATH)/arm-none-eabi-objcopy -SIZE = $(APP_TOOLS_PATH)/arm-none-eabi-size -NM = $(APP_TOOLS_PATH)/arm-none-eabi-nm - - -LDSCRIPT = $(call PARSE_BOARD,$(BOARD_TAG),build.linkscript) -#VARIANT = $(call PARSE_BOARD,$(BOARD_TAG),build.variant) -#VARIANT_PATH = $(APPLICATION_PATH)/hardware/lm4f/variants/$(VARIANT) - -MCU_FLAG_NAME = mcpu -MCU = $(call PARSE_BOARD,$(BOARD_TAG),build.cpu) -F_CPU = 96000000 - -EXTRA_LDFLAGS = -mthumb -T$(CORE_LIB_PATH)/$(LDSCRIPT) - -# CXX = flags for C++ only -# CPP = flags for both C and C++ -# -EXTRA_CPPFLAGS = $(addprefix -D, $(PLATFORM_TAG)) $(call PARSE_BOARD,$(BOARD_TAG),build.option3) -nostdlib -mthumb -MMD -EXTRA_CXXFLAGS = -fno-exceptions -fno-rtti -felide-constructors -std=gnu++0x - -OBJCOPYFLAGS = -R .eeprom -O ihex -TARGET_HEXBIN = $(TARGET_HEX) -TARGET_EEP = $(OBJDIR)/$(TARGET).eep - diff --git a/FastLED/FastLED/Makefiles/Wiring.mk b/FastLED/FastLED/Makefiles/Wiring.mk deleted file mode 100755 index 115bad28..00000000 --- a/FastLED/FastLED/Makefiles/Wiring.mk +++ /dev/null @@ -1,123 +0,0 @@ -# -# embedXcode -# ---------------------------------- -# Embedded Computing on Xcode -# -# Copyright © Rei VILO, 2010-2014 -# http://embedxcode.weebly.com -# All rights reserved -# -# -# Last update: Mar 01, 2014 release 136 - -# WIRING SUPPORT IS PUT ON HOLD -WARNING_MESSAGE = 'WIRING SUPPORT IS PUT ON HOLD' - - -# Wiring specifics -# ---------------------------------- -# -PLATFORM := Wiring -PLATFORM_TAG = WIRING=100 EMBEDXCODE=$(RELEASE_NOW) -APPLICATION_PATH := $(WIRING_PATH) - -APP_TOOLS_PATH := $(APPLICATION_PATH)/tools/avr/bin -CORE_LIB_PATH := $(APPLICATION_PATH)/cores/Common -APP_LIB_PATH := $(APPLICATION_PATH)/libraries -BOARDS_TXT := $(APPLICATION_PATH)/hardware/Wiring/boards.txt - -# Sketchbook/Libraries path -# wildcard required for ~ management -# ?ibraries required for libraries and Libraries -# -ifeq ($(USER_PATH)/Library/Wiring/preferences.txt,) - $(error Error: run Wiring once and define the sketchbook path) -endif - -ifeq ($(wildcard $(SKETCHBOOK_DIR)),) - SKETCHBOOK_DIR = $(shell grep sketchbook.path $(USER_PATH)/Library/Wiring/preferences.txt | cut -d = -f 2) -endif -ifeq ($(wildcard $(SKETCHBOOK_DIR)),) - $(error Error: sketchbook path not found) -endif -USER_LIB_PATH = $(wildcard $(SKETCHBOOK_DIR)/?ibraries) - -# Rules for making a c++ file from the main sketch (.pde) -# -PDEHEADER = \\\#include \"Wiring.h\" - -# Tool-chain names -# -CC = $(APP_TOOLS_PATH)/avr-gcc -CXX = $(APP_TOOLS_PATH)/avr-g++ -AR = $(APP_TOOLS_PATH)/avr-ar -OBJDUMP = $(APP_TOOLS_PATH)/avr-objdump -OBJCOPY = $(APP_TOOLS_PATH)/avr-objcopy -SIZE = $(APP_TOOLS_PATH)/avr-size -NM = $(APP_TOOLS_PATH)/avr-nm - -# Specific AVRDUDE location and options -# -AVRDUDE_PATH = $(APPLICATION_PATH)/tools/avr -AVRDUDE = $(AVRDUDE_PATH)/bin/avrdude -AVRDUDE_CONF = $(AVRDUDE_PATH)/bin/avrdude.conf -AVRDUDE_COM_OPTS = -D -p$(MCU) -C$(AVRDUDE_CONF) - -BOARD = $(call PARSE_BOARD,$(BOARD_TAG),board) -#LDSCRIPT = $(call PARSE_BOARD,$(BOARD_TAG),ldscript) -VARIANT = $(call PARSE_BOARD,$(BOARD_TAG),build.hardware) -VARIANT_PATH = $(APPLICATION_PATH)/hardware/Wiring/$(VARIANT) -BUILD_CORE = $(call PARSE_BOARD,$(BOARD_TAG),build.core) - -BUILD_CORE_LIB_PATH = $(APPLICATION_PATH)/cores/$(BUILD_CORE) -BUILD_CORE_LIBS_LIST = $(subst .h,,$(subst $(BUILD_CORE_LIB_PATH)/,,$(wildcard $(BUILD_CORE_LIB_PATH)/*.h))) # */ - -BUILD_CORE_C_SRCS = $(wildcard $(BUILD_CORE_LIB_PATH)/*.c) # */ - -ifneq ($(strip $(NO_CORE_MAIN_FUNCTION)),) - BUILD_CORE_CPP_SRCS = $(filter-out %program.cpp %main.cpp,$(wildcard $(BUILD_CORE_LIB_PATH)/*.cpp)) # */ -else - BUILD_CORE_CPP_SRCS = $(filter-out %program.cpp, $(wildcard $(BUILD_CORE_LIB_PATH)/*.cpp)) # */ -endif - -BUILD_CORE_OBJ_FILES = $(BUILD_CORE_C_SRCS:.c=.o) $(BUILD_CORE_CPP_SRCS:.cpp=.o) -BUILD_CORE_OBJS = $(patsubst $(BUILD_CORE_LIB_PATH)/%,$(OBJDIR)/%,$(BUILD_CORE_OBJ_FILES)) - -# Extra variant library -# -VARIANT_CPP_SRC = $(wildcard $(VARIANT_PATH)/*.cpp) -VARIANT_OBJS = $(patsubst $(VARIANT_PATH)/%.cpp,$(OBJDIR)/libs/%.o,$(VARIANT_CPP_SRC)) # */ - -# Two locations for Wiring libraries -# -BUILD_APP_LIB_PATH = $(BUILD_CORE_LIB_PATH)/libraries - -ifndef APP_LIBS_LIST - w1 = $(realpath $(sort $(dir $(wildcard $(APP_LIB_PATH)/*/*.h $(APP_LIB_PATH)/*/*/*.h)))) # */ - APP_LIBS_LIST = $(subst $(APP_LIB_PATH)/,,$(filter-out $(EXCLUDE_LIST),$(w1))) - - w2 = $(realpath $(sort $(dir $(wildcard $(BUILD_APP_LIB_PATH)/*/*.h $(BUILD_APP_LIB_PATH)/*/*/*.h)))) # */ - BUILD_APP_LIBS_LIST = $(subst $(BUILD_APP_LIB_PATH)/,,$(filter-out $(EXCLUDE_LIST),$(w2))) -else - BUILD_APP_LIBS_LIST = $(APP_LIBS_LIST) -endif - -ifneq ($(APP_LIBS_LIST),0) - APP_LIBS = $(patsubst %,$(APP_LIB_PATH)/%,$(APP_LIBS_LIST)) - APP_LIB_CPP_SRC = $(wildcard $(patsubst %,%/*.cpp,$(APP_LIBS))) # */ - APP_LIB_C_SRC = $(wildcard $(patsubst %,%/*.c,$(APP_LIBS))) # */ - - APP_LIB_OBJS = $(patsubst $(APP_LIB_PATH)/%.cpp,$(OBJDIR)/libs/%.o,$(APP_LIB_CPP_SRC)) - APP_LIB_OBJS += $(patsubst $(APP_LIB_PATH)/%.c,$(OBJDIR)/libs/%.o,$(APP_LIB_C_SRC)) - - BUILD_APP_LIBS = $(patsubst %,$(BUILD_APP_LIB_PATH)/%,$(BUILD_APP_LIBS_LIST)) - BUILD_APP_LIB_CPP_SRC = $(wildcard $(patsubst %,%/*.cpp,$(BUILD_APP_LIBS))) # */ - BUILD_APP_LIB_C_SRC = $(wildcard $(patsubst %,%/*.c,$(BUILD_APP_LIBS))) # */ - - BUILD_APP_LIB_OBJS = $(patsubst $(BUILD_APP_LIB_PATH)/%.cpp,$(OBJDIR)/libs/%.o,$(BUILD_APP_LIB_CPP_SRC)) - BUILD_APP_LIB_OBJS += $(patsubst $(BUILD_APP_LIB_PATH)/%.c,$(OBJDIR)/libs/%.o,$(BUILD_APP_LIB_C_SRC)) -endif - -MCU_FLAG_NAME = mmcu -EXTRA_LDFLAGS = -EXTRA_CPPFLAGS = $(addprefix -D, $(PLATFORM_TAG)) -I$(CORE_LIB_PATH) -I$(BUILD_CORE_LIB_PATH) -I$(VARIANT_PATH) diff --git a/FastLED/FastLED/ReadMe.txt b/FastLED/FastLED/ReadMe.txt deleted file mode 100644 index 0a6d3b4f..00000000 --- a/FastLED/FastLED/ReadMe.txt +++ /dev/null @@ -1,26 +0,0 @@ - - FastLED - Project - ---------------------------------- - Developed with embedXcode - - Project FastLED - Created by Daniel Garcia on 4/2/14 - Copyright © 2014 Daniel Garcia - License <#license#> - - - - References - ---------------------------------- - - - - embedXcode - embedXcode+ - ---------------------------------- - Embedded Computing on Xcode - Copyright © Rei VILO, 2010-2014 - All rights reserved - http://embedXcode.weebly.com - diff --git a/FastLED/FastLED/Sketchbook/Sketchbook.txt b/FastLED/FastLED/Sketchbook/Sketchbook.txt deleted file mode 100644 index 029dd8a5..00000000 --- a/FastLED/FastLED/Sketchbook/Sketchbook.txt +++ /dev/null @@ -1,9 +0,0 @@ - -Drag and drop your user library folder under the Sketchbook group. - -Then, -• Uncheck Copy items into destination group's folder (if necessary). -• Choose Folders Create groups for any added folders. -• Check Add to targets Index. - -Your user library folder is usually located at Sketchbook > Libraries. \ No newline at end of file diff --git a/FastLED/FastLED/Utilities/TemplateIcon.icns b/FastLED/FastLED/Utilities/TemplateIcon.icns deleted file mode 100644 index 80e2c3f0..00000000 Binary files a/FastLED/FastLED/Utilities/TemplateIcon.icns and /dev/null differ diff --git a/FastLED/FastLED/Utilities/embedXcode_check b/FastLED/FastLED/Utilities/embedXcode_check deleted file mode 100755 index d8a7a710..00000000 Binary files a/FastLED/FastLED/Utilities/embedXcode_check and /dev/null differ diff --git a/FastLED/FastLED/Utilities/embedXcode_chrono b/FastLED/FastLED/Utilities/embedXcode_chrono deleted file mode 100755 index 7fec711d..00000000 Binary files a/FastLED/FastLED/Utilities/embedXcode_chrono and /dev/null differ diff --git a/FastLED/FastLED/Utilities/embedXcode_prepare b/FastLED/FastLED/Utilities/embedXcode_prepare deleted file mode 100755 index 7ce78022..00000000 Binary files a/FastLED/FastLED/Utilities/embedXcode_prepare and /dev/null differ diff --git a/FastLED/FastLED/Utilities/reset.py b/FastLED/FastLED/Utilities/reset.py deleted file mode 100755 index 6410c563..00000000 --- a/FastLED/FastLED/Utilities/reset.py +++ /dev/null @@ -1,124 +0,0 @@ -#!/usr/bin/env python - -import serial -import os -import platform -import sys -import time -from struct import pack - -def unix_get_maple_path(file_prefix): - """Try to find the device file for the Maple on *nix; assuming - that it looks like /dev/*. If there are multiple - possibilities, ask the user what to do. If the user chooses not - to say, returns None.""" - possible_paths = [os.path.join('/dev', x) for x in os.listdir('/dev') \ - if x.startswith(file_prefix)] - return choose_path(possible_paths) - -def windows_get_maple_path(): - """Similar to unix_get_maple_path(), but on Windows.""" - import _winreg as reg - p = 'HARDWARE\\DEVICEMAP\\SERIALCOMM' - k = reg.OpenKey(reg.HKEY_LOCAL_MACHINE, p) - possible_paths = [] - i = 0 - while True: - try: - possible_paths.append(reg.EnumValue(k, i)[1]) - i += 1 - except WindowsError: - break - return choose_path(possible_paths) - -def choose_path(possible_paths): - if len(possible_paths) == 0: - return None - elif len(possible_paths) == 1: - return possible_paths[0] - else: - print 'Found multiple candidates for the Maple device:' - return choose_among_options(possible_paths) - -def choose_among_options(options): - for (i,p) in enumerate(options): - print '\t%d. %s' % (i+1, p) - - prompt = 'Enter a number to select one, or q to quit: ' - while True: - resp = raw_input(prompt).strip().lower() - if resp == 'q': sys.exit() - - try: - i = int(resp, 10) - except ValueError: - pass - else: - if 0 <= i-1 < len(options): - return options[i-1] - - prompt = 'Please enter a number from the list, or q to quit: ' - -plat_sys = platform.system() -plat_bits = platform.architecture()[0] -if plat_sys == 'Linux': - if plat_bits == '64bit': - print 'You appear to be using 64-bit Linux. Let us know if this works.' - maple_path = unix_get_maple_path('ttyACM') - # fall back on /dev/maple if that doesn't work - if maple_path is None: - maple_path = '/dev/maple' - print 'Could not find Maple serial port; defaulting to /dev/maple.' -elif plat_sys == 'Darwin': - maple_path = unix_get_maple_path('tty.usbmodem') -elif plat_sys == 'Windows': - maple_path = windows_get_maple_path() -else: - maple_path = raw_input('Unrecognized platform. Please enter ' - "the path to the Maple's serial port device file:") - -if maple_path is None: - print 'Could not find the Maple serial port for reset.', \ - 'Perhaps this is your first upload, or the board is already', \ - 'in bootloader mode.' - print - print "If your sketch doesn't upload, try putting your Maple", \ - 'into bootloader mode manually by pressing the RESET button', \ - 'then letting it go and quickly pressing button BUT', \ - '(hold for several seconds).' - sys.exit() - -print 'Using %s as Maple serial port' % maple_path - -try: - ser = serial.Serial(maple_path, baudrate=115200, xonxoff=1) - - try: - # try to toggle DTR/RTS (old scheme) - ser.setRTS(0) - time.sleep(0.01) - ser.setDTR(0) - time.sleep(0.01) - ser.setDTR(1) - time.sleep(0.01) - ser.setDTR(0) - - # try magic number - ser.setRTS(1) - time.sleep(0.01) - ser.setDTR(1) - time.sleep(0.01) - ser.setDTR(0) - time.sleep(0.01) - ser.write("1EAF") - - # Windows quirk: delay a bit before proceeding - if plat_sys == 'Windows': time.sleep(0.5) - finally: - # ok we're done here - ser.close() - -except Exception as e: - print 'Failed to open serial port %s for reset' % maple_path - sys.exit() - diff --git a/FastLED/FastLED/Utilities/serial1200.py b/FastLED/FastLED/Utilities/serial1200.py deleted file mode 100755 index 1e482c1c..00000000 --- a/FastLED/FastLED/Utilities/serial1200.py +++ /dev/null @@ -1,13 +0,0 @@ -#!/usr/bin/env python - -import serial -import sys - -if len(sys.argv) < 2: - print "Missing serial port" - sys.exit() - -print 'Setting %s at 1200' % sys.argv[1] - -ser = serial.Serial(sys.argv[1], baudrate=1200) - diff --git a/FastLED/FastLED/main.cpp b/FastLED/FastLED/main.cpp deleted file mode 100644 index dabe2749..00000000 --- a/FastLED/FastLED/main.cpp +++ /dev/null @@ -1,475 +0,0 @@ -// -// main.cpp -// Main file -// ---------------------------------- -// Developed with embedXcode -// http://embedXcode.weebly.com -// -// Project FastLED -// -// Created by Daniel Garcia, 4/2/14 8:09 PM -// Daniel Garcia -// -// Copyright © Daniel Garcia, 2014 -// License <#license#> -// -// See FastLED.ino and ReadMe.txt for references -// -// ---------------------------------- -// DO NOT EDIT THIS FILE. -// THE SKETCH IS IN FastLED.ino -// ---------------------------------- -// -// Last update: Mar 12, 2014 release 139 - -// IDE selection -#if defined(EMBEDXCODE) - -// Sketch -#include "FastLED.ino" - -// Core library and main() -#if defined(MPIDE) -// ============================================================================= chipKIT specific - -//************************************************************************ -//* main.c -//* -//* Arduino core files for PIC32 -//* Copyright (c) 2010, 2011 by Mark Sproul -//* -//* -//************************************************************************ -//* this code is based on code Copyright (c) 2005-2006 David A. Mellis -//* -//* This library is free software; you can redistribute it and/or -//* modify it under the terms of the GNU Lesser General Public -//* License as published by the Free Software Foundation; either -//* version 2.1 of the License, or (at your option) any later version. -//* -//* This library is distributed in the hope that it will be useful, -//* but WITHOUT ANY WARRANTY; without even the implied warranty of -//* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.//* See the GNU -//* Lesser General Public License for more details. -//* -//* You should have received a copy of the GNU Lesser General -//* Public License along with this library; if not, write to the -//* Free Software Foundation, Inc., 59 Temple Place, Suite 330, -//* Boston, MA 02111-1307 USA -//* -//* -//************************************************************************ -//* Edit History -//************************************************************************ -//* Oct 12, 2010 Got MPLAB X working on MacOSX 1.6 for the first time -//* Dec 12, 2011 added call to _scheduleTask() before call -//* to loop(). -//************************************************************************ - -#define OPT_SYSTEM_INTERNAL -#include - -#if (ARDUINO >= 100) -#include -#else -#include -#endif - -extern "C" { - extern void __use_isr_install(void); - __attribute__((section(".comment"))) void (*__use_force_isr_install)(void) = &__use_isr_install; -} - -//************************************************************************ -int main(void) -{ - init(); - - setup(); - - while (1) - { - _scheduleTask(); - loop(); - } - return 0; -} - - -#elif defined(DIGISPARK) -// ============================================================================= Digispark specific - -#include "WProgram.h" - -int main(void) -{ - init(); - - setup(); - - for (;;) - loop(); - - return 0; -} - - - -#elif defined(MICRODUINO) -// ============================================================================= Microduino specific - -#include "Arduino.h" - -int main(void) -{ - init(); - -#if defined(USBCON) - USBDevice.attach(); -#endif - - setup(); - - for (;;) { - loop(); - if (serialEventRun) serialEventRun(); - } - - return 0; -} - - -#elif defined(ENERGIA) -// ============================================================================= LaunchPad MSP430, Stellaris and Tiva, Experimeter Board FR5739 specific - -#if defined(__LM4F120H5QR__) || defined(__TM4C1230C3PM__) || defined(__TM4C129XNCZAD__) -// ----------------------------------------------------------------------------- LaunchPad Stellaris and Tiva specific -#include - -#if defined(PART_TM4C129XNCZAD) -#include "inc/tm4c129xnczad.h" -#elif defined(PART_TM4C1294NCPDT) -#include "inc/tm4c1294ncpdt.h" -#elif defined(PART_TM4C1233H6PM) || defined(PART_LM4F120H5QR) -#include "inc/tm4c123gh6pm.h" -#else -#error "**** No PART defined or unsupported PART ****" -#endif - -#include "inc/hw_gpio.h" -#include "driverlib/rom.h" -#include "driverlib/sysctl.h" -#include "driverlib/eeprom.h" - -int main(void) -{ - - ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_EEPROM0); - if(ROM_EEPROMInit() == EEPROM_INIT_ERROR) { - if(ROM_EEPROMInit() != EEPROM_INIT_ERROR) - EEPROMMassErase(); - } - - timerInit(); - - ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA); - ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB); - ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC); - ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD); - ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE); - ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF); - ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOG); - ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOH); - ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOJ); - ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOK); - ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOL); - ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOM); - ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPION); - ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOP); - ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOQ); -#ifdef TARGET_IS_SNOWFLAKE_RA0 - ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOR); - ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOS); - ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOT); -#endif - - //Unlock and commit NMI pins PD7 and PF0 - HWREG(GPIO_PORTF_BASE + GPIO_O_LOCK) = 0x4C4F434B; - HWREG(GPIO_PORTF_BASE + GPIO_O_CR) |= 0x1; - HWREG(GPIO_PORTD_BASE + GPIO_O_LOCK) = 0x4C4F434B; - HWREG(GPIO_PORTD_BASE + GPIO_O_CR) |= 0x80; - - setup(); - - for (;;) { - loop(); - if (serialEventRun) serialEventRun(); - } - -} - -#else -// ----------------------------------------------------------------------------- LaunchPad MSP430 and Experimeter Board FR5739 specific - -#include - -int main(void) -{ - init(); - - setup(); - - for (;;) { - loop(); - if (serialEventRun) serialEventRun(); - } - - return 0; -} - -#endif // Energia - - -#elif defined(MAPLE_IDE) -// ============================================================================= Maple specific - -// ***************************************************************************** -// The MIT License -// -// Copyright (c) 2010 LeafLabs LLC. -// -// Permission is hereby granted, free of charge, to any person -// obtaining a copy of this software and associated documentation -// files (the "Software"), to deal in the Software without -// restriction, including without limitation the rights to use, copy, -// modify, merge, publish, distribute, sublicense, and/or sell copies -// of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS -// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN -// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// **************************************************************************** - -__attribute__(( constructor )) void premain() { - init(); -} - -int main(void) { - setup(); - - for (;;) - loop(); - - return 0; -} - - -#elif defined(TEENSYDUINO) || defined(CORE_TEENSY) -// ============================================================================= Teensy specific - -#if defined(__MK20DX128__) || defined(__MK20DX256__) -// ----------------------------------------------------------------------------- Teensy 3 specific - -#include "WProgram.h" - -extern "C" int main(void) -{ - // Arduino's main() function just calls setup() and loop().... - setup(); - while (1) { - loop(); - yield(); - } -} - -#else -// ----------------------------------------------------------------------------- Teensy 2 specific - -#include "WProgram.h" - -//int main(void) __attribute__((noreturn)); -int main(void) -{ - _init_Teensyduino_internal_(); - - setup(); - - for (;;) - loop(); -} - - -#endif // Teensy - - -#elif defined(WIRING) -// ============================================================================= Wiring specific - -// Replace #include "WProgram.h" by #include "Wiring.h" -// Comment boardInit(); - -#include "Wiring.h" - -int main(void) -{ - // Hardware specific initializations. - // boardInit(); - init(); - - // User defined setup routine - setup(); - // User defined loop routine - for(;;) - loop(); -} - - -#elif defined(ARDUINO) -// ============================================================================= Arduino specific - -#if (ARDUINO < 100) -// ----------------------------------------------------------------------------- Arduino 0023 specific - -#include "WProgram.h" - -int main(void) -{ - init(); - - setup(); - - for (;;) - loop(); - - return 0; -} - - -#elif (ARDUINO < 150) -// ----------------------------------------------------------------------------- Arduino 1.0x specific - -#include "Arduino.h" - -int main(void) -{ - init(); - -#if defined(USBCON) - USBDevice.attach(); -#endif - - setup(); - - for (;;) { - loop(); - if (serialEventRun) serialEventRun(); - } - - return 0; -} - - -#else -// ----------------------------------------------------------------------------- Arduino 1.5x specific - -#if defined(__SAM3X8E__) -// ............................................................................. Arduino 1.5x SAM architecture specific - -/* - Copyright (c) 2011 Arduino. All rights reserved. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#define ARDUINO_MAIN -#include "Arduino.h" - -/* - * Cortex-M3 Systick IT handler - */ -/* - extern void SysTick_Handler( void ) - { - // Increment tick count each ms - TimeTick_Increment() ; - } - */ - -/* - * \brief Main entry point of Arduino application - */ -int main( void ) -{ - init(); - - delay(1); - -#if defined(USBCON) - USBDevice.attach(); -#endif - - setup(); - - for (;;) - { - loop(); - if (serialEventRun) serialEventRun(); - } - - return 0; -} - -#else -// ............................................................................. Arduino 1.5x AVR architecture specific - -#include "Arduino.h" - -int main(void) -{ - init(); - -#if defined(USBCON) - USBDevice.attach(); -#endif - - setup(); - - for (;;) { - loop(); - if (serialEventRun) serialEventRun(); - } - - return 0; -} - - -#endif // architecture -#endif // Arduino - -#else // error -#error Platform not defined -#endif // end IDE - -#endif // end embedXcode - diff --git a/examples/RGBCalibrate/RGBCalibrate.ino b/examples/RGBCalibrate/RGBCalibrate.ino index 4adf7fbe..897002bf 100644 --- a/examples/RGBCalibrate/RGBCalibrate.ino +++ b/examples/RGBCalibrate/RGBCalibrate.ino @@ -42,8 +42,8 @@ void setup() { // FastLED.addLeds(leds, NUM_LEDS); // FastLED.addLeds(leds, NUM_LEDS); // FastLED.addLeds(leds, NUM_LEDS); - FastLED.addLeds(leds, NUM_LEDS); - FastLED.setBrightness(CRGB(255,255,255)); + // FastLED.addLeds(leds, NUM_LEDS); + // FastLED.setBrightness(CRGB(255,255,255)); // FastLED.addLeds(leds, NUM_LEDS); // FastLED.addLeds(leds, NUM_LEDS); // FastLED.addLeds(leds, NUM_LEDS); @@ -51,7 +51,7 @@ void setup() { // FastLED.addLeds(leds, NUM_LEDS); // FastLED.addLeds(leds, NUM_LEDS); - // FastLED.addLeds(leds, NUM_LEDS); + FastLED.addLeds(leds, NUM_LEDS); // FastLED.addLeds(leds, NUM_LEDS); // FastLED.addLeds(leds, NUM_LEDS); @@ -65,6 +65,9 @@ void loop() { leds[3] = CRGB(0,0,255); leds[4] = CRGB(0,0,255); leds[5] = CRGB(0,0,255); + leds[random8()%NUM_LEDS] = CRGB(0,0,0); + // leds[10] = CRGB(0,0,0); FastLED.show(); // delay(1000); + FastLED.showColor(CRGB::Black); } -- cgit v1.2.3 From 87ab83d13786e42eab9706b419f9db52c360f2d3 Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Thu, 3 Apr 2014 11:28:33 -0700 Subject: Adding a version #define to FastLED so people can condition on versions. --- FastLED.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/FastLED.h b/FastLED.h index 7ce487ca..11d204a9 100644 --- a/FastLED.h +++ b/FastLED.h @@ -4,6 +4,8 @@ // #define NO_CORRECTION 1 // #define NO_DITHERING 1 +#define FASTLED_VERSION 2001000 + #include "controller.h" #include "fastpin.h" #include "fastspi.h" -- cgit v1.2.3 From 46464dbd4d8d570953ee42887b2611b080892382 Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Thu, 3 Apr 2014 12:28:13 -0700 Subject: Fix compiling dc_AVR for chipsets with long delay times in them, e.g. UCS1903 --- clockless_trinket.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clockless_trinket.h b/clockless_trinket.h index 50e49d85..16d3a261 100644 --- a/clockless_trinket.h +++ b/clockless_trinket.h @@ -23,7 +23,7 @@ template inline void _dc_AVR(register uint8_t & 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\tL_%=: DEC %[loopvar]\n\t BRNE L_%=\n\tBSET 0\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) : ); -- cgit v1.2.3 From 24d6cbd995da439356974d8f3e4c2f148f1b89f4 Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Thu, 3 Apr 2014 15:21:09 -0700 Subject: What are betas for if not experimenting? Tossing in a LPD1886 trial --- FastLED.h | 3 +++ chipsets.h | 12 +++++++++++- clockless_trinket.h | 3 --- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/FastLED.h b/FastLED.h index 11d204a9..510caf96 100644 --- a/FastLED.h +++ b/FastLED.h @@ -4,6 +4,8 @@ // #define NO_CORRECTION 1 // #define NO_DITHERING 1 +#define xstr(s) str(s) +#define str(s) #s #define FASTLED_VERSION 2001000 #include "controller.h" @@ -52,6 +54,7 @@ template class WS2811 : public WS2811Control template class WS2811_400 : public WS2811Controller400Khz {}; template class GW6205 : public GW6205Controller800Khz {}; template class GW6205_400 : public GW6205Controller400Khz {}; +template class LPD1886 : public LPD1886Controller1250Khz {}; // template class LPD8806 : public LPD8806Controller {}; // template class WS2801 : public WS2801Controller {}; diff --git a/chipsets.h b/chipsets.h index e1396d72..7cc5b78c 100644 --- a/chipsets.h +++ b/chipsets.h @@ -273,7 +273,11 @@ public: // need the more tightly defined timeframes. #if (F_CPU == 8000000 || F_CPU == 16000000 || F_CPU == 24000000 || F_CPU == 48000000 || F_CPU == 96000000) // 125ns/clock #define FMUL (F_CPU/8000000) -// WS2811@8Mhz 2 clocks, 5 clocks, 3 clocks +// LPD1886 +template +class LPD1886Controller1250Khz : public ClocklessController {}; + +// WS2811@800khz 2 clocks, 5 clocks, 3 clocks template class WS2811Controller800Khz : public ClocklessController {}; @@ -365,6 +369,12 @@ template class TM1829Controller1600Khz : public ClocklessController {}; #if NO_TIME(100, 300, 200) #warning "Not enough clock cycles available for TM1829@1.6Mhz" +#endif + +template +class LPD1886Controller1250Khz : public ClocklessController {}; +#if NO_TIME(200,400,200) +#warning "Not enough clock cycles for LPD1886" #endif #endif diff --git a/clockless_trinket.h b/clockless_trinket.h index 16d3a261..55cd3f2b 100644 --- a/clockless_trinket.h +++ b/clockless_trinket.h @@ -132,9 +132,6 @@ public: : /* clobber registers */ -#define xstr(s) str(s) -#define str(s) #s - // 1 cycle, write hi to the port #define HI1 if((int)(FastPin::port())-0x20 < 64) { asm __volatile__("out %[PORT], %[hi]" ASM_VARS ); } else { *FastPin::port()=hi; } // 1 cycle, write lo to the port -- cgit v1.2.3 From 161a3f06b2f07f654a13b9343442a228574976f2 Mon Sep 17 00:00:00 2001 From: Mark Kriegsman Date: Mon, 7 Apr 2014 23:29:21 -0400 Subject: Fixing scale8_video( {X>0}, 0) --- lib8tion.h | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/lib8tion.h b/lib8tion.h index a2e70fe4..74b8580f 100644 --- a/lib8tion.h +++ b/lib8tion.h @@ -484,18 +484,21 @@ LIB8STATIC uint8_t scale8( uint8_t i, fract8 scale) LIB8STATIC uint8_t scale8_video( uint8_t i, fract8 scale) { #if SCALE8_C == 1 || defined(LIB8_ATTINY) - uint8_t j = (((int)i * (int)scale) >> 8) + (i?1:0); + uint8_t j = (((int)i * (int)scale) >> 8) + ((i&&scale)?1:0); // uint8_t nonzeroscale = (scale != 0) ? 1 : 0; // uint8_t j = (i == 0) ? 0 : (((int)i * (int)(scale) ) >> 8) + nonzeroscale; return j; #elif SCALE8_AVRASM == 1 uint8_t j=0; asm volatile( - "mul %[i], %[scale]\n\t" - "mov %[j], r1\n\t" - "clr __zero_reg__\n\t" - "cpse %[i], r1\n\t" - "subi %[j], 0xFF\n\t" + " tst %[i]\n\t" + " breq L_%=\n\t" + " mul %[i], %[scale]\n\t" + " mov %[j], r1\n\t" + " clr __zero_reg__\n\t" + " cpse %[scale], r1\n\t" + " subi %[j], 0xFF\n\t" + "L_%=: \n\t" : [j] "+a" (j) : [i] "a" (i), [scale] "a" (scale) : "r0", "r1"); -- cgit v1.2.3 From 7d335a7e938d69e478d109393b48626bb786eaa5 Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Tue, 8 Apr 2014 12:55:07 -0700 Subject: Clean up sam clockless code, hopefully improving accuracy on it. --- FastLED.cpp | 6 ++- chipsets.h | 2 +- clockless_arm_sam.h | 105 +++++++++++++++++----------------------------------- 3 files changed, 40 insertions(+), 73 deletions(-) diff --git a/FastLED.cpp b/FastLED.cpp index 30b31cf2..0c10a2a7 100644 --- a/FastLED.cpp +++ b/FastLED.cpp @@ -64,7 +64,11 @@ void CFastLED::clearData() { void CFastLED::delay(unsigned long ms) { unsigned long start = millis(); - while((millis()-start) < ms) { show(); } + while((millis()-start) < ms) { + show(); + + } + } void CFastLED::setTemperature(const struct CRGB & temp) { diff --git a/chipsets.h b/chipsets.h index 7cc5b78c..2b59916e 100644 --- a/chipsets.h +++ b/chipsets.h @@ -371,7 +371,7 @@ class TM1829Controller1600Khz : public ClocklessController +template class LPD1886Controller1250Khz : public ClocklessController {}; #if NO_TIME(200,400,200) #warning "Not enough clock cycles for LPD1886" diff --git a/clockless_arm_sam.h b/clockless_arm_sam.h index fb0be86f..1e056be7 100644 --- a/clockless_arm_sam.h +++ b/clockless_arm_sam.h @@ -7,7 +7,7 @@ #if defined(__SAM3X8E__) -#define TADJUST 4 +#define TADJUST 0 #define TOTAL ( (T1+TADJUST) + (T2+TADJUST) + (T3+TADJUST) ) #define T1_MARK (TOTAL - (T1+TADJUST)) #define T2_MARK (T1_MARK - (T2+TADJUST)) @@ -63,10 +63,10 @@ public: // Serial.print(scale.raw[1]); Serial.print(" "); // Serial.print(scale.raw[2]); Serial.println(" "); // FastPinBB::hi(); delay(1); FastPinBB::lo(); - showRGBInternal(pixels); + uint32_t clocks = showRGBInternal(pixels); // Adjust the timer - long microsTaken = nLeds * CLKS_TO_MICROS(24 * (TOTAL)); + long microsTaken = nLeds * CLKS_TO_MICROS(clocks); long millisTaken = (microsTaken / 1000); savedClock.restore(); do { TimeTick_Increment(); } while(--millisTaken > 0); @@ -81,10 +81,10 @@ public: cli(); SysClockSaver savedClock(TOTAL); - showRGBInternal(pixels); + uint32_t clocks = showRGBInternal(pixels); // Adjust the timer - long microsTaken = nLeds * CLKS_TO_MICROS(24 * (TOTAL)); + long microsTaken = nLeds * CLKS_TO_MICROS(clocks); long millisTaken = (microsTaken / 1000); savedClock.restore(); do { TimeTick_Increment(); } while(--millisTaken > 0); @@ -150,69 +150,38 @@ public: #define _CTRL CTPTR[0] #define _LOAD CTPTR[1] #define _VAL CTPTR[2] +#define VAL *((uint32_t*)(SysTick_BASE + 8)) - __attribute__((always_inline)) static inline void wait_loop_start(register volatile uint32_t *CTPTR) { - __asm__ __volatile__ ( - "L_%=: ldr.w r8, [%0]\n" - " tst.w r8, #65536\n" - " beq.n L_%=\n" - : /* no outputs */ - : "r" (CTPTR) - : "r8" - ); - } - - template __attribute__((always_inline)) static inline void wait_loop_mark(register volatile uint32_t *CTPTR) { - __asm__ __volatile__ ( - "L_%=: ldr.w r8, [%0, #8]\n" - " cmp.w r8, %1\n" - " bhi.n L_%=\n" - : /* no outputs */ - : "r" (CTPTR), "I" (MARK) - : "r8" - ); - } - - __attribute__((always_inline)) static inline void mark_port(register data_ptr_t port, register int val) { - __asm__ __volatile__ ( - " str.w %0, [%1]\n" - : /* no outputs */ - : "r" (val), "r" (port) - ); - } -#define AT_BIT_START(X) wait_loop_start(CTPTR); X; -#define AT_MARK(X) wait_loop_mark(CTPTR); { X; } -#define AT_END(X) wait_loop_mark(CTPTR); { X; } - - template __attribute__((always_inline)) static inline void delayclocks_until(register byte b) { - __asm__ __volatile__ ( - " sub %0, %0, %1\n" - "L_%=: subs %0, %0, #2\n" - " bcs.n L_%=\n" - : /* no outputs */ - : "r" (b), "I" (MARK) - : /* no clobbers */ - ); - - } - - - template __attribute__ ((always_inline)) inline static void writeBits(register volatile uint32_t *CTPTR, register data_ptr_t port, register uint8_t & b) { - // TODO: hand rig asm version of this method. The timings are based on adjusting/studying GCC compiler ouptut. This - // will bite me in the ass at some point, I know it. + template __attribute__ ((always_inline)) inline static void writeBits(register uint32_t & next_mark, register data_ptr_t port, register uint8_t & b) { for(register uint32_t i = BITS; i > 0; i--) { - AT_BIT_START(*port=1); - if(b&0x80) {} else { AT_MARK(*port=0); } + // wait to start the bit, then set the pin high + while(VAL > next_mark); + next_mark = (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((VAL - next_mark) > (T3+TADJUST)); + } else { + // we're a 0, wait until there's less than (T2+T3+slop) clocks left in this bit + while((VAL-next_mark) > (T2+T3+TADJUST+TADJUST)); + } + *port=0; b <<= 1; - AT_END(*port=0); } } #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 void showRGBInternal(PixelController & pixels) { - // Serial.print("Going to show "); Serial.print(pixels.mLen); Serial.println(" pixels."); + static uint32_t showRGBInternal(PixelController & pixels) { + // Setup and start the clock + register volatile uint32_t *CTPTR asm("r6")= &SysTick->CTRL; FORCE_REFERENCE(CTPTR); + _LOAD = 0x00FFFFFF; + _VAL = 0; + _CTRL |= SysTick_CTRL_CLKSOURCE_Msk; + _CTRL |= SysTick_CTRL_ENABLE_Msk; register data_ptr_t port asm("r7") = FastPinBB::port(); FORCE_REFERENCE(port); *port = 0; @@ -221,28 +190,22 @@ public: pixels.preStepFirstByteDithering(); register uint8_t b = pixels.loadAndScale0(); - // Setup and start the clock - register volatile uint32_t *CTPTR asm("r6")= &SysTick->CTRL; FORCE_REFERENCE(CTPTR); - _LOAD = TOTAL; - _VAL = 0; - _CTRL |= SysTick_CTRL_CLKSOURCE_Msk; - _CTRL |= SysTick_CTRL_ENABLE_Msk; - - // read to clear the loop flag - _CTRL; + uint32_t next_mark = (VAL - (TOTAL)); while(pixels.has(1)) { pixels.stepDithering(); - writeBits<8+XTRA0>(CTPTR, port, b); + writeBits<8+XTRA0>(next_mark, port, b); b = pixels.loadAndScale1(); - writeBits<8+XTRA0>(CTPTR, port,b); + writeBits<8+XTRA0>(next_mark, port,b); b = pixels.loadAndScale2(); - writeBits<8+XTRA0>(CTPTR, port,b); + writeBits<8+XTRA0>(next_mark, port,b); b = pixels.advanceAndLoadAndScale0(); }; + + return 0x00FFFFFF - _VAL; } #endif }; -- cgit v1.2.3 From 77a916df1130fec60c85caedc2ae624666001d99 Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Tue, 8 Apr 2014 20:35:24 -0700 Subject: Improve timing adjustments for the teensy3 clockless chips. --- clockless_arm_k20.h | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/clockless_arm_k20.h b/clockless_arm_k20.h index 4abf0e9a..68c2f013 100644 --- a/clockless_arm_k20.h +++ b/clockless_arm_k20.h @@ -30,10 +30,10 @@ public: mWait.wait(); cli(); - showRGBInternal(pixels); + uint32_t clocks = showRGBInternal(pixels); // Adjust the timer - long microsTaken = nLeds * CLKS_TO_MICROS(24 * (T1 + T2 + T3 + 1)); + long microsTaken = nLeds * CLKS_TO_MICROS(clocks); MS_COUNTER += (microsTaken / 1000); sei(); mWait.mark(); @@ -45,10 +45,10 @@ public: mWait.wait(); cli(); - showRGBInternal(pixels); + uint32_t clocks = showRGBInternal(pixels); // Adjust the timer - long microsTaken = nLeds * CLKS_TO_MICROS(24 * (T1 + T2 + T3 + 1)); + long microsTaken = nLeds * CLKS_TO_MICROS(clocks); MS_COUNTER += (microsTaken / 1000); sei(); mWait.mark(); @@ -60,11 +60,11 @@ public: mWait.wait(); cli(); - showRGBInternal(pixels); + uint32_t clocks = showRGBInternal(pixels); // Adjust the timer - long microsTaken = nLeds * CLKS_TO_MICROS(24 * (T1 + T2 + T3 + 1)); + long microsTaken = nLeds * CLKS_TO_MICROS(clocks); MS_COUNTER += (microsTaken / 1000); sei(); mWait.mark(); @@ -101,7 +101,12 @@ public: // 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 showRGBInternal(PixelController & pixels) { + static uint32_t showRGBInternal(PixelController & 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::port(); register data_t hi = *port | FastPin::mask();; register data_t lo = *port & ~FastPin::mask();; @@ -111,10 +116,6 @@ public: pixels.preStepFirstByteDithering(); register uint8_t b = pixels.loadAndScale0(); - // Get access to the clock - ARM_DEMCR |= ARM_DEMCR_TRCENA; - ARM_DWT_CTRL |= ARM_DWT_CTRL_CYCCNTENA; - ARM_DWT_CYCCNT = 0; uint32_t next_mark = ARM_DWT_CYCCNT + (T1+T2+T3); while(pixels.has(1)) { @@ -132,6 +133,8 @@ public: writeBits<8+XTRA0>(next_mark, port, hi, lo, b); b = pixels.advanceAndLoadAndScale0(); }; + + return ARM_DWT_CYCCNT; } }; #endif -- cgit v1.2.3 From 0c00d948804c682379d2dbdefd6bac069508723a Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Tue, 8 Apr 2014 21:03:47 -0700 Subject: Add support for the second hardware SPI port on the teensy 3.1 --- fastpin_arm_k20.h | 8 +++++ fastspi.h | 8 ++++- fastspi_arm_k20.h | 98 ++++++++++++++++++++++++++++++------------------------- 3 files changed, 68 insertions(+), 46 deletions(-) diff --git a/fastpin_arm_k20.h b/fastpin_arm_k20.h index 0eaa11d6..71bddde3 100644 --- a/fastpin_arm_k20.h +++ b/fastpin_arm_k20.h @@ -90,6 +90,14 @@ _DEFPIN_ARM(32, 18, B); _DEFPIN_ARM(33, 4, A); #define SPI_DATA 11 #define SPI_CLOCK 13 +#define SPI1 (*(SPI_t *)0x4002D000) + +#if defined(__MK20DX256__) +#define SPI2_DATA 7 +#define SPI2_CLOCK 14 +#endif + +#define FASTLED_TEENSY3 #define ARM_HARDWARE_SPI #define HAS_HARDWARE_PIN_SUPPORT #endif diff --git a/fastspi.h b/fastspi.h index 68d74a99..d6a73352 100644 --- a/fastspi.h +++ b/fastspi.h @@ -66,7 +66,13 @@ class SoftwareSPIOutput : public AVRSoftwareSPIOutput<_DATA_PIN, _CLOCK_PIN, _SP #if defined(FASTLED_TEENSY3) && defined(CORE_TEENSY) template -class SPIOutput : public ARMHardwareSPIOutput {}; +class SPIOutput : public ARMHardwareSPIOutput {}; + +#if defined(SPI2_DATA) + +template +class SPIOutput : public ARMHardwareSPIOutput {}; +#endif #elif defined(__SAM3X8E__) diff --git a/fastspi_arm_k20.h b/fastspi_arm_k20.h index dba602a7..f8004331 100644 --- a/fastspi_arm_k20.h +++ b/fastspi_arm_k20.h @@ -5,11 +5,11 @@ #if defined(FASTLED_TEENSY3) && defined(CORE_TEENSY) #ifndef SPI_PUSHR_CONT -#define SPI_PUSHR_CONT SPI0_PUSHR_CONT -#define SPI_PUSHR_CTAS(X) SPI0_PUSHR_CTAS(X) -#define SPI_PUSHR_EOQ SPI0_PUSHR_EOQ -#define SPI_PUSHR_CTCNT SPI0_PUSHR_CTCNT -#define SPI_PUSHR_PCS(X) SPI0_PUSHR_PCS(X) +#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, @@ -74,8 +74,9 @@ template void getScalars(uint32_t & preScalar, uint32_t & scalar, uint return; } +#define SPIX (*(SPI_t*)pSPIX) -template +template class ARMHardwareSPIOutput { Selectable *m_pSelect; @@ -101,27 +102,27 @@ public: void setSelect(Selectable *pSelect) { m_pSelect = pSelect; } static inline void update_ctar0(uint32_t ctar) __attribute__((always_inline)) { - if (SPI0_CTAR0 == ctar) return; - uint32_t mcr = SPI0_MCR; + if (SPIX.CTAR0 == ctar) return; + uint32_t mcr = SPIX.MCR; if (mcr & SPI_MCR_MDIS) { - SPI0_CTAR0 = ctar; + SPIX.CTAR0 = ctar; } else { - SPI0_MCR = mcr | SPI_MCR_MDIS | SPI_MCR_HALT; - SPI0_CTAR0 = ctar; + SPIX.MCR = mcr | SPI_MCR_MDIS | SPI_MCR_HALT; + SPIX.CTAR0 = ctar; - SPI0_MCR = mcr; + SPIX.MCR = mcr; } } static inline void update_ctar1(uint32_t ctar) __attribute__((always_inline)) { - if (SPI0_CTAR1 == ctar) return; - uint32_t mcr = SPI0_MCR; + if (SPIX.CTAR1 == ctar) return; + uint32_t mcr = SPIX.MCR; if (mcr & SPI_MCR_MDIS) { - SPI0_CTAR1 = ctar; + SPIX.CTAR1 = ctar; } else { - SPI0_MCR = mcr | SPI_MCR_MDIS | SPI_MCR_HALT; - SPI0_CTAR1 = ctar; - SPI0_MCR = mcr; + SPIX.MCR = mcr | SPI_MCR_MDIS | SPI_MCR_HALT; + SPIX.CTAR1 = ctar; + SPIX.MCR = mcr; } } @@ -174,30 +175,37 @@ public: // Enable SPI0 clock uint32_t sim6 = SIM_SCGC6; - if (!(sim6 & SIM_SCGC6_SPI0)) { - //serial_print("init1\n"); - SIM_SCGC6 = sim6 | SIM_SCGC6_SPI0; - SPI0_CTAR0 = SPI_CTAR_FMSZ(7) | SPI_CTAR_PBR(1) | SPI_CTAR_BR(1); + if((SPI_t*)pSPIX == &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); + } } - setSPIRate(); // Configure SPI as the master and enable - SPI0_MCR |= SPI_MCR_MSTR; // | SPI_MCR_CONT_SCKE); - SPI0_MCR &= ~(SPI_MCR_MDIS | SPI_MCR_HALT); + SPIX.MCR |= SPI_MCR_MSTR; // | SPI_MCR_CONT_SCKE); + SPIX.MCR &= ~(SPI_MCR_MDIS | SPI_MCR_HALT); enable_pins(); } static void waitFully() __attribute__((always_inline)) { - while( (SPI0_SR & 0xF000) > 0); - while (!(SPI0_SR & SPI_SR_TCF)); - SPI0_SR |= (SPI_SR_TCF | SPI_SR_EOQF); + while( (SPIX.SR & 0xF000) > 0); + while (!(SPIX.SR & SPI_SR_TCF)); + SPIX.SR |= (SPI_SR_TCF | SPI_SR_EOQF); } - static bool needwait() __attribute__((always_inline)) { return (SPI0_SR & 0x4000); } - static void wait() __attribute__((always_inline)) { while( (SPI0_SR & 0x4000) ); } - static void wait1() __attribute__((always_inline)) { while( (SPI0_SR & 0xF000) >= 0x2000); } + 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 }; @@ -214,7 +222,7 @@ public: public: static void writeWord(uint16_t w) __attribute__((always_inline)) { if(WAIT_STATE == PRE) { wait(); } - SPI0_PUSHR = ((LAST_STATE == LAST) ? SPI_PUSHR_EOQ : 0) | + SPIX.PUSHR = ((LAST_STATE == LAST) ? SPI_PUSHR_EOQ : 0) | ((CONT_STATE == CONT) ? SPI_PUSHR_CONT : 0) | SPI_PUSHR_CTAS(1) | (w & 0xFFFF); if(WAIT_STATE == POST) { wait(); } @@ -222,30 +230,30 @@ public: static void writeByte(uint8_t b) __attribute__((always_inline)) { if(WAIT_STATE == PRE) { wait(); } - SPI0_PUSHR = ((LAST_STATE == LAST) ? SPI_PUSHR_EOQ : 0) | + SPIX.PUSHR = ((LAST_STATE == LAST) ? SPI_PUSHR_EOQ : 0) | ((CONT_STATE == CONT) ? SPI_PUSHR_CONT : 0) | SPI_PUSHR_CTAS(0) | (b & 0xFF); if(WAIT_STATE == POST) { wait(); } } }; - static void writeWord(uint16_t w) __attribute__((always_inline)) { wait(); SPI0_PUSHR = SPI_PUSHR_CTAS(1) | (w & 0xFFFF); } - static void writeWordNoWait(uint16_t w) __attribute__((always_inline)) { SPI0_PUSHR = SPI_PUSHR_CTAS(1) | (w & 0xFFFF); } + static void writeWord(uint16_t w) __attribute__((always_inline)) { wait(); SPIX.PUSHR = SPI_PUSHR_CTAS(1) | (w & 0xFFFF); } + static void writeWordNoWait(uint16_t w) __attribute__((always_inline)) { SPIX.PUSHR = SPI_PUSHR_CTAS(1) | (w & 0xFFFF); } - static void writeByte(uint8_t b) __attribute__((always_inline)) { wait(); SPI0_PUSHR = SPI_PUSHR_CTAS(0) | (b & 0xFF); } - static void writeBytePostWait(uint8_t b) __attribute__((always_inline)) { SPI0_PUSHR = SPI_PUSHR_CTAS(0) | (b & 0xFF); wait(); } - static void writeByteNoWait(uint8_t b) __attribute__((always_inline)) { SPI0_PUSHR = SPI_PUSHR_CTAS(0) | (b & 0xFF); } + static void writeByte(uint8_t b) __attribute__((always_inline)) { wait(); SPIX.PUSHR = SPI_PUSHR_CTAS(0) | (b & 0xFF); } + static void writeBytePostWait(uint8_t b) __attribute__((always_inline)) { SPIX.PUSHR = SPI_PUSHR_CTAS(0) | (b & 0xFF); wait(); } + static void writeByteNoWait(uint8_t b) __attribute__((always_inline)) { SPIX.PUSHR = SPI_PUSHR_CTAS(0) | (b & 0xFF); } - static void writeWordCont(uint16_t w) __attribute__((always_inline)) { wait(); SPI0_PUSHR = SPI_PUSHR_CONT | SPI_PUSHR_CTAS(1) | (w & 0xFFFF); } - static void writeWordContNoWait(uint16_t w) __attribute__((always_inline)) { SPI0_PUSHR = SPI_PUSHR_CONT | SPI_PUSHR_CTAS(1) | (w & 0xFFFF); } + static void writeWordCont(uint16_t w) __attribute__((always_inline)) { wait(); SPIX.PUSHR = SPI_PUSHR_CONT | SPI_PUSHR_CTAS(1) | (w & 0xFFFF); } + static void writeWordContNoWait(uint16_t w) __attribute__((always_inline)) { SPIX.PUSHR = SPI_PUSHR_CONT | SPI_PUSHR_CTAS(1) | (w & 0xFFFF); } - static void writeByteCont(uint8_t b) __attribute__((always_inline)) { wait(); SPI0_PUSHR = SPI_PUSHR_CONT | SPI_PUSHR_CTAS(0) | (b & 0xFF); } - static void writeByteContPostWait(uint8_t b) __attribute__((always_inline)) { SPI0_PUSHR = SPI_PUSHR_CONT | SPI_PUSHR_CTAS(0) | (b & 0xFF); wait(); } - static void writeByteContNoWait(uint8_t b) __attribute__((always_inline)) { SPI0_PUSHR = SPI_PUSHR_CONT | SPI_PUSHR_CTAS(0) | (b & 0xFF); } + static void writeByteCont(uint8_t b) __attribute__((always_inline)) { wait(); SPIX.PUSHR = SPI_PUSHR_CONT | SPI_PUSHR_CTAS(0) | (b & 0xFF); } + static void writeByteContPostWait(uint8_t b) __attribute__((always_inline)) { SPIX.PUSHR = SPI_PUSHR_CONT | SPI_PUSHR_CTAS(0) | (b & 0xFF); wait(); } + static void writeByteContNoWait(uint8_t b) __attribute__((always_inline)) { SPIX.PUSHR = SPI_PUSHR_CONT | SPI_PUSHR_CTAS(0) | (b & 0xFF); } // not the most efficient mechanism in the world - but should be enough for sm16716 and friends template inline static void writeBit(uint8_t b) { - uint32_t ctar1_save = SPI0_CTAR1; + 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); @@ -324,7 +332,7 @@ public: D::postBlock(len); waitFully(); } else if(FLAGS & FLAG_START_BIT) { - uint32_t ctar1_save = SPI0_CTAR1; + 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); -- cgit v1.2.3 From 347daba55d773aac94a081f11592a74738026c0b Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Tue, 8 Apr 2014 21:31:14 -0700 Subject: Updating the changes.txt file --- preview_changes.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/preview_changes.txt b/preview_changes.txt index 1b6060b5..af422871 100644 --- a/preview_changes.txt +++ b/preview_changes.txt @@ -2,6 +2,7 @@ * RGB based scaling, allow for color balancing * (The moon) dithering support * Teensy 3.1 support +* Second SPI support on teensy 3.1 * Due support * P9813 (aka Cool Neon Total Control Lighting support) * Preliminary TM1829 support (broken, don't use!) -- cgit v1.2.3 From cacf500932886ff8a6e22d46d2f49c389f47bd75 Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Wed, 9 Apr 2014 10:58:13 -0700 Subject: Try to block compiler optimizations on SysTick access --- clockless_arm_sam.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clockless_arm_sam.h b/clockless_arm_sam.h index 1e056be7..3a7cb108 100644 --- a/clockless_arm_sam.h +++ b/clockless_arm_sam.h @@ -150,7 +150,7 @@ public: #define _CTRL CTPTR[0] #define _LOAD CTPTR[1] #define _VAL CTPTR[2] -#define VAL *((uint32_t*)(SysTick_BASE + 8)) +#define VAL (volatile uint32_t)(*((uint32_t*)(SysTick_BASE + 8))) template __attribute__ ((always_inline)) inline static void writeBits(register uint32_t & next_mark, register data_ptr_t port, register uint8_t & b) { for(register uint32_t i = BITS; i > 0; i--) { -- cgit v1.2.3 From 45cd8d8148d492f350ebbcc74a5e9dafcf625618 Mon Sep 17 00:00:00 2001 From: Mark Kriegsman Date: Wed, 9 Apr 2014 21:09:14 -0400 Subject: Made 'number of virtual bits' of dithering configurable (see VIRTUAL_BITS), current value of '8' should exactly match the previous non-configurable behavior. Next step might be exposing this value via API. I suspect ultimately the correct default might be 3 or 4. --- controller.h | 52 +++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 39 insertions(+), 13 deletions(-) diff --git a/controller.h b/controller.h index 35c02d08..6a3660d6 100644 --- a/controller.h +++ b/controller.h @@ -201,11 +201,24 @@ struct PixelController { void init_binary_dithering() { #if !defined(NO_DITHERING) || (NO_DITHERING != 1) - static byte R = 0; - R++; - - // fast reverse bits in a byte - byte Q = 0; + +#define VIRTUAL_BITS 8 + // R is the digther signal 'counter'. + static byte R = 0; + R++; + + // R is wrapped around at 2^ditherBits, + // so if ditherBits is 2, R will cycle through (0,1,2,3) + byte ditherBits = VIRTUAL_BITS; + R &= (0x01 << ditherBits) - 1; + + // Q is the "unscaled dither signal" itself. + // It's initialized to the reversed bits of R. + // If 'ditherBits' is 2, Q here will cycle through (0,128,64,192) + byte Q = 0; + + // Reverse bits in a byte + { if(R & 0x01) { Q |= 0x80; } if(R & 0x02) { Q |= 0x40; } if(R & 0x04) { Q |= 0x20; } @@ -214,14 +227,27 @@ struct PixelController { if(R & 0x20) { Q |= 0x04; } if(R & 0x40) { Q |= 0x02; } if(R & 0x80) { Q |= 0x01; } - - // setup the seed d and e values - for(int i = 0; i < 3; i++) { - byte s = mScale.raw[i]; - e[i] = s ? (256/s) + 1 : 0; - d[i] = scale8(Q, e[i]); - if(e[i]) e[i]--; - } + } + + // Now we adjust Q to fall in the center of each range, + // instead of at the start of the range. + // If ditherBits is 2, Q will be (0, 128, 64, 192) at first, + // and this adjustment makes it (31, 159, 95, 223). + if( ditherBits < 8) { + Q += 0x01 << (7 - ditherBits); + } + + // D and E form the "scaled dither signal" + // which is added to pixel values to affect the + // actual dithering. + + // Setup the initial D and E values + for(int i = 0; i < 3; i++) { + byte s = mScale.raw[i]; + e[i] = s ? (256/s) + 1 : 0; + d[i] = scale8(Q, e[i]); + if(e[i]) e[i]--; + } #endif } -- cgit v1.2.3 From 3d55f51897d322251c99ccd0dbe061728de72e4a Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Tue, 15 Apr 2014 22:12:26 -0700 Subject: Fix issue #48 - tweak timing on UDOO - appears to handle better and bring it in line with the digix/due. --- clockless_arm_sam.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/clockless_arm_sam.h b/clockless_arm_sam.h index 3a7cb108..bbf7e1b1 100644 --- a/clockless_arm_sam.h +++ b/clockless_arm_sam.h @@ -162,10 +162,10 @@ public: // 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((VAL - next_mark) > (T3+TADJUST)); + while((VAL - next_mark) > (T3)); } else { // we're a 0, wait until there's less than (T2+T3+slop) clocks left in this bit - while((VAL-next_mark) > (T2+T3+TADJUST+TADJUST)); + while((VAL-next_mark) > (T2+T3+4+TADJUST+TADJUST)); } *port=0; b <<= 1; -- cgit v1.2.3 From 0ccf71703c1d09bfeb8dfa0fd1ac3f2bf05e9fc6 Mon Sep 17 00:00:00 2001 From: Mark Kriegsman Date: Thu, 17 Apr 2014 15:41:58 -0400 Subject: Changing names to TypicalFoo --- color.h | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/color.h b/color.h index 1b40cec5..17d1b20a 100644 --- a/color.h +++ b/color.h @@ -7,14 +7,17 @@ typedef enum { // Color correction starting points // typical values for SMD5050 LEDs - SMD5050=0xFFA0F0 /* 255, 160, 240 */, - - // typical values for 8.25mm "pixels on a string" - // also for many through-hole T3 package LEDs - Pixel8MM=0xFFE08C /* 255, 224, 140 */, - + TypicalSMD5050=0xFFB0F0 /* 255, 176, 240 */, + TypicalLEDStrip=0xFFB0F0 /* 255, 176, 240 */, + + // typical values for 8mm "pixels on a string" + // also for many through-hole 'T' package LEDs + Typical8mmPixel=0xFFE08C /* 255, 224, 140 */, + TypicalPixelString=0xFFE08C /* 255, 224, 140 */, + // uncorrected color UncorrectedColor=0xFFFFFF + } LEDColorCorrection; -- cgit v1.2.3 From b4e0011a98273590dfdf74f168cac23078eb7f41 Mon Sep 17 00:00:00 2001 From: Mark Kriegsman Date: Thu, 17 Apr 2014 15:44:21 -0400 Subject: Added HUE_RED, etc. as defined enum constants. --- pixeltypes.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/pixeltypes.h b/pixeltypes.h index 663c37bd..279b2055 100644 --- a/pixeltypes.h +++ b/pixeltypes.h @@ -67,6 +67,16 @@ struct CHSV { } }; +typedef enum { + HUE_RED = 0, + HUE_ORANGE = 32, + HUE_YELLOW = 64, + HUE_GREEN = 96, + HUE_AQUA = 128, + HUE_BLUE = 160, + HUE_PURPLE = 192, + HUE_PINK = 224 +} HSVHue; struct CRGB { union { -- cgit v1.2.3 From fb4497bc456866752ec1424b7afb3426e6f042ce Mon Sep 17 00:00:00 2001 From: Mark Kriegsman Date: Thu, 17 Apr 2014 15:52:41 -0400 Subject: Updated preview_changes.txt --- preview_changes.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/preview_changes.txt b/preview_changes.txt index af422871..6955e218 100644 --- a/preview_changes.txt +++ b/preview_changes.txt @@ -7,3 +7,6 @@ * P9813 (aka Cool Neon Total Control Lighting support) * Preliminary TM1829 support (broken, don't use!) * Random code changes and cleanups + +* Added HUE_RED, HUE_ORANGE, etc. +* Added named color correction profiles (eg. TypicalSMD5050) -- cgit v1.2.3 From e98cfa2061a06c8c9a2d72a2dc953dd5ab770c11 Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Thu, 17 Apr 2014 13:06:23 -0700 Subject: Fix the timing adjustments in k20 and sam clockless code. --- clockless_arm_k20.h | 31 +++++++++++++++---------------- clockless_arm_sam.h | 46 +++++++++++++++++++++++----------------------- 2 files changed, 38 insertions(+), 39 deletions(-) diff --git a/clockless_arm_k20.h b/clockless_arm_k20.h index 68c2f013..83080db9 100644 --- a/clockless_arm_k20.h +++ b/clockless_arm_k20.h @@ -13,7 +13,7 @@ class ClocklessController : public CLEDController { data_ptr_t mPort; CMinWait mWait; public: - virtual void init() { + virtual void init() { FastPin::setOutput(); mPinMask = FastPin::mask(); mPort = FastPin::port(); @@ -33,38 +33,38 @@ public: uint32_t clocks = showRGBInternal(pixels); // Adjust the timer - long microsTaken = nLeds * CLKS_TO_MICROS(clocks); + long microsTaken = CLKS_TO_MICROS(clocks); MS_COUNTER += (microsTaken / 1000); sei(); mWait.mark(); } - virtual void show(const struct CRGB *rgbdata, int nLeds, CRGB scale) { + virtual void show(const struct CRGB *rgbdata, int nLeds, CRGB scale) { PixelController pixels(rgbdata, nLeds, scale, getDither()); mWait.wait(); cli(); uint32_t clocks = showRGBInternal(pixels); - + // Adjust the timer - long microsTaken = nLeds * CLKS_TO_MICROS(clocks); + long microsTaken = CLKS_TO_MICROS(clocks); MS_COUNTER += (microsTaken / 1000); sei(); mWait.mark(); } #ifdef SUPPORT_ARGB - virtual void show(const struct CARGB *rgbdata, int nLeds, CRGB scale) { + virtual void show(const struct CARGB *rgbdata, int nLeds, CRGB scale) { PixelController pixels(rgbdata, nLeds, scale, getDither()); mWait.wait(); cli(); uint32_t clocks = showRGBInternal(pixels); - + // Adjust the timer - long microsTaken = nLeds * CLKS_TO_MICROS(clocks); + long microsTaken = CLKS_TO_MICROS(clocks); MS_COUNTER += (microsTaken / 1000); sei(); mWait.mark(); @@ -72,11 +72,11 @@ public: #endif template __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--) { + 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::fastset(port, hi); - if(b&0x80) { + if(b&0x80) { while((next_mark - ARM_DWT_CYCCNT) > T3); FastPin::fastset(port, lo); } else { @@ -90,7 +90,7 @@ public: next_mark = ARM_DWT_CYCCNT + (T1+T2+T3); FastPin::fastset(port, hi); - if(b&0x80) { + if(b&0x80) { while((next_mark - ARM_DWT_CYCCNT) > T3); FastPin::fastset(port, lo); } else { @@ -99,10 +99,10 @@ public: } } - // This method is made static to force making register Y available to use for data on AVR - if the method is non-static, then + // 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 & pixels) { - // Get access to the clock + // Get access to the clock ARM_DEMCR |= ARM_DEMCR_TRCENA; ARM_DWT_CTRL |= ARM_DWT_CTRL_CYCCNTENA; ARM_DWT_CYCCNT = 0; @@ -112,13 +112,13 @@ public: register data_t lo = *port & ~FastPin::mask();; *port = lo; - // Setup the pixel controller and load/scale the first byte + // Setup the pixel controller and load/scale the first byte pixels.preStepFirstByteDithering(); register uint8_t b = pixels.loadAndScale0(); uint32_t next_mark = ARM_DWT_CYCCNT + (T1+T2+T3); - while(pixels.has(1)) { + while(pixels.has(1)) { pixels.stepDithering(); // Write first byte, read next byte @@ -140,4 +140,3 @@ public: #endif #endif - diff --git a/clockless_arm_sam.h b/clockless_arm_sam.h index bbf7e1b1..d71e8162 100644 --- a/clockless_arm_sam.h +++ b/clockless_arm_sam.h @@ -24,7 +24,7 @@ class ClocklessController : public CLEDController { data_ptr_t mPort; CMinWait mWait; public: - virtual void init() { + virtual void init() { FastPinBB::setOutput(); mPinMask = FastPinBB::mask(); mPort = FastPinBB::port(); @@ -41,10 +41,10 @@ public: cli(); SysClockSaver savedClock(TOTAL); - showRGBInternal(pixels); + uint32_t clocks = showRGBInternal(pixels); // Adjust the timer - long microsTaken = nLeds * CLKS_TO_MICROS(24 * (TOTAL)); + long microsTaken = CLKS_TO_MICROS(clocks); long millisTaken = (microsTaken / 1000); savedClock.restore(); do { TimeTick_Increment(); } while(--millisTaken > 0); @@ -52,13 +52,13 @@ public: mWait.mark(); } - virtual void show(const struct CRGB *rgbdata, int nLeds, CRGB scale) { + virtual void show(const struct CRGB *rgbdata, int nLeds, CRGB scale) { PixelController pixels(rgbdata, nLeds, scale, getDither()); mWait.wait(); cli(); SysClockSaver savedClock(TOTAL); - - // Serial.print("Scale is "); + + // Serial.print("Scale is "); // Serial.print(scale.raw[0]); Serial.print(" "); // Serial.print(scale.raw[1]); Serial.print(" "); // Serial.print(scale.raw[2]); Serial.println(" "); @@ -66,7 +66,7 @@ public: uint32_t clocks = showRGBInternal(pixels); // Adjust the timer - long microsTaken = nLeds * CLKS_TO_MICROS(clocks); + long microsTaken = CLKS_TO_MICROS(clocks); long millisTaken = (microsTaken / 1000); savedClock.restore(); do { TimeTick_Increment(); } while(--millisTaken > 0); @@ -75,7 +75,7 @@ public: } #ifdef SUPPORT_ARGB - virtual void show(const struct CARGB *rgbdata, int nLeds, CRGB scale) { + virtual void show(const struct CARGB *rgbdata, int nLeds, CRGB scale) { PixelController pixels(rgbdata, nLeds, scale, getDither()); mWait.wait(); cli(); @@ -84,7 +84,7 @@ public: uint32_t clocks = showRGBInternal(pixels); // Adjust the timer - long microsTaken = nLeds * CLKS_TO_MICROS(clocks); + long microsTaken = CLKS_TO_MICROS(clocks); long millisTaken = (microsTaken / 1000); savedClock.restore(); do { TimeTick_Increment(); } while(--millisTaken > 0); @@ -102,7 +102,7 @@ public: #define ARM_DWT_CYCCNT *(volatile uint32_t *)0xE0001004 // Cycle count register template __attribute__ ((always_inline)) inline static void writeBits(register uint32_t & next_mark, register data_ptr_t port, register uint8_t & b) { - for(register uint32_t i = BITS; i > 0; i--) { + for(register uint32_t i = BITS; i > 0; i--) { while(ARM_DWT_CYCCNT < next_mark); next_mark = ARM_DWT_CYCCNT + (T1+T2+T3); *port = 1; @@ -113,23 +113,23 @@ public: } } - // This method is made static to force making register Y available to use for data on AVR - if the method is non-static, then + // 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 showRGBInternal(PixelController pixels) { register data_ptr_t port = FastPinBB::port(); *port = 0; - // Setup the pixel controller and load/scale the first byte + // Setup the pixel controller and load/scale the first byte pixels.preStepFirstByteDithering(); register uint8_t b = pixels.loadAndScale0(); - - // Get access to the clock + + // Get access to the clock ARM_DEMCR |= ARM_DEMCR_TRCENA; ARM_DWT_CTRL |= ARM_DWT_CTRL_CYCCNTENA; ARM_DWT_CYCCNT = 0; uint32_t next_mark = ARM_DWT_CYCCNT + (T1+T2+T3); - while(pixels.has(1)) { + while(pixels.has(1)) { pixels.stepDithering(); // Write first byte, read next byte @@ -145,7 +145,7 @@ public: b = pixels.advanceAndLoadAndScale0(); }; } -#else +#else // I hate using defines for these, should find a better representation at some point #define _CTRL CTPTR[0] #define _LOAD CTPTR[1] @@ -153,7 +153,7 @@ public: #define VAL (volatile uint32_t)(*((uint32_t*)(SysTick_BASE + 8))) template __attribute__ ((always_inline)) inline static void writeBits(register uint32_t & next_mark, register data_ptr_t port, register uint8_t & b) { - for(register uint32_t i = BITS; i > 0; i--) { + for(register uint32_t i = BITS; i > 0; i--) { // wait to start the bit, then set the pin high while(VAL > next_mark); next_mark = (VAL-TOTAL); @@ -163,9 +163,9 @@ public: if(b&0x80) { // we're a 1, wait until there's less than T3 clocks left while((VAL - next_mark) > (T3)); - } else { + } else { // we're a 0, wait until there's less than (T2+T3+slop) clocks left in this bit - while((VAL-next_mark) > (T2+T3+4+TADJUST+TADJUST)); + while((VAL-next_mark) > (T2+T3+4+TADJUST+TADJUST)); } *port=0; b <<= 1; @@ -173,7 +173,7 @@ public: } #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 + // 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 & pixels) { // Setup and start the clock @@ -186,12 +186,12 @@ public: register data_ptr_t port asm("r7") = FastPinBB::port(); FORCE_REFERENCE(port); *port = 0; - // Setup the pixel controller and load/scale the first byte + // Setup the pixel controller and load/scale the first byte pixels.preStepFirstByteDithering(); register uint8_t b = pixels.loadAndScale0(); - + uint32_t next_mark = (VAL - (TOTAL)); - while(pixels.has(1)) { + while(pixels.has(1)) { pixels.stepDithering(); writeBits<8+XTRA0>(next_mark, port, b); -- cgit v1.2.3 From f22cee6a95983d0bf3327f016fb68d827b30915f Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Thu, 17 Apr 2014 15:43:10 -0700 Subject: Fixing LPD8806 adjustment --- chipsets.h | 68 ++++++++++++++++++++++++++--------------------------- preview_changes.txt | 2 +- 2 files changed, 35 insertions(+), 35 deletions(-) diff --git a/chipsets.h b/chipsets.h index 2b59916e..d628bd9a 100644 --- a/chipsets.h +++ b/chipsets.h @@ -7,7 +7,7 @@ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // LPD8806 controller class - takes data/clock/select pin values (N.B. should take an SPI definition?) -// +// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// template @@ -17,8 +17,8 @@ class LPD8806Controller : public CLEDController { class LPD8806_ADJUST { public: // LPD8806 spec wants the high bit of every rgb data byte sent out to be set. - __attribute__((always_inline)) inline static uint8_t adjust(register uint8_t data) { return (data>>1) | 0x80 | (data & 0x01); } - __attribute__((always_inline)) inline static void postBlock(int len) { + __attribute__((always_inline)) inline static uint8_t adjust(register uint8_t data) { return ((data>>1) | 0x80) + ((data!=255) & 0x01); } + __attribute__((always_inline)) inline static void postBlock(int len) { SPI::writeBytesValueRaw(0, ((len+63)>>6)); } @@ -27,14 +27,14 @@ class LPD8806Controller : public CLEDController { SPI mSPI; int mClearedLeds; - void checkClear(int nLeds) { - if(nLeds > mClearedLeds) { + void checkClear(int nLeds) { + if(nLeds > mClearedLeds) { clearLine(nLeds); mClearedLeds = nLeds; } } - - void clearLine(int nLeds) { + + void clearLine(int nLeds) { int n = ((nLeds + 63) >> 6); mSPI.writeBytesValue(0, n); } @@ -45,9 +45,9 @@ public: mClearedLeds = 0; } - virtual void clearLeds(int nLeds) { + virtual void clearLeds(int nLeds) { mSPI.select(); - mSPI.writeBytesValueRaw(0x80, nLeds * 3); + mSPI.writeBytesValueRaw(0x80, nLeds * 3); mSPI.writeBytesValueRaw(0, ((nLeds*3+63)>>6)); mSPI.release(); } @@ -84,17 +84,17 @@ class WS2801Controller : public CLEDController { public: WS2801Controller() {} - virtual void init() { + virtual void init() { mSPI.init(); mWaitDelay.mark(); } - virtual void clearLeds(int nLeds) { + virtual void clearLeds(int nLeds) { mWaitDelay.wait(); mSPI.writeBytesValue(0, nLeds*3); mWaitDelay.mark(); } - + virtual void showColor(const struct CRGB & data, int nLeds, CRGB scale) { mWaitDelay.wait(); mSPI.template writePixels<0, DATA_NOP, RGB_ORDER>(PixelController(data, nLeds, scale, getDither())); @@ -137,21 +137,21 @@ class P9813Controller : public CLEDController { public: P9813Controller() {} - virtual void init() { + virtual void init() { mSPI.init(); } - virtual void clearLeds(int nLeds) { + virtual void clearLeds(int nLeds) { showColor(CRGB(0,0,0), nLeds, CRGB(0,0,0)); } - + virtual void showColor(const struct CRGB & data, int nLeds, CRGB scale) { PixelController pixels(data, nLeds, scale, getDither()); mSPI.select(); writeBoundary(); - while(nLeds--) { + while(nLeds--) { writeLed(pixels.loadAndScale0(), pixels.loadAndScale1(), pixels.loadAndScale2()); pixels.stepDithering(); } @@ -167,7 +167,7 @@ public: mSPI.select(); writeBoundary(); - for(int i = 0; i < nLeds; i++) { + for(int i = 0; i < nLeds; i++) { writeLed(pixels.loadAndScale0(), pixels.loadAndScale1(), pixels.loadAndScale2()); pixels.advanceData(); pixels.stepDithering(); @@ -184,7 +184,7 @@ public: mSPI.select(); writeBoundary(); - for(int i = 0; i < nLeds; i++) { + for(int i = 0; i < nLeds; i++) { writeLed(pixels.loadAndScale0(), pixels.loadAndScale1(), pixels.loadAndScale2()); pixels.advanceData(); pixels.stepDithering(); @@ -207,7 +207,7 @@ class SM16716Controller : public CLEDController { typedef SPIOutput SPI; SPI mSPI; - void writeHeader() { + void writeHeader() { // Write out 50 zeros to the spi line (6 blocks of 8 followed by two single bit writes) mSPI.select(); mSPI.writeBytesValueRaw(0, 6); @@ -220,13 +220,13 @@ class SM16716Controller : public CLEDController { public: SM16716Controller() {} - virtual void init() { + virtual void init() { mSPI.init(); } - virtual void clearLeds(int nLeds) { + virtual void clearLeds(int nLeds) { mSPI.select(); - while(nLeds--) { + while(nLeds--) { mSPI.template writeBit<0>(1); mSPI.writeByte(0); mSPI.writeByte(0); @@ -309,56 +309,56 @@ class GW6205Controller800Khz : public ClocklessController class GW6205Controller400Khz : public ClocklessController {}; -#if NO_TIME(800, 800, 800) +#if NO_TIME(800, 800, 800) #warning "Not enough clock cycles available for the GW6205@400khz" #endif // GW6205@400khz - 400ns, 400ns, 400ns template class GW6205Controller800Khz : public ClocklessController {}; -#if NO_TIME(400, 400, 400) +#if NO_TIME(400, 400, 400) #warning "Not enough clock cycles available for the GW6205@400khz" #endif // UCS1903 - 500ns, 1500ns, 500ns template class UCS1903Controller400Khz : public ClocklessController {}; -#if NO_TIME(500, 1500, 500) +#if NO_TIME(500, 1500, 500) #warning "Not enough clock cycles available for the UCS103@400khz" #endif // UCS1903B - 400ns, 450ns, 450ns template class UCS1903BController800Khz : public ClocklessController {}; -#if NO_TIME(400, 450, 450) +#if NO_TIME(400, 450, 450) #warning "Not enough clock cycles available for the UCS103B@800khz" #endif // TM1809 - 350ns, 350ns, 550ns template class TM1809Controller800Khz : public ClocklessController {}; -#if NO_TIME(350, 350, 550) +#if NO_TIME(350, 350, 550) #warning "Not enough clock cycles available for the TM1809" #endif -// WS2811 - 400ns, 400ns, 450ns +// WS2811 - 400ns, 400ns, 450ns template class WS2811Controller800Khz : public ClocklessController {}; -#if NO_TIME(400, 400, 450) +#if NO_TIME(400, 400, 450) #warning "Not enough clock cycles available for the WS2811 (800khz)" #endif -// WS2811@400khz - 800ns, 800ns, 900ns +// WS2811@400khz - 800ns, 800ns, 900ns template class WS2811Controller400Khz : public ClocklessController {}; -#if NO_TIME(800, 800, 900) +#if NO_TIME(800, 800, 900) #warning "Not enough clock cycles available for the WS2811 (400Khz)" #endif // 750NS, 750NS, 750NS template class TM1803Controller400Khz : public ClocklessController {}; -#if NO_TIME(750, 750, 750) +#if NO_TIME(750, 750, 750) #warning "Not enough clock cycles available for the TM1803" #endif @@ -369,7 +369,7 @@ template class TM1829Controller1600Khz : public ClocklessController {}; #if NO_TIME(100, 300, 200) #warning "Not enough clock cycles available for TM1829@1.6Mhz" -#endif +#endif template class LPD1886Controller1250Khz : public ClocklessController {}; @@ -377,6 +377,6 @@ class LPD1886Controller1250Khz : public ClocklessController Date: Thu, 17 Apr 2014 16:31:27 -0700 Subject: Updating README.md asking people to please use the g+ community for advice/questions. --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index fea1c296..2648b3cf 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,10 @@ We have multiple goals with this library: * Zero pain switching LED chipsets - you get some new leds that the library supports, just change the definition of LEDs you're using, et. voila! Your code is running with the new leds. * High performance - with features like zero cost global brightness scaling, high performance 8-bit math for RGB manipulation, and some of the fastest bit-bang'd SPI support around, FastLED wants to keep as many CPU cycles available for your led patterns as possible +## Getting help + +If you need help with using the library, please consider going to the google+ community first, which is at http://fastled.io/+ - there are hundreds of people in that group and many times you will get a quicker answer to your question there, as you will be likely to run into other people who have had the same issue. If you run into bugs with the library (compilation failures, the library doing the wrong thing), or if you'd like to request that we support a particular platform or LED chipset, then please open an issue at http://fastled.io/issues and we will try to figure out what is going wrong. + ## Simple example How quickly can you get up and running with the library? Here's a simple blink program: -- cgit v1.2.3 From 1cddfcb0e22b1e1321f92bb551fbace9bdb70c43 Mon Sep 17 00:00:00 2001 From: Mark Kriegsman Date: Fri, 18 Apr 2014 11:07:23 -0400 Subject: Adding basic XY Matrix example --- examples/XYMatrix/XYMatrix.ino | 197 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 197 insertions(+) create mode 100644 examples/XYMatrix/XYMatrix.ino diff --git a/examples/XYMatrix/XYMatrix.ino b/examples/XYMatrix/XYMatrix.ino new file mode 100644 index 00000000..ff0c5d14 --- /dev/null +++ b/examples/XYMatrix/XYMatrix.ino @@ -0,0 +1,197 @@ +#include + +#define LED_PIN 3 + +#define COLOR_ORDER GRB +#define CHIPSET WS2811 + +#define BRIGHTNESS 64 + +// Helper functions for an two-dimensional XY matrix of pixels. +// Simple 2-D demo code is included as well. +// +// XY(x,y) takes x and y coordinates and returns an LED index number, +// for use like this: leds[ XY(x,y) ] == CRGB::Red; +// No error checking is performed on the ranges of x and y. +// +// XYsafe(x,y) takes x and y coordinates and returns an LED index number, +// for use like this: leds[ XY(x,y) ] == CRGB::Red; +// Error checking IS performed on the ranges of x and y, and an +// index of "-1" is returned. Special instructions below +// explain how to use this without having to do your own error +// checking every time you use this function. +// This is a slightly more advanced technique, and +// it REQUIRES SPECIAL ADDITIONAL setup, described below. + + +// Params for width and height +const uint8_t kMatrixWidth = 16; +const uint8_t kMatrixHeight = 16; + +// Param for different pixel layouts +const bool kMatrixSerpentineLayout = true; +// Set 'kMatrixSerpentineLayout' to false if your pixels are +// laid out all running the same way, like this: +// +// 0 > 1 > 2 > 3 > 4 +// | +// .----<----<----<----' +// | +// 5 > 6 > 7 > 8 > 9 +// | +// .----<----<----<----' +// | +// 10 > 11 > 12 > 13 > 14 +// | +// .----<----<----<----' +// | +// 15 > 16 > 17 > 18 > 19 +// +// Set 'kMatrixSerpentineLayout' to true if your pixels are +// laid out back-and-forth, like this: +// +// 0 > 1 > 2 > 3 > 4 +// | +// | +// 9 < 8 < 7 < 6 < 5 +// | +// | +// 10 > 11 > 12 > 13 > 14 +// | +// | +// 19 < 18 < 17 < 16 < 15 +// +// Bonus vocabulary word: anything that goes one way +// in one row, and then backwards in the next row, and so on +// is call "boustrophedon", meaning "as the ox plows." + + +// This function will return the right 'led index number' for +// a given set of X and Y coordinates on your matrix. +// IT DOES NOT CHECK THE COORDINATE BOUNDARIES. +// That's up to you. Don't pass it bogus values. +// +// Use the "XY" function like this: +// +// for( uint8_t x = 0; x < kMatrixWidth; x++) { +// for( uint8_t y = 0; y < kMatrixHeight; y++) { +// +// // Here's the x, y to 'led index' in action: +// leds[ XY( x, y) ] = CHSV( random8(), 255, 255); +// +// } +// } +// +// +uint16_t XY( uint8_t x, uint8_t y) +{ + uint16_t i; + + if( kMatrixSerpentineLayout == false) { + i = (y * kMatrixWidth) + x; + } + + if( kMatrixSerpentineLayout == true) { + if( y & 0x01) { + // Odd rows run backwards + uint8_t reverseX = (kMatrixWidth - 1) - x; + i = (y * kMatrixWidth) + reverseX; + } else { + // Even rows run forwards + i = (y * kMatrixWidth) + x; + } + } + + return i; +} + + +// Once you've gotten the basics working (AND NOT UNTIL THEN!) +// here's a helpful technique that can be tricky to set up, but +// then helps you avoid the needs for sprinkling array-bound-checking +// throughout your code. +// +// It requires a careful attention to get it set up correctly, but +// can potentially make your code smaller and faster. +// +// Suppose you have an 8 x 5 matrix of 40 LEDs. Normally, you'd +// delcare your leds array like this: +// CRGB leds[40]; +// But instead of that, declare an LED buffer with one extra pixel in +// it, "leds_plus_safety_pixel". Then declare "leds" as a pointer to +// that array, but starting with the 2nd element (id=1) of that array: +// CRGB leds_with_safety_pixel[41]; +// const CRGB* leds( leds_plus_safety_pixel + 1); +// Then you use the "leds" array as you normally would. +// Now "leds[0..N]" are aliases for "leds_plus_safety_pixel[1..(N+1)]", +// AND leds[-1] is now a legitimate and safe alias for leds_plus_safety_pixel[0]. +// leds_plus_safety_pixel[0] aka leds[-1] is now your "safety pixel". +// +// Now instead of using the XY function above, use the one below, "XYsafe". +// +// If the X and Y values are 'in bounds', this function will return an index +// into the visible led array, same as "XY" does. +// HOWEVER -- and this is the trick -- if the X or Y values +// are out of bounds, this function will return an index of -1. +// And since leds[-1] is actually just an alias for leds_plus_safety_pixel[0], +// it's a totally safe and legal place to access. And since the 'safety pixel' +// falls 'outside' the visible part of the LED array, anything you write +// there is hidden from view automatically. +// Thus, this line of code is totally safe, regardless of the actual size of +// your matrix: +// leds[ XYsafe( random8(), random8() ) ] = CHSV( random8(), 255, 255); +// +// The only catch here is that while this makes it safe to read from and +// write to 'any pixel', there's really only ONE 'safety pixel'. No matter +// what out-of-bounds coordinates you write to, you'll really be writing to +// that one safety pixel. And if you try to READ from the safety pixel, +// you'll read whatever was written there last, reglardless of what coordinates +// were supplied. + +#define NUM_LEDS (kMatrixWidth * kMatrixHeight) +CRGB leds_plus_safety_pixel[ NUM_LEDS + 1]; +CRGB* leds( leds_plus_safety_pixel + 1); + +uint16_t XYsafe( uint8_t x, uint8_t y) +{ + if( x >= kMatrixWidth) return -1; + if( y >= kMatrixHeight) return -1; + return XY(x,y); +} + + +// Demo that USES "XY" follows code below + +void loop() +{ + uint32_t ms = millis(); + int32_t yHueDelta32 = ((int32_t)cos16( ms * (27/1) ) * (350 / kMatrixWidth)); + int32_t xHueDelta32 = ((int32_t)cos16( ms * (39/1) ) * (310 / kMatrixHeight)); + DrawOneFrame( ms / 65536, yHueDelta32 / 32768, xHueDelta32 / 32768); + if( ms < 5000 ) { + FastLED.setBrightness( scale8( BRIGHTNESS, (ms * 256) / 5000)); + } else { + FastLED.setBrightness(BRIGHTNESS); + } + FastLED.show(); +} + +void DrawOneFrame( byte startHue8, int8_t yHueDelta8, int8_t xHueDelta8) +{ + byte lineStartHue = startHue8; + for( byte y = 0; y < kMatrixHeight; y++) { + lineStartHue += yHueDelta8; + byte pixelHue = lineStartHue; + for( byte x = 0; x < kMatrixWidth; x++) { + pixelHue += xHueDelta8; + leds[ XY(x, y)] = CHSV( pixelHue, 255, 255); + } + } +} + + +void setup() { + FastLED.addLeds(leds, NUM_LEDS).setCorrection(TypicalSMD5050); + FastLED.setBrightness( BRIGHTNESS ); +} + -- cgit v1.2.3 From f6def5eda5d8d763afcc82bedde7645aaf271312 Mon Sep 17 00:00:00 2001 From: Mark Kriegsman Date: Fri, 18 Apr 2014 11:32:47 -0400 Subject: Added HeatColor function, started new file 'colorutils' --- FastLED.h | 1 + colorutils.cpp | 78 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ colorutils.h | 27 ++++++++++++++++++++ hsv2rgb.cpp | 22 ----------------- hsv2rgb.h | 11 --------- 5 files changed, 106 insertions(+), 33 deletions(-) create mode 100644 colorutils.cpp create mode 100644 colorutils.h diff --git a/FastLED.h b/FastLED.h index 510caf96..e3dc4a77 100644 --- a/FastLED.h +++ b/FastLED.h @@ -14,6 +14,7 @@ #include "clockless.h" #include "lib8tion.h" #include "hsv2rgb.h" +#include "colorutils.h" #include "chipsets.h" #include "dmx.h" diff --git a/colorutils.cpp b/colorutils.cpp new file mode 100644 index 00000000..0c436f3e --- /dev/null +++ b/colorutils.cpp @@ -0,0 +1,78 @@ +#include + +#include "hsv2rgb.h" +#include "colorutils.h" + + +void fill_solid( struct CRGB * pFirstLED, int numToFill, + const struct CRGB& color) +{ + for( int i = 0; i < numToFill; i++) { + pFirstLED[i] = color; + } +} + +void fill_rainbow( struct CRGB * pFirstLED, int numToFill, + uint8_t initialhue, + uint8_t deltahue ) +{ + CHSV hsv; + hsv.hue = initialhue; + hsv.val = 255; + hsv.sat = 255; + for( int i = 0; i < numToFill; i++) { + hsv2rgb_rainbow( hsv, pFirstLED[i]); + hsv.hue += deltahue; + } +} + + + + +// CRGB HeatColor( uint8_t temperature) +// +// Approximates a 'black body radiation' spectrum for +// a given 'heat' level. This is useful for animations of 'fire'. +// Heat is specified as an arbitrary scale from 0 (cool) to 255 (hot). +// This is NOT a chromatically correct 'black body radiation' +// spectrum, but it's surprisingly close, and it's fast and small. +// +// On AVR/Arduino, this typically takes around 70 bytes of program memory, +// versus 768 bytes for a full 256-entry RGB lookup table. + +CRGB HeatColor( uint8_t temperature) +{ + CRGB heatcolor; + + // Scale 'heat' down from 0-255 to 0-191, + // which can then be easily divided into three + // equal 'thirds' of 64 units each. + uint8_t t192 = scale8_video( temperature, 192); + + // calculate a value that ramps up from + // zero to 255 in each 'third' of the scale. + uint8_t heatramp = t192 & 0x3F; // 0..63 + heatramp <<= 2; // scale up to 0..252 + + // now figure out which third of the spectrum we're in: + if( t192 & 0x80) { + // we're in the hottest third + heatcolor.r = 255; // full red + heatcolor.g = 255; // full green + heatcolor.b = heatramp; // ramp up blue + + } else if( t192 & 0x40 ) { + // we're in the middle third + heatcolor.r = 255; // full red + heatcolor.g = heatramp; // ramp up green + heatcolor.b = 0; // no blue + + } else { + // we're in the coolest third + heatcolor.r = heatramp; // ramp up red + heatcolor.g = 0; // no green + heatcolor.b = 0; // no blue + } + + return heatcolor; +} diff --git a/colorutils.h b/colorutils.h new file mode 100644 index 00000000..8a135966 --- /dev/null +++ b/colorutils.h @@ -0,0 +1,27 @@ +#ifndef __INC_COLORUTILS_H +#define __INC_COLORUTILS_H + +#include "pixeltypes.h" + + +// fill_solid - fill a range of LEDs with a solid color +void fill_solid( struct CRGB * pFirstLED, int numToFill, + const struct CRGB& color); + +// fill_rainbow - fill a range of LEDs with a rainbow of colors, at +// full saturation and full value (brightness) +void fill_rainbow( struct CRGB * pFirstLED, int numToFill, + uint8_t initialhue, + uint8_t deltahue = 5); + + +// CRGB HeatColor( uint8_t temperature) +// +// Approximates a 'black body radiation' spectrum for +// a given 'heat' level. This is useful for animations of 'fire'. +// Heat is specified as an arbitrary scale from 0 (cool) to 255 (hot). +// This is NOT a chromatically correct 'black body radiation' +// spectrum, but it's surprisingly close, and it's fast and small. +CRGB HeatColor( uint8_t temperature); + +#endif diff --git a/hsv2rgb.cpp b/hsv2rgb.cpp index 43379a0e..0844d1f2 100644 --- a/hsv2rgb.cpp +++ b/hsv2rgb.cpp @@ -474,25 +474,3 @@ void hsv2rgb_spectrum( const struct CHSV* phsv, struct CRGB * prgb, int numLeds) hsv2rgb_spectrum(phsv[i], prgb[i]); } } - -void fill_solid( struct CRGB * pFirstLED, int numToFill, - const struct CRGB& color) -{ - for( int i = 0; i < numToFill; i++) { - pFirstLED[i] = color; - } -} - -void fill_rainbow( struct CRGB * pFirstLED, int numToFill, - uint8_t initialhue, - uint8_t deltahue ) -{ - CHSV hsv; - hsv.hue = initialhue; - hsv.val = 255; - hsv.sat = 255; - for( int i = 0; i < numToFill; i++) { - hsv2rgb_rainbow( hsv, pFirstLED[i]); - hsv.hue += deltahue; - } -} diff --git a/hsv2rgb.h b/hsv2rgb.h index d30e9aef..959c754a 100644 --- a/hsv2rgb.h +++ b/hsv2rgb.h @@ -45,15 +45,4 @@ void hsv2rgb_raw(const struct CHSV& hsv, struct CRGB & rgb); void hsv2rgb_raw(const struct CHSV* phsv, struct CRGB * prgb, int numLeds); #define HUE_MAX 191 - -// fill_solid - fill a range of LEDs with a solid color -void fill_solid( struct CRGB * pFirstLED, int numToFill, - const struct CRGB& color); - -// fill_rainbow - fill a range of LEDs with a rainbow of colors, at -// full saturation and full value (brightness) -void fill_rainbow( struct CRGB * pFirstLED, int numToFill, - uint8_t initialhue, - uint8_t deltahue = 5); - #endif -- cgit v1.2.3 From 51f62979b3aa46f4f22975a6b5d7ee3406db783d Mon Sep 17 00:00:00 2001 From: Mark Kriegsman Date: Fri, 18 Apr 2014 11:49:47 -0400 Subject: Adding Fire2012 example -- the Examples folder now needs serious organization, but one step at a time since I have a few minutes free to do this part. --- examples/Fire2012/Fire2012.ino | 96 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 96 insertions(+) create mode 100644 examples/Fire2012/Fire2012.ino diff --git a/examples/Fire2012/Fire2012.ino b/examples/Fire2012/Fire2012.ino new file mode 100644 index 00000000..73703426 --- /dev/null +++ b/examples/Fire2012/Fire2012.ino @@ -0,0 +1,96 @@ +#include + +#define LED_PIN 5 +#define COLOR_ORDER GRB +#define CHIPSET WS2811 +#define NUM_LEDS 30 + +#define BRIGHTNESS 200 +#define FRAMES_PER_SECOND 60 + +CRGB leds[NUM_LEDS]; + +void setup() { + delay(3000); // sanity delay + FastLED.addLeds(leds, NUM_LEDS).setCorrection( TypicalLEDStrip ); + FastLED.setBrightness( BRIGHTNESS ); +} + +void loop() +{ + // Add entropy to random number generator; we use a lot of it. + random16_add_entropy( random()); + + Fire2012(); // run simulation frame + + FastLED.show(); // display this frame + FastLED.delay(1000 / FRAMES_PER_SECOND); +} + + +// Fire2012 by Mark Kriegsman, July 2012 +// as part of "Five Elements" shown here: http://youtu.be/knWiGsmgycY +//// +// This basic one-dimensional 'fire' simulation works roughly as follows: +// There's a underlying array of 'heat' cells, that model the temperature +// at each point along the line. Every cycle through the simulation, +// four steps are performed: +// 1) All cells cool down a little bit, losing heat to the air +// 2) The heat from each cell drifts 'up' and diffuses a little +// 3) Sometimes randomly new 'sparks' of heat are added at the bottom +// 4) The heat from each cell is rendered as a color into the leds array +// The heat-to-color mapping uses a black-body radiation approximation. +// +// Temperature is in arbitrary units from 0 (cold black) to 255 (white hot). +// +// This simulation scales it self a bit depending on NUM_LEDS; it should look +// "OK" on anywhere from 20 to 100 LEDs without too much tweaking. +// +// I recommend running this simulation at anywhere from 30-100 frames per second, +// meaning an interframe delay of about 10-35 milliseconds. +// +// Looks best on a high-density LED setup (60+ pixels/meter). +// +// +// There are two main parameters you can play with to control the look and +// feel of your fire: COOLING (used in step 1 above), and SPARKING (used +// in step 3 above). +// +// COOLING: How much does the air cool as it rises? +// Less cooling = taller flames. More cooling = shorter flames. +// Default 50, suggested range 20-100 +#define COOLING 55 + +// SPARKING: What chance (out of 255) is there that a new spark will be lit? +// Higher chance = more roaring fire. Lower chance = more flickery fire. +// Default 120, suggested range 50-200. +#define SPARKING 120 + + +void Fire2012() +{ +// Array of temperature readings at each simulation cell + static byte heat[NUM_LEDS]; + + // Step 1. Cool down every cell a little + for( int i = 0; i < NUM_LEDS; i++) { + heat[i] = qsub8( heat[i], random8(0, ((COOLING * 10) / NUM_LEDS) + 2)); + } + + // Step 2. Heat from each cell drifts 'up' and diffuses a little + for( int k= NUM_LEDS - 3; k > 0; k--) { + heat[k] = (heat[k - 1] + heat[k - 2] + heat[k - 2] ) / 3; + } + + // Step 3. Randomly ignite new 'sparks' of heat near the bottom + if( random8() < SPARKING ) { + int y = random8(7); + heat[y] = qadd8( heat[y], random8(160,255) ); + } + + // Step 4. Map from heat cells to LED colors + for( int j = 0; j < NUM_LEDS; j++) { + leds[j] = HeatColor( heat[j]); + } +} + -- cgit v1.2.3 From fd7074f0e564de0b8e038defe174cf889aa880e4 Mon Sep 17 00:00:00 2001 From: Mark Kriegsman Date: Fri, 18 Apr 2014 13:55:36 -0400 Subject: Updated with additions --- preview_changes.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/preview_changes.txt b/preview_changes.txt index afcddf64..2017f972 100644 --- a/preview_changes.txt +++ b/preview_changes.txt @@ -10,3 +10,5 @@ * More accurate timing adjustments for k20 and due clockless chips * Added HUE_RED, HUE_ORANGE, etc. * Added named color correction profiles (eg. TypicalSMD5050) +* Added XY Matrix example +* Added Fire2012 example, added HeatColor(...) to the library -- cgit v1.2.3 From 6f790f8a40804ccfc43a08da8edd923ed866676f Mon Sep 17 00:00:00 2001 From: Mark Kriegsman Date: Fri, 18 Apr 2014 14:10:47 -0400 Subject: Added ColorTemperature example demo --- examples/ColorTemperature/ColorTemperature.ino | 85 ++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 examples/ColorTemperature/ColorTemperature.ino diff --git a/examples/ColorTemperature/ColorTemperature.ino b/examples/ColorTemperature/ColorTemperature.ino new file mode 100644 index 00000000..66093e06 --- /dev/null +++ b/examples/ColorTemperature/ColorTemperature.ino @@ -0,0 +1,85 @@ +#include + +#define LED_PIN 3 + +// Information about the LED strip itself +#define NUM_LEDS 60 +#define CHIPSET WS2811 +#define COLOR_ORDER GRB +CRGB leds[NUM_LEDS]; + +#define BRIGHTNESS 128 + + +// FastLED v2.1 provides two color-management controls: +// (1) color correction settings for each LED strip, and +// (2) master control of the overall output 'color temperature' +// +// THIS EXAMPLE demonstrates the second, "color temperature" control. +// It shows a simple rainbow animation first with one temperature profile, +// and a few seconds later, with a different temperature profile. +// +// The first pixel of the strip will show the color temperature. +// +// HELPFUL HINTS for "seeing" the effect in this demo: +// * Don't look directly at the LED pixels. Shine the LEDs aganst +// a white wall, table, or piece of paper, and look at the reflected light. +// +// * If you watch it for a bit, and then walk away, and then come back +// to it, you'll probably be able to "see" whether it's currently using +// the 'redder' or the 'bluer' temperature profile, even not counting +// the lowest 'indicator' pixel. +// +// +// FastLED provides these pre-conigured incandescent color profiles: +// Candle, Tungsten40W, Tungsten100W, Halogen, CarbonArc, +// HighNoonSun, DirectSunlight, OvercastSky, ClearBlueSky, +// FastLED provides these pre-configured gaseous-light color profiles: +// WarmFluorescent, StandardFluorescent, CoolWhiteFluorescent, +// FullSpectrumFluorescent, GrowLightFluorescent, BlackLightFluorescent, +// MercuryVapor, SodiumVapor, MetalHalide, HighPressureSodium, +// FastLED also provides an "Uncorrected temperature" profile +// UncorrectedTemperature; + +#define TEMPERATURE_1 Tungsten100W +#define TEMPERATURE_2 OvercastSky + +// How many seconds to show each temperature before switching +#define DISPLAYTIME 20 +// How many seconds to show black between switches +#define BLACKTIME 3 + +void loop() +{ + // draw a generic, no-name rainbow + static uint8_t starthue = 0; + fill_rainbow( leds + 5, NUM_LEDS - 5, --starthue, 20); + + // Choose which 'color temperature' profile to enable. + uint8_t secs = (millis() / 1000) % (DISPLAYTIME * 2); + if( secs < DISPLAYTIME) { + FastLED.setTemperature( TEMPERATURE_1 ); // first temperature + leds[0] = TEMPERATURE_1; // show indicator pixel + } else { + FastLED.setTemperature( TEMPERATURE_2 ); // second temperature + leds[0] = TEMPERATURE_2; // show indicator pixel + } + + // Black out the LEDs for a few secnds between color changes + // to let the eyes and brains adjust + if( (secs % DISPLAYTIME) < BLACKTIME) { + memset8( leds, 0, NUM_LEDS * sizeof(CRGB)); + } + + FastLED.show(); + FastLED.delay(8); +} + +void setup() { + delay( 3000 ); // power-up safety delay + // It's important to set the color correction for your LED strip here, + // so that colors can be more accurately rendered through the 'temperature' profiles + FastLED.addLeds(leds, NUM_LEDS).setCorrection( TypicalSMD5050 ); + FastLED.setBrightness( BRIGHTNESS ); +} + -- cgit v1.2.3 From 4095389d9b1d7bd21919fe9aee2be6ead1785b63 Mon Sep 17 00:00:00 2001 From: Mark Kriegsman Date: Tue, 22 Apr 2014 00:09:55 -0400 Subject: Adding example that DOESN'T use a pixel-addressable LED strip, but just uses the FastLED HSV-to-RGB conversion functions. --- examples/AnalogOutput/AnalogOutput.ino | 65 ++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 examples/AnalogOutput/AnalogOutput.ino diff --git a/examples/AnalogOutput/AnalogOutput.ino b/examples/AnalogOutput/AnalogOutput.ino new file mode 100644 index 00000000..33733102 --- /dev/null +++ b/examples/AnalogOutput/AnalogOutput.ino @@ -0,0 +1,65 @@ +#include + +// Example showing how to use FastLED color functions +// even when you're NOT using a "pixel-addressible" smart LED strip. +// +// This example is designed to control an "analog" RGB LED strip +// (or a single RGB LED) being driven by Arduino PWM output pins. +// So this code never calls FastLED.addLEDs() or FastLED.show(). +// +// This example illustrates one way you can use just the portions +// of FastLED that you need. In this case, this code uses just the +// fast HSV color conversion code. +// +// In this example, the RGB values are output on three separate +// 'analog' PWM pins, one for red, one for green, and one for blue. + +#define REDPIN 5 +#define GREENPIN 6 +#define BLUEPIN 3 + +// showAnalogRGB: this is like FastLED.show(), but outputs on +// analog PWM output pins instead of sending data to an intelligent, +// pixel-addressable LED strip. +// +// This function takes the incoming RGB values and outputs the values +// on three analog PWM output pins to the r, g, and b values respectively. +void showAnalogRGB( const CRGB& rgb) +{ + analogWrite(REDPIN, rgb.r ); + analogWrite(GREENPIN, rgb.g ); + analogWrite(BLUEPIN, rgb.b ); +} + + + +// colorBars: flashes Red, then Green, then Blue, then Black. +// Helpful for diagnosing if you've mis-wired which is which. +void colorBars() +{ + showAnalogRGB( CRGB::Red ); delay(500); + showAnalogRGB( CRGB::Green ); delay(500); + showAnalogRGB( CRGB::Blue ); delay(500); + showAnalogRGB( CRGB::Black ); delay(500); +} + +void loop() +{ + static uint8_t hue; + hue = hue + 1; + // Use FastLED automatic HSV->RGB conversion + showAnalogRGB( CHSV( hue, 255, 255) ); + + delay(20); +} + + +void setup() { + pinMode(REDPIN, OUTPUT); + pinMode(GREENPIN, OUTPUT); + pinMode(BLUEPIN, OUTPUT); + + // Flash the "hello" color sequence: R, G, B, black. + colorBars(); +} + -- cgit v1.2.3 From b368d8684e45523b5ab78ca03b0b43d7f1532324 Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Wed, 23 Apr 2014 21:04:59 -0700 Subject: Adding various multiple examples --- .../Multiple/ArrayOfLedArrays/ArrayOfLedArrays.ino | 37 +++++++++++++++ .../Multiple/MirroringSample/MirroringSample.ino | 44 ++++++++++++++++++ examples/Multiple/MultiArrays/MultiArrays.ino | 52 ++++++++++++++++++++++ .../MultipleStripsInOneArray.ino | 34 ++++++++++++++ 4 files changed, 167 insertions(+) create mode 100644 examples/Multiple/ArrayOfLedArrays/ArrayOfLedArrays.ino create mode 100644 examples/Multiple/MirroringSample/MirroringSample.ino create mode 100644 examples/Multiple/MultiArrays/MultiArrays.ino create mode 100644 examples/Multiple/MultipleStripsInOneArray/MultipleStripsInOneArray.ino diff --git a/examples/Multiple/ArrayOfLedArrays/ArrayOfLedArrays.ino b/examples/Multiple/ArrayOfLedArrays/ArrayOfLedArrays.ino new file mode 100644 index 00000000..56a61881 --- /dev/null +++ b/examples/Multiple/ArrayOfLedArrays/ArrayOfLedArrays.ino @@ -0,0 +1,37 @@ +// ArrayOfLedArrays - see https://github.com/FastLED/FastLED/wiki/Example-MultipleControllers for more info on +// using multiple controllers. In this example, we're going to set up four NEOPIXEL strips on three +// different pins, each strip getting its own CRGB array to be played with, only this time they're going +// to be all parts of an array of arrays. + +#include "FastLED.h" + +#define NUM_STRIPS 3 +#define NUM_LEDS_PER_STRIP 60 +CRGB leds[NUM_STRIPS][NUM_LEDS_PER_STRIP]; + +// For mirroring strips, all the "special" stuff happens just in setup. We +// just addLeds multiple times, once for each strip +void setup() { + // tell FastLED there's 60 NEOPIXEL leds on pin 10 + FastLED.addLeds(leds[0], NUM_LEDS_PER_STRIP); + + // tell FastLED there's 60 NEOPIXEL leds on pin 11 + FastLED.addLeds(leds[1], NUM_LEDS_PER_STRIP); + + // tell FastLED there's 60 NEOPIXEL leds on pin 12 + FastLED.addLeds(leds[2], NUM_LEDS_PER_STRIP); + +} + +void loop() { + // This outer loop will go over each strip, one at a time + for(int x = 0; x < NUM_STRIPS; x++) { + // This inner loop will go over each led in the current strip, one at a time + for(int i = 0; i < NUM_LEDS_PER_STRIP; i++) { + leds[x][i] = CRGB::Red; + FastLED.show(); + leds[x][i] = CRGB::Black; + delay(100); + } + } +} diff --git a/examples/Multiple/MirroringSample/MirroringSample.ino b/examples/Multiple/MirroringSample/MirroringSample.ino new file mode 100644 index 00000000..b9f8f5fd --- /dev/null +++ b/examples/Multiple/MirroringSample/MirroringSample.ino @@ -0,0 +1,44 @@ +// MirroringSample - see https://github.com/FastLED/FastLED/wiki/Example-MultipleControllers for more info on +// using multiple controllers. In this example, we're going to set up four NEOPIXEL strips on four +// different pins, and show the same thing on all four of them, a simple bouncing dot/cyclon type pattern + +#include "FastLED.h" + +#define NUM_LEDS_PER_STRIP 60 +CRGB leds[NUM_LEDS_PER_STRIP]; + +// For mirroring strips, all the "special" stuff happens just in setup. We +// just addLeds multiple times, once for each strip +void setup() { + // tell FastLED there's 60 NEOPIXEL leds on pin 4 + FastLED.addLeds(leds, NUM_LEDS_PER_STRIP); + + // tell FastLED there's 60 NEOPIXEL leds on pin 5 + FastLED.addLeds(leds, NUM_LEDS_PER_STRIP); + + // tell FastLED there's 60 NEOPIXEL leds on pin 6 + FastLED.addLeds(leds, NUM_LEDS_PER_STRIP); + + // tell FastLED there's 60 NEOPIXEL leds on pin 7 + FastLED.addLeds(leds, NUM_LEDS_PER_STRIP); +} + +void loop() { + for(int i = 0; i < NUM_LEDS_PER_STRIP; i++) { + // set our current dot to red + leds[i] = CRGB::Red; + FastLED.show(); + // clear our current dot before we move on + leds[i] = CRGB::Black; + delay(100); + } + + for(int i = NUM_LEDS_PER_STRIP-1; i >= 0; i--) { + // set our current dot to red + leds[i] = CRGB::Red; + FastLED.show(); + // clear our current dot before we move on + leds[i] = CRGB::Black; + delay(100); + } +} diff --git a/examples/Multiple/MultiArrays/MultiArrays.ino b/examples/Multiple/MultiArrays/MultiArrays.ino new file mode 100644 index 00000000..31d8776d --- /dev/null +++ b/examples/Multiple/MultiArrays/MultiArrays.ino @@ -0,0 +1,52 @@ +// MultiArrays - see https://github.com/FastLED/FastLED/wiki/Example-MultipleControllers for more info on +// using multiple controllers. In this example, we're going to set up four NEOPIXEL strips on three +// different pins, each strip getting its own CRGB array to be played with + +#include "FastLED.h" + +#define NUM_LEDS_PER_STRIP 60 +CRGB redLeds[NUM_LEDS_PER_STRIP]; +CRGB greenLeds[NUM_LEDS_PER_STRIP]; +CRGB blueLeds[NUM_LEDS_PER_STRIP]; + +// For mirroring strips, all the "special" stuff happens just in setup. We +// just addLeds multiple times, once for each strip +void setup() { + // tell FastLED there's 60 NEOPIXEL leds on pin 10 + FastLED.addLeds(redLeds, NUM_LEDS_PER_STRIP); + + // tell FastLED there's 60 NEOPIXEL leds on pin 11 + FastLED.addLeds(greenLeds, NUM_LEDS_PER_STRIP); + + // tell FastLED there's 60 NEOPIXEL leds on pin 12 + FastLED.addLeds(blueLeds, NUM_LEDS_PER_STRIP); + +} + +void loop() { + for(int i = 0; i < NUM_LEDS_PER_STRIP; i++) { + // set our current dot to red, green, and blue + redLeds[i] = CRGB::Red; + greenLeds[i] = CRGB::Green; + blueLeds[i] = CRGB::Blue; + FastLED.show(); + // clear our current dot before we move on + redLeds[i] = CRGB::Black; + greenLeds[i] = CRGB::Black; + blueLeds[i] = CRGB::Blue; + delay(100); + } + + for(int i = NUM_LEDS_PER_STRIP-1; i >= 0; i--) { + // set our current dot to red, green, and blue + redLeds[i] = CRGB::Red; + greenLeds[i] = CRGB::Green; + blueLeds[i] = CRGB::Blue; + FastLED.show(); + // clear our current dot before we move on + redLeds[i] = CRGB::Black; + greenLeds[i] = CRGB::Black; + blueLeds[i] = CRGB::Blue; + delay(100); + } +} diff --git a/examples/Multiple/MultipleStripsInOneArray/MultipleStripsInOneArray.ino b/examples/Multiple/MultipleStripsInOneArray/MultipleStripsInOneArray.ino new file mode 100644 index 00000000..286211ae --- /dev/null +++ b/examples/Multiple/MultipleStripsInOneArray/MultipleStripsInOneArray.ino @@ -0,0 +1,34 @@ +// MultipleStripsInOneArray - see https://github.com/FastLED/FastLED/wiki/Example-MultipleControllers for more info on +// using multiple controllers. In this example, we're going to set up four NEOPIXEL strips on three +// different pins, each strip will be referring to a different part of the single led array + +#include "FastLED.h" + +#define NUM_STRIPS 3 +#define NUM_LEDS_PER_STRIP 60 +#define NUM_LEDS NUM_LEDS_PER_STRIP * NUM_STRIPS + +CRGB leds[NUM_STRIPS * NUM_LEDS_PER_STRIP]; + +// For mirroring strips, all the "special" stuff happens just in setup. We +// just addLeds multiple times, once for each strip +void setup() { + // tell FastLED there's 60 NEOPIXEL leds on pin 10, starting at index 0 in the led array + FastLED.addLeds(leds, 0, NUM_LEDS_PER_STRIP); + + // tell FastLED there's 60 NEOPIXEL leds on pin 11, starting at index 60 in the led array + FastLED.addLeds(leds, NUM_LEDS_PER_STRIP, NUM_LEDS_PER_STRIP); + + // tell FastLED there's 60 NEOPIXEL leds on pin 12, starting at index 120 in the led array + FastLED.addLeds(leds, 2 * NUM_LEDS_PER_STRIP, NUM_LEDS_PER_STRIP); + +} + +void loop() { + for(int i = 0; i < NUM_LEDS; i++) { + leds[i] = CRGB::Red; + FastLED.show(); + leds[i] = CRGB::Black; + delay(100); + } +} -- cgit v1.2.3 From 8ffac05d172d1914e01abdad764c8d41b7e1c859 Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Wed, 23 Apr 2014 21:08:11 -0700 Subject: Updating wiki page link for examples --- examples/Multiple/ArrayOfLedArrays/ArrayOfLedArrays.ino | 2 +- examples/Multiple/MirroringSample/MirroringSample.ino | 2 +- examples/Multiple/MultiArrays/MultiArrays.ino | 2 +- examples/Multiple/MultipleStripsInOneArray/MultipleStripsInOneArray.ino | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/Multiple/ArrayOfLedArrays/ArrayOfLedArrays.ino b/examples/Multiple/ArrayOfLedArrays/ArrayOfLedArrays.ino index 56a61881..cc171835 100644 --- a/examples/Multiple/ArrayOfLedArrays/ArrayOfLedArrays.ino +++ b/examples/Multiple/ArrayOfLedArrays/ArrayOfLedArrays.ino @@ -1,4 +1,4 @@ -// ArrayOfLedArrays - see https://github.com/FastLED/FastLED/wiki/Example-MultipleControllers for more info on +// ArrayOfLedArrays - see https://github.com/FastLED/FastLED/wiki/Multiple-Controller-Examples for more info on // using multiple controllers. In this example, we're going to set up four NEOPIXEL strips on three // different pins, each strip getting its own CRGB array to be played with, only this time they're going // to be all parts of an array of arrays. diff --git a/examples/Multiple/MirroringSample/MirroringSample.ino b/examples/Multiple/MirroringSample/MirroringSample.ino index b9f8f5fd..39d748bd 100644 --- a/examples/Multiple/MirroringSample/MirroringSample.ino +++ b/examples/Multiple/MirroringSample/MirroringSample.ino @@ -1,4 +1,4 @@ -// MirroringSample - see https://github.com/FastLED/FastLED/wiki/Example-MultipleControllers for more info on +// MirroringSample - see https://github.com/FastLED/FastLED/wiki/Multiple-Controller-Examples for more info on // using multiple controllers. In this example, we're going to set up four NEOPIXEL strips on four // different pins, and show the same thing on all four of them, a simple bouncing dot/cyclon type pattern diff --git a/examples/Multiple/MultiArrays/MultiArrays.ino b/examples/Multiple/MultiArrays/MultiArrays.ino index 31d8776d..79b5bfc9 100644 --- a/examples/Multiple/MultiArrays/MultiArrays.ino +++ b/examples/Multiple/MultiArrays/MultiArrays.ino @@ -1,4 +1,4 @@ -// MultiArrays - see https://github.com/FastLED/FastLED/wiki/Example-MultipleControllers for more info on +// MultiArrays - see https://github.com/FastLED/FastLED/wiki/Multiple-Controller-Examples for more info on // using multiple controllers. In this example, we're going to set up four NEOPIXEL strips on three // different pins, each strip getting its own CRGB array to be played with diff --git a/examples/Multiple/MultipleStripsInOneArray/MultipleStripsInOneArray.ino b/examples/Multiple/MultipleStripsInOneArray/MultipleStripsInOneArray.ino index 286211ae..35a6c6a3 100644 --- a/examples/Multiple/MultipleStripsInOneArray/MultipleStripsInOneArray.ino +++ b/examples/Multiple/MultipleStripsInOneArray/MultipleStripsInOneArray.ino @@ -1,4 +1,4 @@ -// MultipleStripsInOneArray - see https://github.com/FastLED/FastLED/wiki/Example-MultipleControllers for more info on +// MultipleStripsInOneArray - see https://github.com/FastLED/FastLED/wiki/Multiple-Controller-Examples for more info on // using multiple controllers. In this example, we're going to set up four NEOPIXEL strips on three // different pins, each strip will be referring to a different part of the single led array -- cgit v1.2.3 From 3d420a822b3d6546dec5bb6e3f70482d0dbb0378 Mon Sep 17 00:00:00 2001 From: Mark Kriegsman Date: Sat, 26 Apr 2014 22:00:26 -0400 Subject: Added sin8, cos8, quadwave8, cubicwave8, triwave8, and ease8InOutQuad. --- lib8tion.h | 215 +++++++++++++++++++++++++++++++++++++++++++++++++--- preview_changes.txt | 1 + 2 files changed, 204 insertions(+), 12 deletions(-) diff --git a/lib8tion.h b/lib8tion.h index 74b8580f..84ae3dde 100644 --- a/lib8tion.h +++ b/lib8tion.h @@ -82,23 +82,40 @@ cos16( x) == cos( (x/32768.0) * pi) * 32767 Accurate to more than 99% in all cases. - - - Dimming and brightening functions for 8-bit - light values. - dim8_video( x) == scale8_video( x, x) - dim8_raw( x) == scale8( x, x) - brighten8_video( x) == 255 - dim8_video( 255 - x) - brighten8_raw( x) == 255 - dim8_raw( 255 - x) - The dimming functions in particular are suitable - for making LED light output appear more 'linear'. - + - Fast 8-bit approximations of sin and cos. + Input angle is a uint8_t from 0-255. + Output is an UNsigned uint8_t from 0 to 255. + sin8( x) == (sin( (x/128.0) * pi) * 128) + 128 + cos8( x) == (cos( (x/128.0) * pi) * 128) + 128 + Accurate to within about 2%. + - Fast 8-bit "easing in/out" function. ease8InOutCubic(x) == 3(x^i) - 2(x^3) ease8InOutApprox(x) == faster, rougher, approximation of cubic easing - + ease8InOutQuad(x) == quadratic (vs cubic) easing + + - Cubic, Quadratic, and Triangle wave functions. + Input is a uint8_t representing phase withing the wave, + similar to how sin8 takes an angle 'theta'. + Output is a uint8_t representing the amplitude of + the wave at that point. + cubicwave8( x) + quadwave8( x) + triwave8( x) + + - Dimming and brightening functions for 8-bit + light values. + dim8_video( x) == scale8_video( x, x) + dim8_raw( x) == scale8( x, x) + brighten8_video( x) == 255 - dim8_video( 255 - x) + brighten8_raw( x) == 255 - dim8_raw( 255 - x) + The dimming functions in particular are suitable + for making LED light output appear more 'linear'. + + - Linear interpolation between two values, with the fraction between them expressed as an 8- or 16-bit fixed point fraction (fract8 or fract16). @@ -1125,6 +1142,120 @@ LIB8STATIC int16_t cos16( uint16_t theta) return sin16( theta + 16384); } +/////////////////////////////////////////////////////////////////////// + +// sin8 & cos8 +// Fast 8-bit approximations of sin(x) & cos(x). +// Input angle is an unsigned int from 0-255. +// Output is an unsigned int from 0 to 255. +// +// This approximation can vary to to 2% +// from the floating point value you'd get by doing +// float s = (sin( x ) * 128.0) + 128; +// +// Don't use this approximation for calculating the +// "real" trigonometric calculations, but it's great +// for art projects and LED displays. +// +// On Arduino/AVR, this approximation is more than +// 20X faster than floating point sin(x) and cos(x) + +#if defined(__AVR__) && !defined(LIB8_ATTINY) +#define sin8 sin8_avr +#else +#define sin8 sin8_C +#endif + + +const uint8_t b_m16_interleave[] = { 0, 49, 49, 41, 90, 27, 117, 10 }; + +LIB8STATIC uint8_t sin8_avr( uint8_t theta) +{ + uint8_t offset = theta; + + asm volatile( + "sbrc %[theta],6 \n\t" + "com %[offset] \n\t" + : [theta] "+r" (theta), [offset] "+r" (offset) + ); + + offset &= 0x3F; // 0..63 + + uint8_t secoffset = offset & 0x0F; // 0..15 + if( theta & 0x40) secoffset++; + + uint8_t m16; uint8_t b; + + uint8_t section = offset >> 4; // 0..3 + uint8_t s2 = section * 2; + + const uint8_t* p = b_m16_interleave; + p += s2; + b = *p; + p++; + m16 = *p; + + uint8_t mx; + uint8_t xr1; + asm volatile( + "mul %[m16],%[secoffset] \n\t" + "mov %[mx],r0 \n\t" + "mov %[xr1],r1 \n\t" + "eor r1, r1 \n\t" + "swap %[mx] \n\t" + "andi %[mx],0x0F \n\t" + "swap %[xr1] \n\t" + "andi %[xr1], 0xF0 \n\t" + "or %[mx], %[xr1] \n\t" + : [mx] "=r" (mx), [xr1] "=r" (xr1) + : [m16] "r" (m16), [secoffset] "r" (secoffset) + ); + + int8_t y = mx + b; + if( theta & 0x80 ) y = -y; + + y += 128; + + return y; +} + + +LIB8STATIC uint8_t sin8_C( uint8_t theta) +{ + uint8_t offset = theta; + if( theta & 0x40 ) { + offset = (uint8_t)255 - offset; + } + offset &= 0x3F; // 0..63 + + uint8_t secoffset = offset & 0x0F; // 0..15 + if( theta & 0x40) secoffset++; + + uint8_t section = offset >> 4; // 0..3 + uint8_t s2 = section * 2; + const uint8_t* p = b_m16_interleave; + p += s2; + uint8_t b = *p; + p++; + uint8_t m16 = *p; + + uint8_t mx = (m16 * secoffset) >> 4; + + int8_t y = mx + b; + if( theta & 0x80 ) y = -y; + + y += 128; + + return y; +} + + +LIB8STATIC uint8_t cos8( uint8_t theta) +{ + return sin8( theta + 64); +} + + /////////////////////////////////////////////////////////////////////// // // memmove8, memcpy8, and memset8: @@ -1221,7 +1352,24 @@ LIB8STATIC int16_t lerp15by8( int16_t a, int16_t b, fract8 frac) // easing functions; see http://easings.net // -// ease8InOuCubic: 8-bit cubic ease-in / ease-out function +// ease8InOutQuad: 8-bit quadratic ease-in / ease-out function +// Takes around 13 cycles on AVR +LIB8STATIC uint8_t ease8InOutQuad( uint8_t i) +{ + uint8_t j = i; + if( j & 0x80 ) { + j = 255 - j; + } + uint8_t jj = scale8( j, (j+1)); + uint8_t jj2 = jj << 1; + if( i & 0x80 ) { + jj2 = 255 - jj2; + } + return jj2; +} + + +// ease8InOutCubic: 8-bit cubic ease-in / ease-out function // Takes around 18 cycles on AVR LIB8STATIC fract8 ease8InOutCubic( fract8 i) { @@ -1307,6 +1455,49 @@ LIB8STATIC uint8_t ease8InOutApprox( fract8 i) +// triwave8: triangle (sawtooth) wave generator. Useful for +// turning a one-byte ever-increasing value into a +// one-byte value that oscillates up and down. +// +// input output +// 0..127 0..254 (positive slope) +// 128..255 254..0 (negative slope) +// +// On AVR this function takes just three cycles. +// +LIB8STATIC uint8_t triwave8(uint8_t in) +{ + if( in & 0x80) { + in = 255 - in; + } + uint8_t out = in << 1; + return out; +} + + +// quadwave8 and cubicwave8: S-shaped wave generators (like 'sine'). +// Useful for turning a one-byte 'counter' value into a +// one-byte oscillating value that moves smoothly up and down, +// with an 'acceleration' and 'deceleration' curve. +// +// These are even faster than 'sin8', and have +// slightly different curve shapes. +// + +// quadwave8: quadratic waveform generator. Spends just a little more +// time at the limits than 'sine' does. +LIB8STATIC uint8_t quadwave8(uint8_t in) +{ + return ease8InOutQuad( triwave8( in)); +} + +// cubicwave8: cubic waveform generator. Spends visibly more time +// at the limits than 'sine' does. +LIB8STATIC uint8_t cubicwave8(uint8_t in) +{ + return ease8InOutCubic( triwave8( in)); +} + #endif diff --git a/preview_changes.txt b/preview_changes.txt index 2017f972..975cd3f6 100644 --- a/preview_changes.txt +++ b/preview_changes.txt @@ -12,3 +12,4 @@ * Added named color correction profiles (eg. TypicalSMD5050) * Added XY Matrix example * Added Fire2012 example, added HeatColor(...) to the library +* Added sin8, cos8, quadwave8, cubicwave8, triwave8, and ease8InOutQuad -- cgit v1.2.3 From e621b095414a0817d0d46fbac70585d1bab4e93a Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Thu, 8 May 2014 21:45:25 -0700 Subject: Define WS2803 using 25Mhz clock that datasheet claims. Tweak LPD8806 output. --- FastLED.h | 53 +++++++++++++++++++++++++++++------------------------ chipsets.h | 5 ++++- 2 files changed, 33 insertions(+), 25 deletions(-) diff --git a/FastLED.h b/FastLED.h index e3dc4a77..c3800bee 100644 --- a/FastLED.h +++ b/FastLED.h @@ -21,6 +21,7 @@ enum ESPIChipsets { LPD8806, WS2801, + WS2803, SM16716, P9813 }; @@ -81,78 +82,82 @@ public: static CLEDController &addLeds(CLEDController *pLed, const struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0); - template static CLEDController &addLeds(const struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) { - switch(CHIPSET) { + template static CLEDController &addLeds(const struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) { + switch(CHIPSET) { case LPD8806: { static LPD8806Controller c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); } case WS2801: { static WS2801Controller c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); } + case WS2803: { static WS2803Controller c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); } case SM16716: { static SM16716Controller c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); } + case P9813: { static P9813Controller c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); } } } - template static CLEDController &addLeds(const struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) { - switch(CHIPSET) { + template static CLEDController &addLeds(const struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) { + switch(CHIPSET) { case LPD8806: { static LPD8806Controller c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); } case WS2801: { static WS2801Controller c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); } + case WS2803: { static WS2803Controller c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); } case SM16716: { static SM16716Controller c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); } case P9813: { static P9813Controller c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); } } } - - template CLEDController &addLeds(const struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) { - switch(CHIPSET) { + + template CLEDController &addLeds(const struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) { + switch(CHIPSET) { case LPD8806: { static LPD8806Controller c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); } case WS2801: { static WS2801Controller c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); } + case WS2803: { static WS2803Controller c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); } case SM16716: { static SM16716Controller c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); } case P9813: { static P9813Controller c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); } } } #ifdef SPI_DATA - template static CLEDController &addLeds(const struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) { + template static CLEDController &addLeds(const struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) { return addLeds(data, nLedsOrOffset, nLedsIfOffset); - } + } - template static CLEDController &addLeds(const struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) { + template static CLEDController &addLeds(const struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) { return addLeds(data, nLedsOrOffset, nLedsIfOffset); - } + } - template static CLEDController &addLeds(const struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) { + template static CLEDController &addLeds(const struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) { return addLeds(data, nLedsOrOffset, nLedsIfOffset); - } + } #endif template class CHIPSET, uint8_t DATA_PIN> static CLEDController &addLeds(const struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) { - static CHIPSET c; + static CHIPSET c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); - } + } template class CHIPSET, uint8_t DATA_PIN, EOrder RGB_ORDER> static CLEDController &addLeds(const struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) { - static CHIPSET c; + static CHIPSET c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); - } + } template class CHIPSET, uint8_t DATA_PIN> static CLEDController &addLeds(const struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) { - static CHIPSET c; + static CHIPSET c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); - } + } #ifdef FASTSPI_USE_DMX_SIMPLE - template + template static CLEDController &addLeds(const struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) { - switch(CHIPSET) { + switch(CHIPSET) { case DMX: { static DMXController controller; return addLeds(&controller, data, nLedsOrOffset, nLedsIfOffset); } } } - template + template static CLEDController &addLeds(const struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) { - switch(CHIPSET) { + switch(CHIPSET) { case DMX: {static DMXController controller; return addLeds(&controller, data, nLedsOrOffset, nLedsIfOffset); } } } @@ -160,7 +165,7 @@ public: #ifdef HAS_BLOCKLESS template - static CLEDController &addLeds(const struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) { + static CLEDController &addLeds(const struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) { switch(CHIPSET) { case WS2811_PORTC: return addLeds(new BlockClocklessController(), data, nLedsOrOffset, nLedsIfOffset); } diff --git a/chipsets.h b/chipsets.h index d628bd9a..e82fa295 100644 --- a/chipsets.h +++ b/chipsets.h @@ -17,7 +17,7 @@ class LPD8806Controller : public CLEDController { class LPD8806_ADJUST { public: // LPD8806 spec wants the high bit of every rgb data byte sent out to be set. - __attribute__((always_inline)) inline static uint8_t adjust(register uint8_t data) { return ((data>>1) | 0x80) + ((data!=255) & 0x01); } + __attribute__((always_inline)) inline static uint8_t adjust(register uint8_t data) { return ((data>>1) | 0x80) + ((data<254) & 0x01); } __attribute__((always_inline)) inline static void postBlock(int len) { SPI::writeBytesValueRaw(0, ((len+63)>>6)); } @@ -116,6 +116,9 @@ public: #endif }; +template +class WS2803Controller : public WS2801Controller {}; + ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // P9813 definition - takes data/clock/select pin values (N.B. should take an SPI definition?) -- cgit v1.2.3 From fc1de94a66038985760ac7721c6b518ad8c88973 Mon Sep 17 00:00:00 2001 From: Mark Kriegsman Date: Sun, 11 May 2014 17:20:40 -0400 Subject: added map8(in,rangeStart,rangeEnd) --- lib8tion.h | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/lib8tion.h b/lib8tion.h index 84ae3dde..8e53dd05 100644 --- a/lib8tion.h +++ b/lib8tion.h @@ -125,6 +125,8 @@ == from + (( to - from ) * fract8) / 256) lerp16by16( fromU16, toU16, fract16 ) == from + (( to - from ) * fract16) / 65536) + map8( in, rangeStart, rangeEnd) + == map( in, 0, 255, rangeStart, rangeEnd); - Optimized memmove, memcpy, and memset, that are faster than standard avr-libc 1.8. @@ -1346,6 +1348,28 @@ LIB8STATIC int16_t lerp15by8( int16_t a, int16_t b, fract8 frac) return result; } +// map8: map from one full-range 8-bit value into a narrower +// range of 8-bit values, possibly a range of hues. +// +// E.g. map myValue into a hue in the range blue..purple..pink..red +// hue = map8( myValue, HUE_BLUE, HUE_RED); +// +// Combines nicely with the waveform functions (like sin8, etc) +// to produce continuous hue gradients back and forth: +// hue = map8( sin8( myValue), HUE_BLUE, HUE_RED); +// +// Mathematically simiar to lerp8by8, but arguments are more +// like Arduino's "map"; this function is similar to +// map( in, 0, 255, rangeStart, rangeEnd) +// but faster and specifically designed for 8-bit values. +LIB8STATIC uint8_t map8( uint8_t in, uint8_t rangeStart, uint8_t rangeEnd) +{ + uint8_t rangeWidth = rangeEnd - rangeStart; + uint8_t out = scale8( in, rangeWidth); + out += rangeStart; + return out; +} + /////////////////////////////////////////////////////////////////////// // -- cgit v1.2.3 From 436789ed14183d13b5d6b8114ff19f24e2690951 Mon Sep 17 00:00:00 2001 From: Mark Kriegsman Date: Sun, 11 May 2014 17:40:17 -0400 Subject: Dropped VIRTUAL_BITS from the hopelessly unrealistic '8' to the only modestly unrealistic '3', and added notes on how this is calculated and how we might auto-adjust it in the future. --- controller.h | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/controller.h b/controller.h index 6a3660d6..80de389d 100644 --- a/controller.h +++ b/controller.h @@ -201,8 +201,31 @@ struct PixelController { void init_binary_dithering() { #if !defined(NO_DITHERING) || (NO_DITHERING != 1) - -#define VIRTUAL_BITS 8 + + // Set 'virtual bits' of dithering to the highest level + // that is not likely to cause excessive flickering at + // low brightness levels + low update rates. + // These pre-set values are a little ambitious, since + // a 400Hz update rate for WS2811-family LEDs is only + // possible with 85 pixels or fewer. + // Once we have a 'number of milliseconds since last update' + // value available here, we can quickly calculate the correct + // number of 'virtual bits' on the fly with a couple of 'if' + // statements -- no division required. At this point, + // the division is done at compile time, so there's no runtime + // cost, but the values are still hard-coded. +#define MAX_LIKELY_UPDATE_RATE_HZ 400 +#define MIN_ACCEPTABLE_DITHER_RATE_HZ 50 +#define UPDATES_PER_FULL_DITHER_CYCLE (MAX_LIKELY_UPDATE_RATE_HZ / MIN_ACCEPTABLE_DITHER_RATE_HZ) +#define RECOMMENDED_VIRTUAL_BITS ((UPDATES_PER_FULL_DITHER_CYCLE>1) + \ + (UPDATES_PER_FULL_DITHER_CYCLE>2) + \ + (UPDATES_PER_FULL_DITHER_CYCLE>4) + \ + (UPDATES_PER_FULL_DITHER_CYCLE>8) + \ + (UPDATES_PER_FULL_DITHER_CYCLE>16) + \ + (UPDATES_PER_FULL_DITHER_CYCLE>32) + \ + (UPDATES_PER_FULL_DITHER_CYCLE>64) + \ + (UPDATES_PER_FULL_DITHER_CYCLE>128) ) +#define VIRTUAL_BITS RECOMMENDED_VIRTUAL_BITS // R is the digther signal 'counter'. static byte R = 0; R++; -- cgit v1.2.3 From 4c546b3f6b68629920d01567b62410f6d67f9e76 Mon Sep 17 00:00:00 2001 From: Mark Kriegsman Date: Sun, 11 May 2014 17:42:20 -0400 Subject: Noted map8 and change to VIRTUAL_BITS of dithering from a flickery 8 to a more solid 3. --- preview_changes.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/preview_changes.txt b/preview_changes.txt index 975cd3f6..c39919ad 100644 --- a/preview_changes.txt +++ b/preview_changes.txt @@ -13,3 +13,5 @@ * Added XY Matrix example * Added Fire2012 example, added HeatColor(...) to the library * Added sin8, cos8, quadwave8, cubicwave8, triwave8, and ease8InOutQuad +* Added map8 +* Adjusted VIRTAL_BITS of dithering from a flickery 8 to a more solid 3 -- cgit v1.2.3 From 081b0395791c73e0705b05b27831ef622e1124c9 Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Wed, 14 May 2014 11:08:14 -0700 Subject: more tweaking for lpd8806 --- chipsets.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chipsets.h b/chipsets.h index e82fa295..b93058c6 100644 --- a/chipsets.h +++ b/chipsets.h @@ -17,7 +17,7 @@ class LPD8806Controller : public CLEDController { class LPD8806_ADJUST { public: // LPD8806 spec wants the high bit of every rgb data byte sent out to be set. - __attribute__((always_inline)) inline static uint8_t adjust(register uint8_t data) { return ((data>>1) | 0x80) + ((data<254) & 0x01); } + __attribute__((always_inline)) inline static uint8_t adjust(register uint8_t data) { return ((data>>1) | 0x80) + ((data && (data<254)) & 0x01); } __attribute__((always_inline)) inline static void postBlock(int len) { SPI::writeBytesValueRaw(0, ((len+63)>>6)); } -- cgit v1.2.3 From 8e61630e4abf99d94b33dac2576619282cfe7262 Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Wed, 21 May 2014 01:02:55 -0700 Subject: Adding linear interpolation to CRGB pixels. --- pixeltypes.h | 85 +++++++++++++++++++++++++++++++++++++----------------------- 1 file changed, 53 insertions(+), 32 deletions(-) diff --git a/pixeltypes.h b/pixeltypes.h index 279b2055..4711acd1 100644 --- a/pixeltypes.h +++ b/pixeltypes.h @@ -111,19 +111,19 @@ struct CRGB { inline CRGB() __attribute__((always_inline)) { } - + // allow construction from R, G, B inline CRGB( uint8_t ir, uint8_t ig, uint8_t ib) __attribute__((always_inline)) : r(ir), g(ig), b(ib) { } - + // allow construction from 32-bit (really 24-bit) bit 0xRRGGBB color code inline CRGB( uint32_t colorcode) __attribute__((always_inline)) : r((colorcode >> 16) & 0xFF), g((colorcode >> 8) & 0xFF), b((colorcode >> 0) & 0xFF) { } - + inline CRGB( LEDColorCorrection colorcode) __attribute__((always_inline)) : r((colorcode >> 16) & 0xFF), g((colorcode >> 8) & 0xFF), b((colorcode >> 0) & 0xFF) { @@ -133,7 +133,7 @@ struct CRGB { inline CRGB( ColorTemperature colorcode) __attribute__((always_inline)) : r((colorcode >> 16) & 0xFF), g((colorcode >> 8) & 0xFF), b((colorcode >> 0) & 0xFF) { - + } // allow copy construction @@ -143,7 +143,7 @@ struct CRGB { g = rhs.g; b = rhs.b; } - + // allow construction from HSV color inline CRGB(const CHSV& rhs) __attribute__((always_inline)) { @@ -157,7 +157,7 @@ struct CRGB { g = rhs.g; b = rhs.b; return *this; - } + } // allow assignment from 32-bit (really 24-bit) 0xRRGGBB color code inline CRGB& operator= (const uint32_t colorcode) __attribute__((always_inline)) @@ -167,7 +167,7 @@ struct CRGB { b = (colorcode >> 0) & 0xFF; return *this; } - + // allow assignment from R, G, and B inline CRGB& setRGB (uint8_t nr, uint8_t ng, uint8_t nb) __attribute__((always_inline)) { @@ -176,28 +176,28 @@ struct CRGB { b = nb; return *this; } - + // allow assignment from H, S, and V inline CRGB& setHSV (uint8_t hue, uint8_t sat, uint8_t val) __attribute__((always_inline)) { hsv2rgb_rainbow( CHSV(hue, sat, val), *this); return *this; } - + // allow assignment from just a Hue, saturation and value automatically at max. inline CRGB& setHue (uint8_t hue) __attribute__((always_inline)) { hsv2rgb_rainbow( CHSV(hue, 255, 255), *this); return *this; } - + // allow assignment from HSV color inline CRGB& operator= (const CHSV& rhs) __attribute__((always_inline)) { hsv2rgb_rainbow( rhs, *this); return *this; } - + // allow assignment from 32-bit (really 24-bit) 0xRRGGBB color code inline CRGB& setColorCode (uint32_t colorcode) __attribute__((always_inline)) { @@ -206,7 +206,7 @@ struct CRGB { b = (colorcode >> 0) & 0xFF; return *this; } - + // add one RGB to another, saturating at 0xFF for each channel inline CRGB& operator+= (const CRGB& rhs ) @@ -216,7 +216,7 @@ struct CRGB { b = qadd8( b, rhs.b); return *this; } - + // add a contstant to each channel, saturating at 0xFF // this is NOT an operator+= overload because the compiler // can't usefully decide when it's being passed a 32-bit @@ -228,7 +228,7 @@ struct CRGB { b = qadd8( b, d); return *this; } - + // subtract one RGB from another, saturating at 0x00 for each channel inline CRGB& operator-= (const CRGB& rhs ) { @@ -237,7 +237,7 @@ struct CRGB { b = qsub8( b, rhs.b); return *this; } - + // subtract a constant from each channel, saturating at 0x00 // this is NOT an operator+= overload because the compiler // can't usefully decide when it's being passed a 32-bit @@ -249,14 +249,14 @@ struct CRGB { b = qsub8( b, d); return *this; } - + // subtract a constant of '1' from each channel, saturating at 0x00 inline CRGB& operator-- () __attribute__((always_inline)) { subtractFromRGB(1); return *this; } - + // subtract a constant of '1' from each channel, saturating at 0x00 inline CRGB operator-- (int DUMMY_ARG) __attribute__((always_inline)) { @@ -271,7 +271,7 @@ struct CRGB { addToRGB(1); return *this; } - + // add a constant of '1' from each channel, saturating at 0xFF inline CRGB operator++ (int DUMMY_ARG) __attribute__((always_inline)) { @@ -288,7 +288,7 @@ struct CRGB { b /= d; return *this; } - + // multiply each of the channels by a constant, // saturating each channel at 0xFF inline CRGB& operator*= (uint8_t d ) @@ -309,7 +309,7 @@ struct CRGB { nscale8x3_video( r, g, b, scaledown); return *this; } - + // %= is a synonym for nscale8_video. Think of it is scaling down // by "a percentage" inline CRGB& operator%= (uint8_t scaledown ) @@ -324,7 +324,7 @@ struct CRGB { nscale8x3_video( r, g, b, 255 - fadefactor); return *this; } - + // scale down a RGB to N 256ths of it's current brightness, using // 'plain math' dimming rules, which means that if the low light levels // may dim all the way to 100% black. @@ -340,7 +340,7 @@ struct CRGB { nscale8x3( r, g, b, 255 - fadefactor); return *this; } - + // "or" operator brings each channel up to the higher of the two values inline CRGB& operator|= (const CRGB& rhs ) { @@ -356,7 +356,7 @@ struct CRGB { if( d > b) b = d; return *this; } - + // "and" operator brings each channel down to the lower of the two values inline CRGB& operator&= (const CRGB& rhs ) { @@ -372,13 +372,13 @@ struct CRGB { if( d < b) b = d; return *this; } - + // this allows testing a CRGB for zero-ness inline operator bool() const __attribute__((always_inline)) { return r || g || b; } - + // invert each channel inline CRGB operator- () { @@ -388,19 +388,19 @@ struct CRGB { retval.b = 255 - b; return retval; } - - + + inline uint8_t getLuma ( ) { //Y' = 0.2126 R' + 0.7152 G' + 0.0722 B' // 54 183 18 (!) - + uint8_t luma = scale8_LEAVING_R1_DIRTY( r, 54) + \ scale8_LEAVING_R1_DIRTY( g, 183) + \ scale8_LEAVING_R1_DIRTY( b, 18); cleanup_R1(); return luma; } - + inline uint8_t getAverageLight( ) { const uint8_t eightysix = 86; uint8_t avg = scale8_LEAVING_R1_DIRTY( r, eightysix) + \ @@ -419,7 +419,28 @@ struct CRGB { green = (green * factor) / 256; blue = (blue * factor) / 256; } - + + inline CRGB lerp8( CRGB & other, fract8 frac) + { + CRGB ret; + + ret.r = lerp16by8(r<<8,other.r<<8,frac)>>8; + ret.g = lerp16by8(g<<8,other.g<<8,frac)>>8; + ret.b = lerp16by8(b<<8,other.b<<8,frac)>>8; + + return ret; + } + + inline CRGB lerp16( CRGB & other, fract16 frac) + { + CRGB ret; + + ret.r = lerp16by16(r<<8,other.r<<8,frac)>>8; + ret.g = lerp16by16(g<<8,other.g<<8,frac)>>8; + ret.b = lerp16by16(b<<8,other.b<<8,frac)>>8; + + return ret; + } typedef enum { AliceBlue=0xF0F8FF, Amethyst=0x9966CC, @@ -647,7 +668,7 @@ inline CRGB operator/( const CRGB& p1, uint8_t d) return CRGB( p1.r/d, p1.g/d, p1.b/d); } - + __attribute__((always_inline)) inline CRGB operator&( const CRGB& p1, const CRGB& p2) { @@ -655,7 +676,7 @@ inline CRGB operator&( const CRGB& p1, const CRGB& p2) p1.g < p2.g ? p1.g : p2.g, p1.b < p2.b ? p1.b : p2.b); } - + __attribute__((always_inline)) inline CRGB operator|( const CRGB& p1, const CRGB& p2) { -- cgit v1.2.3 From 9d3a2a45d7c33b2bb9bfc28d4c0a113c39d41354 Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Fri, 23 May 2014 13:02:08 -0700 Subject: Try fixing bitbang'd spi output --- fastspi_bitbang.h | 116 +++++++++++++++++++++++++++--------------------------- 1 file changed, 59 insertions(+), 57 deletions(-) diff --git a/fastspi_bitbang.h b/fastspi_bitbang.h index 24d2e41e..fe5fe19c 100644 --- a/fastspi_bitbang.h +++ b/fastspi_bitbang.h @@ -10,7 +10,7 @@ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// template -class AVRSoftwareSPIOutput { +class AVRSoftwareSPIOutput { // The data types for pointers to the pin port - typedef'd here from the Pin definition because on avr these // are pointers to 8 bit values, while on arm they are 32 bit typedef typename FastPin::port_ptr_t data_ptr_t; @@ -41,14 +41,14 @@ public: // wait until the SPI subsystem is ready for more data to write. A NOP when bitbanging static void wait() __attribute__((always_inline)) { } static void waitFully() __attribute__((always_inline)) { wait(); } - + static void writeByteNoWait(uint8_t b) __attribute__((always_inline)) { writeByte(b); } static void writeBytePostWait(uint8_t b) __attribute__((always_inline)) { writeByte(b); wait(); } static void writeWord(uint16_t w) __attribute__((always_inline)) { writeByte(w>>8); writeByte(w&0xFF); } - + // naive writeByte implelentation, simply calls writeBit on the 8 bits in the byte. - static void writeByte(uint8_t b) { + static void writeByte(uint8_t b) { writeBit<7>(b); writeBit<6>(b); writeBit<5>(b); @@ -59,9 +59,9 @@ public: writeBit<0>(b); } -private: +private: // writeByte implementation with data/clock registers passed in. - static void writeByte(uint8_t b, clock_ptr_t clockpin, data_ptr_t datapin) { + static void writeByte(uint8_t b, clock_ptr_t clockpin, data_ptr_t datapin) { writeBit<7>(b, clockpin, datapin); writeBit<6>(b, clockpin, datapin); writeBit<5>(b, clockpin, datapin); @@ -73,11 +73,11 @@ private: } // writeByte implementation with the data register passed in and prebaked values for data hi w/clock hi and - // low and data lo w/clock hi and lo. This is to be used when clock and data are on the same GPIO register, + // low and data lo w/clock hi and lo. This is to be used when clock and data are on the same GPIO register, // can get close to getting a bit out the door in 2 clock cycles! - static void writeByte(uint8_t b, data_ptr_t datapin, - data_t hival, data_t loval, - clock_t hiclock, clock_t loclock) { + static void writeByte(uint8_t b, data_ptr_t datapin, + data_t hival, data_t loval, + clock_t hiclock, clock_t loclock) { writeBit<7>(b, datapin, hival, loval, hiclock, loclock); writeBit<6>(b, datapin, hival, loval, hiclock, loclock); writeBit<5>(b, datapin, hival, loval, hiclock, loclock); @@ -91,9 +91,9 @@ private: // writeByte implementation with not just registers passed in, but pre-baked values for said registers for // data hi/lo and clock hi/lo values. Note: weird things will happen if this method is called in cases where // the data and clock pins are on the same port! Don't do that! - static void writeByte(uint8_t b, clock_ptr_t clockpin, data_ptr_t datapin, - data_t hival, data_t loval, - clock_t hiclock, clock_t loclock) { + static void writeByte(uint8_t b, clock_ptr_t clockpin, data_ptr_t datapin, + data_t hival, data_t loval, + clock_t hiclock, clock_t loclock) { writeBit<7>(b, clockpin, datapin, hival, loval, hiclock, loclock); writeBit<6>(b, clockpin, datapin, hival, loval, hiclock, loclock); writeBit<5>(b, clockpin, datapin, hival, loval, hiclock, loclock); @@ -108,34 +108,34 @@ public: #define SPI_DELAY delaycycles< (SPI_SPEED-2) / 2>(); // write the BIT'th bit out via spi, setting the data pin then strobing the clcok - template __attribute__((always_inline, hot)) inline static void writeBit(uint8_t b) { - if(b & (1 << BIT)) { + template __attribute__((always_inline, hot)) inline static void writeBit(uint8_t b) { + if(b & (1 << BIT)) { FastPin::hi(); - if(SPI_SPEED < 3) { + if(SPI_SPEED < 3) { FastPin::strobe(); - } else { + } else { FastPin::hi(); SPI_DELAY; FastPin::lo(); SPI_DELAY; } - } else { + } else { FastPin::lo(); - if(SPI_SPEED < 3) { + if(SPI_SPEED < 3) { FastPin::strobe(); - } else { + } else { FastPin::hi(); SPI_DELAY; FastPin::lo(); SPI_DELAY; } } } - + private: // write the BIT'th bit out via spi, setting the data pin then strobing the clock, using the passed in pin registers to accelerate access if needed - template __attribute__((always_inline)) inline static void writeBit(uint8_t b, clock_ptr_t clockpin, data_ptr_t datapin) { - if(b & (1 << BIT)) { + template __attribute__((always_inline)) inline static void writeBit(uint8_t b, clock_ptr_t clockpin, data_ptr_t datapin) { + if(b & (1 << BIT)) { FastPin::hi(datapin); FastPin::hi(clockpin); SPI_DELAY; FastPin::lo(clockpin); SPI_DELAY; - } else { + } else { FastPin::lo(datapin); FastPin::hi(clockpin); SPI_DELAY; FastPin::lo(clockpin); SPI_DELAY; @@ -145,14 +145,14 @@ private: // the version of write to use when clock and data are on separate pins with precomputed values for setting // the clock and data pins - template __attribute__((always_inline)) inline static void writeBit(uint8_t b, clock_ptr_t clockpin, data_ptr_t datapin, - data_t hival, data_t loval, clock_t hiclock, clock_t loclock) { + template __attribute__((always_inline)) inline static void writeBit(uint8_t b, clock_ptr_t clockpin, data_ptr_t datapin, + data_t hival, data_t loval, clock_t hiclock, clock_t loclock) { // // only need to explicitly set clock hi if clock and data are on different ports - if(b & (1 << BIT)) { + if(b & (1 << BIT)) { FastPin::fastset(datapin, hival); FastPin::fastset(clockpin, hiclock); SPI_DELAY; FastPin::fastset(clockpin, loclock); SPI_DELAY; - } else { + } else { // NOP; FastPin::fastset(datapin, loval); FastPin::fastset(clockpin, hiclock); SPI_DELAY; @@ -162,17 +162,17 @@ private: // the version of write to use when clock and data are on the same port with precomputed values for the various // combinations - template __attribute__((always_inline)) inline static void writeBit(uint8_t b, data_ptr_t clockdatapin, - data_t datahiclockhi, data_t dataloclockhi, - data_t datahiclocklo, data_t dataloclocklo) { + template __attribute__((always_inline)) inline static void writeBit(uint8_t b, data_ptr_t clockdatapin, + data_t datahiclockhi, data_t dataloclockhi, + data_t datahiclocklo, data_t dataloclocklo) { #if 0 writeBit(b); #else - if(b & (1 << BIT)) { + if(b & (1 << BIT)) { FastPin::fastset(clockdatapin, datahiclocklo); SPI_DELAY; FastPin::fastset(clockdatapin, datahiclockhi); SPI_DELAY; FastPin::fastset(clockdatapin, datahiclocklo); SPI_DELAY; - } else { + } else { // NOP; FastPin::fastset(clockdatapin, dataloclocklo); SPI_DELAY; FastPin::fastset(clockdatapin, dataloclockhi); SPI_DELAY; @@ -190,7 +190,7 @@ public: void release() { if(m_pSelect != NULL) { m_pSelect->release(); } } // FastPin::lo(); } // Write out len bytes of the given value out over SPI. Useful for quickly flushing, say, a line of 0's down the line. - void writeBytesValue(uint8_t value, int len) { + void writeBytesValue(uint8_t value, int len) { select(); writeBytesValueRaw(value, len); release(); @@ -201,7 +201,7 @@ public: // TODO: Weird things may happen if software bitbanging SPI output and other pins on the output reigsters are being twiddled. Need // to allow specifying whether or not exclusive i/o access is allowed during this process, and if i/o access is not allowed fall // back to the degenerative code below - while(len--) { + while(len--) { writeByte(value); } #else @@ -215,18 +215,18 @@ public: register data_t datalo = FastPin::loval(); register clock_t clockhi = FastPin::hival(); register clock_t clocklo = FastPin::loval(); - while(len--) { + while(len--) { writeByte(value, clockpin, datapin, datahi, datalo, clockhi, clocklo); } } else { - // If data and clock are on the same port then we can combine setting the data and clock pins + // If data and clock are on the same port then we can combine setting the data and clock pins register data_t datahi_clockhi = FastPin::hival() | FastPin::mask(); register data_t datalo_clockhi = FastPin::loval() | FastPin::mask(); register data_t datahi_clocklo = FastPin::hival() & ~FastPin::mask(); register data_t datalo_clocklo = FastPin::loval() & ~FastPin::mask(); - while(len--) { + while(len--) { writeByte(value, datapin, datahi_clockhi, datalo_clockhi, datahi_clocklo, datalo_clocklo); } } @@ -234,12 +234,12 @@ public: } // write a block of len uint8_ts out. Need to type this better so that explicit casts into the call aren't required. - // note that this template version takes a class parameter for a per-byte modifier to the data. - template void writeBytes(register uint8_t *data, int len) { + // note that this template version takes a class parameter for a per-byte modifier to the data. + template void writeBytes(register uint8_t *data, int len) { select(); #ifdef FAST_SPI_INTERRUPTS_WRITE_PINS uint8_t *end = data + len; - while(data != end) { + while(data != end) { writeByte(D::adjust(*data++)); } #else @@ -255,28 +255,28 @@ public: register clock_t clocklo = FastPin::loval(); uint8_t *end = data + len; - while(data != end) { + while(data != end) { writeByte(D::adjust(*data++), clockpin, datapin, datahi, datalo, clockhi, clocklo); } } else { // FastPin::hi(); - // If data and clock are on the same port then we can combine setting the data and clock pins + // If data and clock are on the same port then we can combine setting the data and clock pins register data_t datahi_clockhi = FastPin::hival() | FastPin::mask(); register data_t datalo_clockhi = FastPin::loval() | FastPin::mask(); register data_t datahi_clocklo = FastPin::hival() & ~FastPin::mask(); register data_t datalo_clocklo = FastPin::loval() & ~FastPin::mask(); - + uint8_t *end = data + len; - while(data != end) { + while(data != end) { writeByte(D::adjust(*data++), datapin, datahi_clockhi, datalo_clockhi, datahi_clocklo, datalo_clocklo); } // FastPin::lo(); } #endif D::postBlock(len); - release(); + release(); } // default version of writing a block of data out to the SPI port, with no data modifications being made @@ -286,15 +286,15 @@ public: // 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 of each grouping, as well as a class specifying a per // byte of data modification to be made. (See DATA_NOP above) - template __attribute__((noinline)) void writePixels(PixelController pixels) { + template __attribute__((noinline)) void writePixels(PixelController pixels) { select(); int len = pixels.mLen; #ifdef FAST_SPI_INTERRUPTS_WRITE_PINS // If interrupts or other things may be generating output while we're working on things, then we need // to use this block - while(pixels.has(1)) { - if(FLAGS & FLAG_START_BIT) { + while(pixels.has(1)) { + if(FLAGS & FLAG_START_BIT) { writeBit<0>(1); } writeByte(D::adjust(pixels.loadAndScale0())); @@ -316,9 +316,9 @@ public: register data_t datalo = FastPin::loval(); register clock_t clockhi = FastPin::hival(); register clock_t clocklo = FastPin::loval(); - - while(pixels.has(1)) { - if(FLAGS & FLAG_START_BIT) { + + while(pixels.has(1)) { + if(FLAGS & FLAG_START_BIT) { writeBit<0>(1, clockpin, datapin, datahi, datalo, clockhi, clocklo); } writeByte(D::adjust(pixels.loadAndScale0()), clockpin, datapin, datahi, datalo, clockhi, clocklo); @@ -329,14 +329,14 @@ public: } } else { - // If data and clock are on the same port then we can combine setting the data and clock pins + // If data and clock are on the same port then we can combine setting the data and clock pins register data_t datahi_clockhi = FastPin::hival() | FastPin::mask(); register data_t datalo_clockhi = FastPin::loval() | FastPin::mask(); register data_t datahi_clocklo = FastPin::hival() & ~FastPin::mask(); register data_t datalo_clocklo = FastPin::loval() & ~FastPin::mask(); - - while(pixels.has(1)) { - if(FLAGS & FLAG_START_BIT) { + + while(pixels.has(1)) { + if(FLAGS & FLAG_START_BIT) { writeBit<0>(1, datapin, datahi_clockhi, datalo_clockhi, datahi_clocklo, datalo_clocklo); } writeByte(D::adjust(pixels.loadAndScale0()), datapin, datahi_clockhi, datalo_clockhi, datahi_clocklo, datalo_clocklo); @@ -345,9 +345,11 @@ public: pixels.advanceData(); pixels.stepDithering(); } - } + } #endif D::postBlock(len); + FastPin::hi(); SPI_DELAY; + FastPin::lo(); release(); } }; -- cgit v1.2.3 From c7578996f3d0be96ac8cdbfb9318067847b44497 Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Sat, 24 May 2014 19:02:59 -0700 Subject: Add a clock toggle to the end of all the spi work --- fastspi_arm_k20.h | 79 +++++++++++++++++++------------------- fastspi_arm_sam.h | 41 ++++++++++---------- fastspi_avr.h | 111 +++++++++++++++++++++++++++--------------------------- 3 files changed, 117 insertions(+), 114 deletions(-) diff --git a/fastspi_arm_k20.h b/fastspi_arm_k20.h index f8004331..2e29a27f 100644 --- a/fastspi_arm_k20.h +++ b/fastspi_arm_k20.h @@ -12,16 +12,16 @@ #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, +// 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 class BitWork { - public: - static int highestBit() __attribute__((always_inline)) { return (VAL & 1 << BIT) ? BIT : BitWork::highestBit(); } +template class BitWork { + public: + static int highestBit() __attribute__((always_inline)) { return (VAL & 1 << BIT) ? BIT : BitWork::highestBit(); } }; -template class BitWork { - public: - static int highestBit() __attribute__((always_inline)) { return 0; } +template class BitWork { + public: + static int highestBit() __attribute__((always_inline)) { return 0; } }; #define MAX(A, B) (( (A) > (B) ) ? (A) : (B)) @@ -77,7 +77,7 @@ template void getScalars(uint32_t & preScalar, uint32_t & scalar, uint #define SPIX (*(SPI_t*)pSPIX) template -class ARMHardwareSPIOutput { +class ARMHardwareSPIOutput { Selectable *m_pSelect; // Borrowed from the teensy3 SPSR emulation code @@ -112,7 +112,7 @@ public: SPIX.MCR = mcr; } - } + } static inline void update_ctar1(uint32_t ctar) __attribute__((always_inline)) { if (SPIX.CTAR1 == ctar) return; @@ -123,11 +123,11 @@ public: SPIX.MCR = mcr | SPI_MCR_MDIS | SPI_MCR_HALT; SPIX.CTAR1 = ctar; SPIX.MCR = mcr; - + } - } + } - void setSPIRate() { + void setSPIRate() { // Configure CTAR0, defaulting to 8 bits and CTAR1, defaulting to 16 bits uint32_t _PBR = 0; uint32_t _BR = 0; @@ -157,7 +157,7 @@ public: ctar1 |= SPI_CTAR_CPHA | SPI_CTAR_CPOL; #endif - if(_DBR) { + if(_DBR) { ctar0 |= SPI_CTAR_DBR; ctar1 |= SPI_CTAR_DBR; } @@ -166,7 +166,7 @@ public: update_ctar1(ctar1); } - + void init() { // set the pins to output FastPin<_DATA_PIN>::setOutput(); @@ -190,23 +190,23 @@ public: } setSPIRate(); - // Configure SPI as the master and enable + // Configure SPI as the master and enable SPIX.MCR |= SPI_MCR_MSTR; // | SPI_MCR_CONT_SCKE); SPIX.MCR &= ~(SPI_MCR_MDIS | SPI_MCR_HALT); enable_pins(); } - static void waitFully() __attribute__((always_inline)) { - while( (SPIX.SR & 0xF000) > 0); - while (!(SPIX.SR & SPI_SR_TCF)); - SPIX.SR |= (SPI_SR_TCF | SPI_SR_EOQF); + static void waitFully() __attribute__((always_inline)) { + while( (SPIX.SR & 0xF000) > 0); + 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 }; @@ -218,20 +218,20 @@ public: #endif #define WM PRE - template class Write { + template class Write { public: - static void writeWord(uint16_t w) __attribute__((always_inline)) { + 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) | + ((CONT_STATE == CONT) ? SPI_PUSHR_CONT : 0) | SPI_PUSHR_CTAS(1) | (w & 0xFFFF); if(WAIT_STATE == POST) { wait(); } } - static void writeByte(uint8_t b) __attribute__((always_inline)) { + 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) | + ((CONT_STATE == CONT) ? SPI_PUSHR_CONT : 0) | SPI_PUSHR_CTAS(0) | (b & 0xFF); if(WAIT_STATE == POST) { wait(); } } @@ -252,7 +252,7 @@ public: static void writeByteContNoWait(uint8_t b) __attribute__((always_inline)) { SPIX.PUSHR = SPI_PUSHR_CONT | SPI_PUSHR_CTAS(0) | (b & 0xFF); } // not the most efficient mechanism in the world - but should be enough for sm16716 and friends - template inline static void writeBit(uint8_t b) { + template 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 @@ -264,35 +264,35 @@ public: update_ctar1(ctar1_save); } - void inline select() __attribute__((always_inline)) { if(m_pSelect != NULL) { m_pSelect->select(); } } - void inline release() __attribute__((always_inline)) { if(m_pSelect != NULL) { m_pSelect->release(); } } + void inline select() __attribute__((always_inline)) { if(m_pSelect != NULL) { m_pSelect->select(); } } + void inline release() __attribute__((always_inline)) { if(m_pSelect != NULL) { m_pSelect->release(); } } static void writeBytesValueRaw(uint8_t value, int len) { while(len--) { Write::writeByte(value); } } - void writeBytesValue(uint8_t value, int len) { + void writeBytesValue(uint8_t value, int len) { setSPIRate(); select(); - while(len--) { + while(len--) { writeByte(value); } waitFully(); release(); } - - // Write a block of n uint8_ts out - template void writeBytes(register uint8_t *data, int len) { + + // Write a block of n uint8_ts out + template 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) { + while(data != end) { writeByte(D::adjust(*data++)); } D::postBlock(len); waitFully(); - release(); + release(); } void writeBytes(register uint8_t *data, int len) { writeBytes(data, len); } @@ -304,7 +304,7 @@ public: select(); int len = pixels.mLen; - // Setup the pixel controller + // 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)) { @@ -315,14 +315,14 @@ public: // Load and write out the next two bytes (step dithering, advance data in between since we // cross pixels here) Write::writeWord(D::adjust(pixels.loadAndScale2()) << 8 | D::adjust(pixels.stepAdvanceAndLoadAndScale0())); - + // Load and write out the next two bytes Write::writeWord(D::adjust(pixels.loadAndScale1()) << 8 | D::adjust(pixels.loadAndScale2())); pixels.stepDithering(); pixels.advanceData(); } - if(pixels.has(1)) { + if(pixels.has(1)) { if(WM == NONE) { wait1(); } // write out the rest as alternating 16/8-bit blocks (likely to be just one) Write::writeWord(D::adjust(pixels.loadAndScale0()) << 8 | D::adjust(pixels.loadAndScale1())); @@ -338,7 +338,7 @@ public: uint32_t ctar1 = (ctar1_save & (~SPI_CTAR_FMSZ(15))) | SPI_CTAR_FMSZ(8); update_ctar1(ctar1); - while(pixels.has(1)) { + while(pixels.has(1)) { writeWord( 0x100 | D::adjust(pixels.loadAndScale0())); writeByte(D::adjust(pixels.loadAndScale1())); writeByte(D::adjust(pixels.loadAndScale2())); @@ -350,6 +350,7 @@ public: // restore ctar1 update_ctar1(ctar1_save); + FastPin<_CLOCK_PIN>::toggle(); } release(); } diff --git a/fastspi_arm_sam.h b/fastspi_arm_sam.h index 8f73b884..bc4bddc2 100644 --- a/fastspi_arm_sam.h +++ b/fastspi_arm_sam.h @@ -17,7 +17,7 @@ class SAMHardwareSPIOutput { 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) { + 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(); @@ -40,12 +40,12 @@ public: void init() { // m_SPI = SPI0; - // set the output pins master out, master in, clock. Note doing this here because I still don't + // 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 @@ -68,14 +68,14 @@ public: } // latch the CS select - void inline select() __attribute__((always_inline)) { if(m_pSelect != NULL) { m_pSelect->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(); } } + // 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); @@ -89,36 +89,36 @@ public: // 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 void writeBytes(register uint8_t *data, int len) { + template 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) { + while(data != end) { writeByte(D::adjust(*data++)); } D::postBlock(len); waitFully(); - release(); + release(); } void writeBytes(register uint8_t *data, int len) { writeBytes(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 inline void writeBit(uint8_t b) { + template inline void writeBit(uint8_t b) { // need to wait for all exisiting data to go out the door, first - waitFully(); + waitFully(); disableSPI(); - if(b & (1 << BIT)) { + if(b & (1 << BIT)) { FastPin<_DATA_PIN>::hi(); - } else { + } else { FastPin<_DATA_PIN>::lo(); } @@ -129,12 +129,12 @@ public: // 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 void writePixels(PixelController pixels) { + template void writePixels(PixelController pixels) { select(); int len = pixels.mLen; - if(FLAGS & FLAG_START_BIT) { - while(pixels.has(1)) { + 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())); @@ -142,7 +142,7 @@ public: pixels.stepDithering(); } } else { - while(pixels.has(1)) { + while(pixels.has(1)) { writeByte(D::adjust(pixels.loadAndScale0())); writeByte(D::adjust(pixels.loadAndScale1())); writeByte(D::adjust(pixels.loadAndScale2())); @@ -151,10 +151,11 @@ public: } } D::postBlock(len); + FastPin<_CLOCK_PIN>::toggle(); release(); } }; #endif -#endif \ No newline at end of file +#endif diff --git a/fastspi_avr.h b/fastspi_avr.h index e6e07fed..3319c9b9 100644 --- a/fastspi_avr.h +++ b/fastspi_avr.h @@ -13,7 +13,7 @@ #if defined(AVR_HARDWARE_SPI) #if defined(UBRR0) template -class AVRUSARTSPIOutput { +class AVRUSARTSPIOutput { Selectable *m_pSelect; public: @@ -21,7 +21,7 @@ public: AVRUSARTSPIOutput(Selectable *pSelect) { m_pSelect = pSelect; } void setSelect(Selectable *pSelect) { m_pSelect = pSelect; } - void init() { + void init() { UBRR0 = 0; UCSR0A = 1<>8); writeByte(w&0xFF); } - - template inline static void writeBit(uint8_t b) { - if(b && (1 << BIT)) { + + template inline static void writeBit(uint8_t b) { + if(b && (1 << BIT)) { FastPin<_DATA_PIN>::hi(); - } else { + } else { FastPin<_DATA_PIN>::lo(); } @@ -60,46 +60,46 @@ public: } void select() { if(m_pSelect != NULL) { m_pSelect->select(); } } // FastPin<_SELECT_PIN>::hi(); } - void release() { + void release() { // wait for all transmissions to finish while ((UCSR0A & (1 <release(); } // FastPin<_SELECT_PIN>::hi(); + if(m_pSelect != NULL) { m_pSelect->release(); } // FastPin<_SELECT_PIN>::hi(); } static void writeBytesValueRaw(uint8_t value, int len) { while(len--) { writeByte(value); } } - - void writeBytesValue(uint8_t value, int len) { + + void writeBytesValue(uint8_t value, int len) { select(); - while(len--) { + while(len--) { writeByte(value); } release(); } - - // Write a block of n uint8_ts out - template void writeBytes(register uint8_t *data, int len) { + + // Write a block of n uint8_ts out + template void writeBytes(register uint8_t *data, int len) { uint8_t *end = data + len; select(); - while(data != end) { + 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>(); } D::postBlock(len); - release(); + release(); } void writeBytes(register uint8_t *data, int len) { writeBytes(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 void writeBytes3(register uint8_t *data, int len, register uint8_t scale, bool advance=true, uint8_t skip=0) { + template void writeBytes3(register uint8_t *data, int len, register uint8_t scale, bool advance=true, uint8_t skip=0) { uint8_t *end = data + len; PixelController pixels(data, scale, true, advance, skip); select(); - while(data != end) { - if(FLAGS & FLAG_START_BIT) { + while(data != end) { + if(FLAGS & FLAG_START_BIT) { writeBit<0>(1); } writeByte(D::adjust(pixels.loadAndScale0())); @@ -114,17 +114,17 @@ public: } // template instantiations for writeBytes 3 - template void writeBytes3(register uint8_t *data, int len, register uint8_t scale, bool advance=true, uint8_t skip=0) { - writeBytes3(data, len, scale, advance, skip); + template void writeBytes3(register uint8_t *data, int len, register uint8_t scale, bool advance=true, uint8_t skip=0) { + writeBytes3(data, len, scale, advance, skip); } - template void writeBytes3(register uint8_t *data, int len, register uint8_t scale, bool advance=true, uint8_t skip=0) { - writeBytes3<0, D, RGB_ORDER>(data, len, scale, advance, skip); + template void writeBytes3(register uint8_t *data, int len, register uint8_t scale, bool advance=true, uint8_t skip=0) { + writeBytes3<0, D, RGB_ORDER>(data, len, scale, advance, skip); } - template void writeBytes3(register uint8_t *data, int len, register uint8_t scale, bool advance=true, uint8_t skip=0) { - writeBytes3<0, DATA_NOP, RGB_ORDER>(data, len, scale, advance, skip); + template void writeBytes3(register uint8_t *data, int len, register uint8_t scale, bool advance=true, uint8_t skip=0) { + writeBytes3<0, DATA_NOP, RGB_ORDER>(data, len, scale, advance, skip); } - void writeBytes3(register uint8_t *data, int len, register uint8_t scale, bool advance=true, uint8_t skip=0) { - writeBytes3<0, DATA_NOP, RGB>(data, len, scale, advance, skip); + void writeBytes3(register uint8_t *data, int len, register uint8_t scale, bool advance=true, uint8_t skip=0) { + writeBytes3<0, DATA_NOP, RGB>(data, len, scale, advance, skip); } }; @@ -138,14 +138,14 @@ public: // 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. +// classes that map the AVR SPI registers to ARM's, however this caps the performance of output. // // TODO: implement ARMHardwareSPIOutput // ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// template -class AVRHardwareSPIOutput { +class AVRHardwareSPIOutput { Selectable *m_pSelect; bool mWait; public: @@ -153,7 +153,7 @@ public: AVRHardwareSPIOutput(Selectable *pSelect) { m_pSelect = pSelect; } void setSelect(Selectable *pSelect) { m_pSelect = pSelect; } - void setSPIRate() { + void setSPIRate() { SPCR &= ~ ( (1<= 128) { SPCR |= (1<= 64) { SPCR |= (1<= 32) { SPCR |= (1<= 16) { SPCR |= (1<= 16) { SPCR |= (1<= 8) { SPCR |= (1<= 4) { /* do nothing - default rate */ } else { b2x = true; } @@ -169,7 +169,7 @@ public: if(b2x) { SPSR |= (1<= 128) { SPCR |= (1<= 64) { SPCR |= (1<= 32) { SPCR |= (1<= 16) { SPCR |= (1<= 16) { SPCR |= (1<= 8) { SPCR |= (1<= 4) { /* do nothing - default rate */ } else { b2x = true; } @@ -207,9 +207,9 @@ public: shouldWait(false); } - static bool shouldWait(bool wait = false) __attribute__((always_inline)) { - static bool sWait=false; - if(sWait) { sWait = wait; return true; } else { sWait = wait; return false; } + 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< inline static void writeBit(uint8_t b) { + template inline static void writeBit(uint8_t b) { SPCR &= ~(1 << SPE); - if(b & (1 << BIT)) { + if(b & (1 << BIT)) { FastPin<_DATA_PIN>::hi(); - } else { + } else { FastPin<_DATA_PIN>::lo(); } @@ -242,25 +242,25 @@ public: while(len--) { writeByte(value); } } - void writeBytesValue(uint8_t value, int len) { + void writeBytesValue(uint8_t value, int len) { //setSPIRate(); select(); - while(len--) { + while(len--) { writeByte(value); } release(); } - - // Write a block of n uint8_ts out - template void writeBytes(register uint8_t *data, int len) { + + // Write a block of n uint8_ts out + template void writeBytes(register uint8_t *data, int len) { //setSPIRate(); uint8_t *end = data + len; select(); - while(data != end) { + 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(); + release(); } void writeBytes(register uint8_t *data, int len) { writeBytes(data, len); } @@ -270,15 +270,15 @@ public: template void writePixels(PixelController pixels) { //setSPIRate(); int len = pixels.mLen; - + select(); - while(pixels.has(1)) { - if(FLAGS & FLAG_START_BIT) { + 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 { + } else { writeByte(D::adjust(pixels.loadAndScale0())); writeByte(D::adjust(pixels.loadAndScale1())); writeByte(D::adjust(pixels.loadAndScale2())); @@ -288,6 +288,7 @@ public: pixels.stepDithering(); } D::postBlock(len); + FastPin<_CLOCK_PIN>::toggle(); release(); } }; @@ -297,4 +298,4 @@ public: // #define FORCE_SOFTWARE_SPI #endif -#endif \ No newline at end of file +#endif -- cgit v1.2.3 From ffb441d728f29c77fc2b2c5bdbd7c993b6efb49d Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Sat, 24 May 2014 20:13:38 -0700 Subject: Fix LPD8806 latch sending. --- chipsets.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/chipsets.h b/chipsets.h index b93058c6..6409bcc2 100644 --- a/chipsets.h +++ b/chipsets.h @@ -19,7 +19,7 @@ class LPD8806Controller : public CLEDController { // LPD8806 spec wants the high bit of every rgb data byte sent out to be set. __attribute__((always_inline)) inline static uint8_t adjust(register uint8_t data) { return ((data>>1) | 0x80) + ((data && (data<254)) & 0x01); } __attribute__((always_inline)) inline static void postBlock(int len) { - SPI::writeBytesValueRaw(0, ((len+63)>>6)); + SPI::writeBytesValueRaw(0, ((len*3+63)>>6)); } }; @@ -35,7 +35,7 @@ class LPD8806Controller : public CLEDController { } void clearLine(int nLeds) { - int n = ((nLeds + 63) >> 6); + int n = ((nLeds*3 + 63) >> 6); mSPI.writeBytesValue(0, n); } public: -- cgit v1.2.3 From a73ab8c10b5ec286a85bdfc0a4f344373f134cff Mon Sep 17 00:00:00 2001 From: Mark Kriegsman Date: Wed, 28 May 2014 23:03:39 -0400 Subject: Added array versions ofnscale8_video, fade_video, fadeLightBy, nscale8, fade_raw, and fadeToBlackBy --- colorutils.cpp | 41 +++++++++++++++++++++++++++++++++++++++++ colorutils.h | 27 +++++++++++++++++++++++++++ 2 files changed, 68 insertions(+) diff --git a/colorutils.cpp b/colorutils.cpp index 0c436f3e..e0a82882 100644 --- a/colorutils.cpp +++ b/colorutils.cpp @@ -28,6 +28,47 @@ void fill_rainbow( struct CRGB * pFirstLED, int numToFill, +void nscale8_video( CRGB* leds, uint16_t num_leds, uint8_t scale) +{ + for( uint16_t i = 0; i < num_leds; i++) { + leds[i].nscale8_video( scale); + } +} + +void fade_video(CRGB* leds, uint16_t num_leds, uint8_t fadeBy) +{ + nscale8_video( leds, num_leds, 255 - fadeBy); +} + +void fadeLightBy(CRGB* leds, uint16_t num_leds, uint8_t fadeBy) +{ + nscale8_video( leds, num_leds, 255 - fadeBy); +} + + +void fadeToBlackBy( CRGB* leds, uint16_t num_leds, uint8_t fadeBy) +{ + nscale8( leds, num_leds, 255 - fadeBy); +} + +void fade_raw( CRGB* leds, uint16_t num_leds, uint8_t fadeBy) +{ + nscale8( leds, num_leds, 255 - fadeBy); +} + +void nscale8_raw( CRGB* leds, uint16_t num_leds, uint8_t scale) +{ + nscale8( leds, num_leds, scale); +} + +void nscale8( CRGB* leds, uint16_t num_leds, uint8_t scale) +{ + for( uint16_t i = 0; i < num_leds; i++) { + leds[i].nscale8( scale); + } +} + + // CRGB HeatColor( uint8_t temperature) // diff --git a/colorutils.h b/colorutils.h index 8a135966..457aec57 100644 --- a/colorutils.h +++ b/colorutils.h @@ -15,6 +15,33 @@ void fill_rainbow( struct CRGB * pFirstLED, int numToFill, uint8_t deltahue = 5); +// fadeLightBy and fade_video - reduce the brightness of an array +// of pixels all at once. Guaranteed +// to never fade all the way to black. +// (The two names are synonyms.) +void fadeLightBy( CRGB* leds, uint16_t num_leds, uint8_t fadeBy); +void fade_video( CRGB* leds, uint16_t num_leds, uint8_t fadeBy); + +// nscale8_video - scale down the brightness of an array of pixels +// all at once. Guaranteed to never scale a pixel +// all the way down to black, unless 'scale' is zero. +void nscale8_video( CRGB* leds, uint16_t num_leds, uint8_t scale); + +// fadeToBlackBy and fade_raw - reduce the brightness of an array +// of pixels all at once. These +// functions will eventually fade all +// the way to black. +// (The two names are synonyms.) +void fadeToBlackBy( CRGB* leds, uint16_t num_leds, uint8_t fadeBy); +void fade_raw( CRGB* leds, uint16_t num_leds, uint8_t fadeBy); + +// nscale8 - scale down the brightness of an array of pixels +// all at once. This function can scale pixels all the +// way down to black even if 'scale' is not zero. +void nscale8( CRGB* leds, uint16_t num_leds, uint8_t scale); + + + // CRGB HeatColor( uint8_t temperature) // // Approximates a 'black body radiation' spectrum for -- cgit v1.2.3 From f605f293e6523f555ab06e1ec8fce7bae6f3575e Mon Sep 17 00:00:00 2001 From: Mark Kriegsman Date: Wed, 28 May 2014 23:05:40 -0400 Subject: Added array versions of fade_video, fade_raw, etc. --- preview_changes.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/preview_changes.txt b/preview_changes.txt index c39919ad..caa45100 100644 --- a/preview_changes.txt +++ b/preview_changes.txt @@ -15,3 +15,4 @@ * Added sin8, cos8, quadwave8, cubicwave8, triwave8, and ease8InOutQuad * Added map8 * Adjusted VIRTAL_BITS of dithering from a flickery 8 to a more solid 3 +* Added array versions of fade_video, fade_raw, and some variations -- cgit v1.2.3 From e674fbe42ae7e41249a9a8487ed6440d7f6cf363 Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Fri, 30 May 2014 21:07:59 -0400 Subject: We don't need these toggles. --- fastspi_arm_k20.h | 1 - fastspi_arm_sam.h | 1 - fastspi_avr.h | 1 - fastspi_bitbang.h | 2 -- 4 files changed, 5 deletions(-) diff --git a/fastspi_arm_k20.h b/fastspi_arm_k20.h index 2e29a27f..0cb343a3 100644 --- a/fastspi_arm_k20.h +++ b/fastspi_arm_k20.h @@ -350,7 +350,6 @@ public: // restore ctar1 update_ctar1(ctar1_save); - FastPin<_CLOCK_PIN>::toggle(); } release(); } diff --git a/fastspi_arm_sam.h b/fastspi_arm_sam.h index bc4bddc2..d756c221 100644 --- a/fastspi_arm_sam.h +++ b/fastspi_arm_sam.h @@ -151,7 +151,6 @@ public: } } D::postBlock(len); - FastPin<_CLOCK_PIN>::toggle(); release(); } }; diff --git a/fastspi_avr.h b/fastspi_avr.h index 3319c9b9..6470f37d 100644 --- a/fastspi_avr.h +++ b/fastspi_avr.h @@ -288,7 +288,6 @@ public: pixels.stepDithering(); } D::postBlock(len); - FastPin<_CLOCK_PIN>::toggle(); release(); } }; diff --git a/fastspi_bitbang.h b/fastspi_bitbang.h index fe5fe19c..fc2403bd 100644 --- a/fastspi_bitbang.h +++ b/fastspi_bitbang.h @@ -348,8 +348,6 @@ public: } #endif D::postBlock(len); - FastPin::hi(); SPI_DELAY; - FastPin::lo(); release(); } }; -- cgit v1.2.3 From 7947112768eff495cafa5bcce92a29746257dd24 Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Fri, 30 May 2014 21:09:10 -0400 Subject: Getting rid of a bad example --- examples/Fast2Dev/Fast2Dev.ino | 108 ----------------------------------------- 1 file changed, 108 deletions(-) delete mode 100644 examples/Fast2Dev/Fast2Dev.ino diff --git a/examples/Fast2Dev/Fast2Dev.ino b/examples/Fast2Dev/Fast2Dev.ino deleted file mode 100644 index 3ae799c0..00000000 --- a/examples/Fast2Dev/Fast2Dev.ino +++ /dev/null @@ -1,108 +0,0 @@ -// Uncomment this line if you have any interrupts that are changing pins - this causes the library to be a little bit more cautious -// #define FAST_SPI_INTERRUPTS_WRITE_PINS 1 - -// Uncomment this line to force always using software, instead of hardware, SPI (why?) -// #define FORCE_SOFTWARE_SPI 1 - -// Uncomment this line if you want to talk to DMX controllers -// #define FASTSPI_USE_DMX_SIMPLE 1 - -#include "FastLED.h" - - -//////////////////////////////////////////////////////////////////////////////////////////////////// -// -// test code -// -////////////////////////////////////////////////// - -#define NUM_LEDS 256 - -CRGB leds[NUM_LEDS]; - -void setup() { - // sanity check delay - allows reprogramming if accidently blowing power w/leds - delay(2000); - - // For safety (to prevent too high of a power draw), the test case defaults to - // setting brightness to 25% brightness - LEDS.setBrightness(64); - - // LEDS.addLeds(leds, NUM_LEDS); - // LEDS.addLeds(leds, NUM_LEDS); - // LEDS.addLeds(leds, NUM_LEDS); - // LEDS.addLeds(leds, NUM_LEDS); - // LEDS.addLeds(leds, NUM_LEDS); - - FastLED.addLeds(leds, NUM_LEDS); - - // LEDS.addLeds(leds, NUM_LEDS); - // LEDS.addLeds(leds, NUM_LEDS); - // LEDS.addLeds(leds, NUM_LEDS); - - // LEDS.addLeds(leds, NUM_LEDS); - // LEDS.addLeds(leds, NUM_LEDS); - // LEDS.addLeds(leds, NUM_LEDS); - - // LEDS.addLeds(leds, NUM_LEDS); - - // Put ws2801 strip on the hardware SPI pins with a BGR ordering of rgb and limited to a 1Mhz data rate - // LEDS.addLeds(leds, NUM_LEDS); - - // LEDS.addLeds(leds, NUM_LEDS); - // LEDS.addLeds(leds, NUM_LEDS); - // LEDS.addLeds(leds, NUM_LEDS); -} - -void loop() { - // LEDS.clear(); for(;;); - - for(int i = 0; i < 3; i++) { - for(int iLed = 0; iLed < NUM_LEDS; iLed++) { - memset(leds, 0, NUM_LEDS * sizeof(struct CRGB)); - - switch(i) { - // You can access the rgb values by field r, g, b - case 0: leds[iLed].r = 128; break; - - // or by indexing into the led (r==0, g==1, b==2) - case 1: leds[iLed][i] = 128; break; - - // or by setting the rgb values for the pixel all at once - case 2: leds[iLed] = CRGB(0, 0, 128); break; - } - - // and now, show your led array! - LEDS.show(); - delay(10); - } - - // leave the last pixel lit for a bit - delay(2000); - - // fade up - for(int x = 0; x < 128; x++) { - // The showColor method sets all the leds in the strip to the same color - LEDS.showColor(CRGB(x, 0, 0)); - delay(10); - } - - // fade down - for(int x = 128; x >= 0; x--) { - LEDS.showColor(CRGB(x, 0, 0)); - delay(10); - } - - // let's fade up by scaling the brightness - for(int scale = 0; scale < 128; scale++) { - LEDS.showColor(CRGB(0, 128, 0), scale); - delay(10); - } - - // let's fade down by scaling the brightness - for(int scale = 128; scale > 0; scale--) { - LEDS.showColor(CRGB(0, 128, 0), scale); - delay(10); - } - } -} -- cgit v1.2.3 From 19bcc72623e7a28788f1dbd4307fb7a445029f79 Mon Sep 17 00:00:00 2001 From: Mark Kriegsman Date: Sat, 31 May 2014 08:41:48 -0400 Subject: Added fill_gradient --- colorutils.cpp | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++++ colorutils.h | 23 ++++++++++++++++++ preview_changes.txt | 1 + 3 files changed, 92 insertions(+) diff --git a/colorutils.cpp b/colorutils.cpp index e0a82882..12e9b0ad 100644 --- a/colorutils.cpp +++ b/colorutils.cpp @@ -27,6 +27,74 @@ void fill_rainbow( struct CRGB * pFirstLED, int numToFill, } +#define saccum87 int16_t + +void fill_gradient( CRGB* leds, + uint16_t startpos, CHSV startcolor, + uint16_t endpos, CHSV endcolor, + TGradientDirectionCode directionCode ) +{ + // if the points are in the wrong order, straighten them + if( endpos < startpos ) { + uint16_t t = endpos; + CHSV tc = endcolor; + startpos = t; + startcolor = tc; + endcolor = startcolor; + endpos = startpos; + } + + saccum87 huedistance87; + saccum87 satdistance87; + saccum87 valdistance87; + + satdistance87 = (endcolor.sat - startcolor.sat) << 7; + valdistance87 = (endcolor.val - startcolor.val) << 7; + + uint8_t huedelta8 = endcolor.hue - startcolor.hue; + + if( directionCode == SHORTEST_HUES ) { + directionCode = FORWARD_HUES; + if( huedelta8 > 127) { + directionCode = BACKWARD_HUES; + } + } + + if( directionCode == LONGEST_HUES ) { + directionCode = FORWARD_HUES; + if( huedelta8 < 128) { + directionCode = BACKWARD_HUES; + } + } + + if( directionCode == FORWARD_HUES) { + huedistance87 = huedelta8 << 7; + } + else /* directionCode == BACKWARD_HUES */ + { + huedistance87 = (uint8_t)(256 - huedelta8) << 7; + huedistance87 = -huedistance87; + } + + uint16_t pixeldistance = endpos - startpos; + uint16_t p2 = pixeldistance / 2; + int16_t divisor = p2 ? p2 : 1; + saccum87 huedelta87 = huedistance87 / divisor; + saccum87 satdelta87 = satdistance87 / divisor; + saccum87 valdelta87 = valdistance87 / divisor; + + accum88 hue88 = startcolor.hue << 8; + accum88 sat88 = startcolor.sat << 8; + accum88 val88 = startcolor.val << 8; + for( uint16_t i = startpos; i <= endpos; i++) { + leds[i] = CHSV( hue88 >> 8, sat88 >> 8, val88 >> 8); + hue88 += huedelta87; + sat88 += satdelta87; + val88 += valdelta87; + } +} + + void nscale8_video( CRGB* leds, uint16_t num_leds, uint8_t scale) { diff --git a/colorutils.h b/colorutils.h index 457aec57..44b2855b 100644 --- a/colorutils.h +++ b/colorutils.h @@ -15,6 +15,29 @@ void fill_rainbow( struct CRGB * pFirstLED, int numToFill, uint8_t deltahue = 5); +// fill_gradient - fill a range of LEDs with a smooth gradient +// between two specified HSV colors. +// Since 'hue' is a value around a color wheel, +// there are always two ways to sweep from one hue +// to another. +// This function lets you specify which way you want +// the hue gradient to sweep around the color wheel: +// FORWARD_HUES: hue always goes clockwise +// BACKWARD_HUES: hue always goes counter-clockwise +// SHORTEST_HUES: hue goes whichever way is shortest +// LONGEST_HUES: hue goes whichever way is longest +// The default is SHORTEST_HUES, as this is nearly +// always what is wanted. +// +typedef enum { FORWARD_HUES, BACKWARD_HUES, SHORTEST_HUES, LONGEST_HUES } TGradientDirectionCode; + +void fill_gradient( struct CRGB* leds, + uint16_t startpos, CHSV startcolor, + uint16_t endpos, CHSV endcolor, + TGradientDirectionCode directionCode = SHORTEST_HUES ); + + + // fadeLightBy and fade_video - reduce the brightness of an array // of pixels all at once. Guaranteed // to never fade all the way to black. diff --git a/preview_changes.txt b/preview_changes.txt index caa45100..bc69c59f 100644 --- a/preview_changes.txt +++ b/preview_changes.txt @@ -16,3 +16,4 @@ * Added map8 * Adjusted VIRTAL_BITS of dithering from a flickery 8 to a more solid 3 * Added array versions of fade_video, fade_raw, and some variations +* Added fill_gradient -- cgit v1.2.3 From b0bf34240cd0dcbadfbb8413d351b2627027c20c Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Sat, 31 May 2014 17:32:45 -0400 Subject: Added lerp15by16 as well as improved performance on some of the scaling functions on avr. --- lib8tion.h | 302 +++++++++++++++++++++++++++++++++++-------------------------- 1 file changed, 176 insertions(+), 126 deletions(-) diff --git a/lib8tion.h b/lib8tion.h index 8e53dd05..233132e8 100644 --- a/lib8tion.h +++ b/lib8tion.h @@ -2,37 +2,37 @@ #define __INC_LIB8TION_H /* - + Fast, efficient 8-bit math functions specifically designed for high-performance LED programming. - + Because of the AVR(Arduino) and ARM assembly language implementations provided, using these functions often results in smaller and faster code than the equivalent program using plain "C" arithmetic and logic. - - + + Included are: - - + + - Saturating unsigned 8-bit add and subtract. Instead of wrapping around if an overflow occurs, these routines just 'clamp' the output at a maxumum - of 255, or a minimum of 0. Useful for adding pixel + of 255, or a minimum of 0. Useful for adding pixel values. E.g., qadd8( 200, 100) = 255. - + qadd8( i, j) == MIN( (i + j), 0xFF ) qsub8( i, j) == MAX( (i - j), 0 ) - + - Saturating signed 8-bit ("7-bit") add. qadd7( i, j) == MIN( (i + j), 0x7F) - - + + - Scaling (down) of unsigned 8- and 16- bit values. Scaledown value is specified in 1/256ths. scale8( i, sc) == (i * sc) / 256 scale16by8( i, sc) == (i * sc) / 256 - + Example: scaling a 0-255 value down into a range from 0-99: downscaled = scale8( originalnumber, 100); @@ -42,27 +42,27 @@ accidentally scale down to total black at low dimming levels, since that would look wrong: scale8_video( i, sc) = ((i * sc) / 256) +? 1 - + Example: reducing an LED brightness by a dimming factor: new_bright = scale8_video( orig_bright, dimming); - - + + - Fast 8- and 16- bit unsigned random numbers. - Significantly faster than Arduino random(), but + Significantly faster than Arduino random(), but also somewhat less random. You can add entropy. random8() == random from 0..255 random8( n) == random from 0..(N-1) random8( n, m) == random from N..(M-1) - + random16() == random from 0..65535 random16( n) == random from 0..(N-1) random16( n, m) == random from N..(M-1) - + random16_set_seed( k) == seed = k random16_add_entropy( k) == seed += k - + - Absolute value of a signed 8-bit value. abs8( i) == abs( i) @@ -74,14 +74,14 @@ add8( i, j) == (i + j) & 0xFF sub8( i, j) == (i - j) & 0xFF - + - Fast 16-bit approximations of sin and cos. Input angle is a uint16_t from 0-65535. Output is a signed int16_t from -32767 to 32767. sin16( x) == sin( (x/32768.0) * pi) * 32767 cos16( x) == cos( (x/32768.0) * pi) * 32767 Accurate to more than 99% in all cases. - + - Fast 8-bit approximations of sin and cos. Input angle is a uint8_t from 0-255. Output is an UNsigned uint8_t from 0 to 255. @@ -89,10 +89,10 @@ cos8( x) == (cos( (x/128.0) * pi) * 128) + 128 Accurate to within about 2%. - + - Fast 8-bit "easing in/out" function. ease8InOutCubic(x) == 3(x^i) - 2(x^3) - ease8InOutApprox(x) == + ease8InOutApprox(x) == faster, rougher, approximation of cubic easing ease8InOutQuad(x) == quadratic (vs cubic) easing @@ -104,7 +104,7 @@ cubicwave8( x) quadwave8( x) triwave8( x) - + - Dimming and brightening functions for 8-bit light values. @@ -114,8 +114,8 @@ brighten8_raw( x) == 255 - dim8_raw( 255 - x) The dimming functions in particular are suitable for making LED light output appear more 'linear'. - - + + - Linear interpolation between two values, with the fraction between them expressed as an 8- or 16-bit fixed point fraction (fract8 or fract16). @@ -127,19 +127,19 @@ == from + (( to - from ) * fract16) / 65536) map8( in, rangeStart, rangeEnd) == map( in, 0, 255, rangeStart, rangeEnd); - + - Optimized memmove, memcpy, and memset, that are faster than standard avr-libc 1.8. memmove8( dest, src, bytecount) memcpy8( dest, src, bytecount) memset8( buf, value, bytecount) - + Lib8tion is pronounced like 'libation': lie-BAY-shun */ - - + + #include @@ -361,7 +361,7 @@ LIB8STATIC int8_t qadd7( int8_t i, int8_t j) asm volatile( /* First, add j to i, conditioning the V flag */ "add %0, %1 \n\t" - + /* Now test the V flag. If V is clear, we branch around a load of 0x7F into i. If V is set, we go ahead and load 0x7F into i. @@ -393,7 +393,7 @@ LIB8STATIC uint8_t qsub8( uint8_t i, uint8_t j) asm volatile( /* First, subtract j from i, conditioning the C flag */ "sub %0, %1 \n\t" - + /* Now test the C flag. If C is clear, we branch around a load of 0x00 into i. If C is set, we go ahead and load 0x00 into i. @@ -403,7 +403,7 @@ LIB8STATIC uint8_t qsub8( uint8_t i, uint8_t j) "L_%=: " : "+a" (i) : "a" (j) ); - + return i; #else #error "No implementation for qsub8 available." @@ -446,10 +446,10 @@ LIB8STATIC uint8_t sub8( uint8_t i, uint8_t j) // the numerator of a fraction whose denominator is 256 // In other words, it computes i * (scale / 256) // 4 clocks AVR, 2 clocks ARM -LIB8STATIC uint8_t scale8( uint8_t i, fract8 scale) +LIB8STATIC uint8_t scale8( uint8_t i, fract8 scale) { #if SCALE8_C == 1 - return + return ((int)i * (int)(scale) ) >> 8; #elif SCALE8_AVRASM == 1 #if defined(LIB8_ATTINY) @@ -481,7 +481,7 @@ LIB8STATIC uint8_t scale8( uint8_t i, fract8 scale) "mov %0, r1 \n\t" /* Restore r1 to "0"; it's expected to always be that */ "clr __zero_reg__ \n\t" - + : "+a" (i) /* writes to i */ : "a" (scale) /* uses scale */ : "r0", "r1" /* clobbers r0, r1 */ ); @@ -532,11 +532,11 @@ LIB8STATIC uint8_t scale8_video( uint8_t i, fract8 scale) // " add %0, %2 \n" // " clr __zero_reg__ \n" // "L_%=: \n" - + // : "+a" (i) // : "a" (scale), "a" (nonzeroscale) // : "r0", "r1"); - + // // Return the result // return i; #else @@ -560,11 +560,11 @@ LIB8STATIC uint8_t scale8_LEAVING_R1_DIRTY( uint8_t i, fract8 scale) "mov %0, r1 \n\t" /* R1 IS LEFT DIRTY HERE; YOU MUST ZERO IT OUT YOURSELF */ /* "clr __zero_reg__ \n\t" */ - + : "+a" (i) /* writes to i */ : "a" (scale) /* uses scale */ : "r0", "r1" /* clobbers r0, r1 */ ); - + // Return the result return i; #else @@ -586,7 +586,7 @@ LIB8STATIC void nscale8_LEAVING_R1_DIRTY( uint8_t& i, fract8 scale) "mov %0, r1 \n\t" /* R1 IS LEFT DIRTY HERE; YOU MUST ZERO IT OUT YOURSELF */ /* "clr __zero_reg__ \n\t" */ - + : "+a" (i) /* writes to i */ : "a" (scale) /* uses scale */ : "r0", "r1" /* clobbers r0, r1 */ ); @@ -599,34 +599,67 @@ LIB8STATIC void nscale8_LEAVING_R1_DIRTY( uint8_t& i, fract8 scale) LIB8STATIC uint8_t scale8_video_LEAVING_R1_DIRTY( uint8_t i, fract8 scale) { - return scale8_video(i,scale); -// #if SCALE8_C == 1 -// uint8_t nonzeroscale = (scale != 0) ? 1 : 0; -// uint8_t j = (i == 0) ? 0 : (((int)i * (int)(scale) ) >> 8) + nonzeroscale; -// return j; -// #elif SCALE8_AVRASM == 1 - -// uint8_t nonzeroscale = (scale != 0) ? 1 : 0; -// asm volatile( -// " tst %0 \n" -// " breq L_%= \n" -// " mul %0, %1 \n" -// " mov %0, r1 \n" -// " add %0, %2 \n" -// /* R1 IS LEFT DIRTY, YOU MUST ZERO IT OUT YOURSELF */ -// "L_%=: \n" - -// : "+a" (i) -// : "a" (scale), "a" (nonzeroscale) -// : "r0", "r1"); - -// // Return the result -// return i; -// #else -// #error "No implementation for scale8_video available." -// #endif +#if SCALE8_C == 1 || defined(LIB8_ATTINY) + uint8_t j = (((int)i * (int)scale) >> 8) + ((i&&scale)?1:0); + // uint8_t nonzeroscale = (scale != 0) ? 1 : 0; + // uint8_t j = (i == 0) ? 0 : (((int)i * (int)(scale) ) >> 8) + nonzeroscale; + return j; +#elif SCALE8_AVRASM == 1 + uint8_t j=0; + asm volatile( + " tst %[i]\n\t" + " breq L_%=\n\t" + " mul %[i], %[scale]\n\t" + " mov %[j], r1\n\t" + " breq L_%=\n\t" + " subi %[j], 0xFF\n\t" + "L_%=: \n\t" + : [j] "+a" (j) + : [i] "a" (i), [scale] "a" (scale) + : "r0", "r1"); + + return j; + // uint8_t nonzeroscale = (scale != 0) ? 1 : 0; + // asm volatile( + // " tst %0 \n" + // " breq L_%= \n" + // " mul %0, %1 \n" + // " mov %0, r1 \n" + // " add %0, %2 \n" + // " clr __zero_reg__ \n" + // "L_%=: \n" + + // : "+a" (i) + // : "a" (scale), "a" (nonzeroscale) + // : "r0", "r1"); + + // // Return the result + // return i; +#else +#error "No implementation for scale8_video_LEAVING_R1_DIRTY available." +#endif } +LIB8STATIC void nscale8_video_LEAVING_R1_DIRTY( uint8_t & i, fract8 scale) +{ +#if SCALE8_C == 1 || defined(LIB8_ATTINY) + i = (((int)i * (int)scale) >> 8) + ((i&&scale)?1:0); +#elif SCALE8_AVRASM == 1 + asm volatile( + " tst %[i]\n\t" + " breq L_%=\n\t" + " mul %[i], %[scale]\n\t" + " mov %[i], r1\n\t" + " breq L_%=\n\t" + " subi %[i], 0xFF\n\t" + "L_%=: \n\t" + : [i] "+a" (i) + : [scale] "a" (scale) + : "r0", "r1"); +#else +#error "No implementation for scale8_video_LEAVING_R1_DIRTY available." +#endif +} LIB8STATIC void cleanup_R1() @@ -669,9 +702,9 @@ LIB8STATIC void nscale8x3_video( uint8_t& r, uint8_t& g, uint8_t& b, fract8 scal g = (g == 0) ? 0 : (((int)g * (int)(scale) ) >> 8) + nonzeroscale; b = (b == 0) ? 0 : (((int)b * (int)(scale) ) >> 8) + nonzeroscale; #elif SCALE8_AVRASM == 1 - r = scale8_video_LEAVING_R1_DIRTY( r, scale); - g = scale8_video_LEAVING_R1_DIRTY( g, scale); - b = scale8_video_LEAVING_R1_DIRTY( b, scale); + nscale8_video_LEAVING_R1_DIRTY( r, scale); + nscale8_video_LEAVING_R1_DIRTY( g, scale); + nscale8_video_LEAVING_R1_DIRTY( b, scale); cleanup_R1(); #else #error "No implementation for nscale8x3 available." @@ -706,8 +739,8 @@ LIB8STATIC void nscale8x2_video( uint8_t& i, uint8_t& j, fract8 scale) i = (i == 0) ? 0 : (((int)i * (int)(scale) ) >> 8) + nonzeroscale; j = (j == 0) ? 0 : (((int)j * (int)(scale) ) >> 8) + nonzeroscale; #elif SCALE8_AVRASM == 1 - i = scale8_video_LEAVING_R1_DIRTY( i, scale); - j = scale8_video_LEAVING_R1_DIRTY( j, scale); + nscale8_video_LEAVING_R1_DIRTY( i, scale); + nscale8_video_LEAVING_R1_DIRTY( j, scale); cleanup_R1(); #else #error "No implementation for nscale8x2 available." @@ -735,15 +768,15 @@ LIB8STATIC uint16_t scale16by8( uint16_t i, fract8 scale ) " mul %A[i], %[scale] \n\t" " mov %A[result], r1 \n\t" " clr %B[result] \n\t" - + // result.A-B += i.B x j " mul %B[i], %[scale] \n\t" " add %A[result], r0 \n\t" " adc %B[result], r1 \n\t" - + // cleanup r1 " clr __zero_reg__ \n\t" - + : [result] "=r" (result) : [i] "r" (i), [scale] "r" (scale) : "r0", "r1" @@ -786,7 +819,7 @@ uint16_t scale16( uint16_t i, fract16 scale ) // one clock cycle, just like mov, so might as // well, in case we want to use this code for // a generic 16x16 multiply somewhere. - + // result.C-D = i.B x scale.B " mul %B[i], %B[scale] \n\t" //" mov %C[result], r0 \n\t" @@ -795,21 +828,21 @@ uint16_t scale16( uint16_t i, fract16 scale ) // result.B-D += i.B x scale.A " mul %B[i], %A[scale] \n\t" - + " add %B[result], r0 \n\t" " adc %C[result], r1 \n\t" " adc %D[result], %[zero] \n\t" - + // result.B-D += i.A x scale.B " mul %A[i], %B[scale] \n\t" - + " add %B[result], r0 \n\t" " adc %C[result], r1 \n\t" " adc %D[result], %[zero] \n\t" - + // cleanup r1 " clr r1 \n\t" - + : [result] "+r" (result) : [i] "r" (i), [scale] "r" (scale), @@ -841,7 +874,7 @@ LIB8STATIC uint8_t mul8( uint8_t i, uint8_t j) : "+a" (i) : "a" (j) : "r0", "r1"); - + return i; #else #error "No implementation for mul8 available." @@ -875,7 +908,7 @@ LIB8STATIC uint8_t qmul8( uint8_t i, uint8_t j) : "+a" (i) : "a" (j) : "r0", "r1"); - + return i; #else #error "No implementation for qmul8 available." @@ -890,15 +923,15 @@ LIB8STATIC int8_t abs8( int8_t i) if( i < 0) i = -i; return i; #elif ABS8_AVRASM == 1 - - + + asm volatile( /* First, check the high bit, and prepare to skip if it's clear */ "sbrc %0, 7 \n" - + /* Negate the value */ "neg %0 \n" - + : "+r" (i) : "r" (i) ); return i; #else @@ -947,7 +980,7 @@ sfract15 floatToSfract15( float f) // appear half as bright as 'full' brightness (255), you // have to apply a 'dimming function'. // -// +// LIB8STATIC uint8_t dim8_raw( uint8_t x) { @@ -1071,9 +1104,9 @@ LIB8STATIC int16_t sin16_avr( uint16_t theta ) 12539%256, 12539/256, 44, 0, 18204%256, 18204/256, 38, 0, 23170%256, 23170/256, 31, 0, 27245%256, 27245/256, 23, 0, 30273%256, 30273/256, 14, 0, 32137%256, 32137/256, 4 /*,0*/ }; - + uint16_t offset = (theta & 0x3FFF); - + // AVR doesn't have a multi-bit shift instruction, // so if we say "offset >>= 3", gcc makes a tiny loop. // Inserting empty volatile statements between each @@ -1085,13 +1118,13 @@ LIB8STATIC int16_t sin16_avr( uint16_t theta ) offset >>= 1; // 0..2047 if( theta & 0x4000 ) offset = 2047 - offset; - + uint8_t sectionX4; sectionX4 = offset / 256; sectionX4 *= 4; - + uint8_t m; - + union { uint16_t b; struct { @@ -1099,19 +1132,19 @@ LIB8STATIC int16_t sin16_avr( uint16_t theta ) uint8_t bhi; }; } u; - + //in effect u.b = blo + (256 * bhi); u.blo = data[ sectionX4 ]; u.bhi = data[ sectionX4 + 1]; m = data[ sectionX4 + 2]; - + uint8_t secoffset8 = (uint8_t)(offset) / 2; - + uint16_t mx = m * secoffset8; - + int16_t y = mx + u.b; if( theta & 0x8000 ) y = -y; - + return y; } @@ -1121,21 +1154,21 @@ LIB8STATIC int16_t sin16_C( uint16_t theta ) { 0, 6393, 12539, 18204, 23170, 27245, 30273, 32137 }; static const uint8_t slope[] = { 49, 48, 44, 38, 31, 23, 14, 4 }; - + uint16_t offset = (theta & 0x3FFF) >> 3; // 0..2047 if( theta & 0x4000 ) offset = 2047 - offset; - + uint8_t section = offset / 256; // 0..7 uint16_t b = base[section]; uint8_t m = slope[section]; - + uint8_t secoffset8 = (uint8_t)(offset) / 2; - + uint16_t mx = m * secoffset8; int16_t y = mx + b; - + if( theta & 0x8000 ) y = -y; - + return y; } @@ -1174,20 +1207,20 @@ const uint8_t b_m16_interleave[] = { 0, 49, 49, 41, 90, 27, 117, 10 }; LIB8STATIC uint8_t sin8_avr( uint8_t theta) { uint8_t offset = theta; - + asm volatile( "sbrc %[theta],6 \n\t" "com %[offset] \n\t" : [theta] "+r" (theta), [offset] "+r" (offset) ); - + offset &= 0x3F; // 0..63 - + uint8_t secoffset = offset & 0x0F; // 0..15 if( theta & 0x40) secoffset++; - + uint8_t m16; uint8_t b; - + uint8_t section = offset >> 4; // 0..3 uint8_t s2 = section * 2; @@ -1196,7 +1229,7 @@ LIB8STATIC uint8_t sin8_avr( uint8_t theta) b = *p; p++; m16 = *p; - + uint8_t mx; uint8_t xr1; asm volatile( @@ -1212,12 +1245,12 @@ LIB8STATIC uint8_t sin8_avr( uint8_t theta) : [mx] "=r" (mx), [xr1] "=r" (xr1) : [m16] "r" (m16), [secoffset] "r" (secoffset) ); - + int8_t y = mx + b; if( theta & 0x80 ) y = -y; - + y += 128; - + return y; } @@ -1229,10 +1262,10 @@ LIB8STATIC uint8_t sin8_C( uint8_t theta) offset = (uint8_t)255 - offset; } offset &= 0x3F; // 0..63 - + uint8_t secoffset = offset & 0x0F; // 0..15 if( theta & 0x40) secoffset++; - + uint8_t section = offset >> 4; // 0..3 uint8_t s2 = section * 2; const uint8_t* p = b_m16_interleave; @@ -1240,14 +1273,14 @@ LIB8STATIC uint8_t sin8_C( uint8_t theta) uint8_t b = *p; p++; uint8_t m16 = *p; - + uint8_t mx = (m16 * secoffset) >> 4; - + int8_t y = mx + b; if( theta & 0x80 ) y = -y; - + y += 128; - + return y; } @@ -1348,6 +1381,23 @@ LIB8STATIC int16_t lerp15by8( int16_t a, int16_t b, fract8 frac) return result; } +// linear interpolation between two signed 15-bit values, +// with 8-bit fraction +LIB8STATIC int16_t lerp15by16( int16_t a, int16_t b, fract16 frac) +{ + int16_t result; + if( b > a) { + uint16_t delta = b - a; + uint16_t scaled = scale16( delta, frac); + result = a + scaled; + } else { + uint16_t delta = a - b; + uint16_t scaled = scale16( delta, frac); + result = a - scaled; + } + return result; +} + // map8: map from one full-range 8-bit value into a narrower // range of 8-bit values, possibly a range of hues. // @@ -1399,15 +1449,15 @@ LIB8STATIC fract8 ease8InOutCubic( fract8 i) { uint8_t ii = scale8_LEAVING_R1_DIRTY( i, i); uint8_t iii = scale8_LEAVING_R1_DIRTY( ii, i); - + uint16_t r1 = (3 * (uint16_t)(ii)) - ( 2 * (uint16_t)(iii)); /* the code generated for the above *'s automatically cleans up R1, so there's no need to explicitily call cleanup_R1(); */ - + uint8_t result = r1; - + // if we got "256", return 255: if( r1 & 0x100 ) { result = 255; @@ -1440,7 +1490,7 @@ LIB8STATIC fract8 ease8InOutApprox( fract8 i) i += (i / 2); i += 32; } - + return i; } @@ -1466,9 +1516,9 @@ LIB8STATIC uint8_t ease8InOutApprox( fract8 i) " subi %[i], 96 \n\t" "Ldone_%=: \n\t" - + : [i] "+a" (i) - : + : : "r0", "r1" ); return i; @@ -1505,7 +1555,7 @@ LIB8STATIC uint8_t triwave8(uint8_t in) // with an 'acceleration' and 'deceleration' curve. // // These are even faster than 'sin8', and have -// slightly different curve shapes. +// slightly different curve shapes. // // quadwave8: quadratic waveform generator. Spends just a little more -- cgit v1.2.3 From 063c9371f7d8a41accea98fe385ab6f449cdc438 Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Sat, 31 May 2014 17:33:29 -0400 Subject: CRGB::lerp should be using 8by8, not 16by8. Add operator>>= for fast shifting of rgb values in a pixel if wanted. --- pixeltypes.h | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/pixeltypes.h b/pixeltypes.h index 4711acd1..ae56c159 100644 --- a/pixeltypes.h +++ b/pixeltypes.h @@ -289,6 +289,15 @@ struct CRGB { return *this; } + // right shift each of the channels by a constant + inline CRGB& operator>>= (uint8_t d) + { + r >>= d; + g >>= d; + b >>= d; + return *this; + } + // multiply each of the channels by a constant, // saturating each channel at 0xFF inline CRGB& operator*= (uint8_t d ) @@ -424,9 +433,9 @@ struct CRGB { { CRGB ret; - ret.r = lerp16by8(r<<8,other.r<<8,frac)>>8; - ret.g = lerp16by8(g<<8,other.g<<8,frac)>>8; - ret.b = lerp16by8(b<<8,other.b<<8,frac)>>8; + ret.r = lerp8by8(r,other.r,frac); + ret.g = lerp8by8(g,other.g,frac); + ret.b = lerp8by8(b,other.b,frac); return ret; } -- cgit v1.2.3 From da2d05616b5e82cd722ed7ae850b3b0208672fc5 Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Sat, 31 May 2014 18:51:46 -0400 Subject: Adding 8 and 16 bit simplex noise implementations to the library. The 8 bit version can do over 30,000 noise points per second, the 16 bit version over 15,000. Also, add a debugging FPS counter to FastLED. --- FastLED.cpp | 50 ++++--- FastLED.h | 5 + examples/Noise/Noise.ino | 113 ++++++++++++++++ noise.cpp | 339 +++++++++++++++++++++++++++++++++++++++++++++++ noise.h | 20 +++ 5 files changed, 510 insertions(+), 17 deletions(-) create mode 100644 examples/Noise/Noise.ino create mode 100644 noise.cpp create mode 100644 noise.h diff --git a/FastLED.cpp b/FastLED.cpp index 0c10a2a7..d93b765e 100644 --- a/FastLED.cpp +++ b/FastLED.cpp @@ -14,15 +14,15 @@ CLEDController *CLEDController::m_pTail = NULL; // uint32_t CRGB::Squant = ((uint32_t)((__TIME__[4]-'0') * 28))<<16 | ((__TIME__[6]-'0')*50)<<8 | ((__TIME__[7]-'0')*28); -CFastLED::CFastLED() { +CFastLED::CFastLED() { // clear out the array of led controllers // m_nControllers = 0; m_Scale = 255; } -CLEDController &CFastLED::addLeds(CLEDController *pLed, - const struct CRGB *data, - int nLedsOrOffset, int nLedsIfOffset) { +CLEDController &CFastLED::addLeds(CLEDController *pLed, + const struct CRGB *data, + int nLedsOrOffset, int nLedsIfOffset) { int nOffset = (nLedsIfOffset > 0) ? nLedsOrOffset : 0; int nLeds = (nLedsIfOffset > 0) ? nLedsIfOffset : nLedsOrOffset; @@ -31,24 +31,24 @@ CLEDController &CFastLED::addLeds(CLEDController *pLed, return *pLed; } -void CFastLED::show(uint8_t scale) { +void CFastLED::show(uint8_t scale) { CLEDController *pCur = CLEDController::head(); - while(pCur) { + while(pCur) { pCur->showLeds(scale); pCur = pCur->next(); } } -void CFastLED::showColor(const struct CRGB & color, uint8_t scale) { +void CFastLED::showColor(const struct CRGB & color, uint8_t scale) { CLEDController *pCur = CLEDController::head(); - while(pCur) { + while(pCur) { pCur->showColor(color, scale); pCur = pCur->next(); } } -void CFastLED::clear(boolean writeData) { - if(writeData) { +void CFastLED::clear(boolean writeData) { + if(writeData) { showColor(CRGB(0,0,0), 0); } clearData(); @@ -56,16 +56,16 @@ void CFastLED::clear(boolean writeData) { void CFastLED::clearData() { CLEDController *pCur = CLEDController::head(); - while(pCur) { + while(pCur) { pCur->clearLedData(); pCur = pCur->next(); } } -void CFastLED::delay(unsigned long ms) { +void CFastLED::delay(unsigned long ms) { unsigned long start = millis(); - while((millis()-start) < ms) { - show(); + while((millis()-start) < ms) { + show(); } @@ -73,7 +73,7 @@ void CFastLED::delay(unsigned long ms) { void CFastLED::setTemperature(const struct CRGB & temp) { CLEDController *pCur = CLEDController::head(); - while(pCur) { + while(pCur) { pCur->setTemperature(temp); pCur = pCur->next(); } @@ -81,7 +81,7 @@ void CFastLED::setTemperature(const struct CRGB & temp) { void CFastLED::setCorrection(const struct CRGB & correction) { CLEDController *pCur = CLEDController::head(); - while(pCur) { + while(pCur) { pCur->setCorrection(correction); pCur = pCur->next(); } @@ -89,9 +89,25 @@ void CFastLED::setCorrection(const struct CRGB & correction) { void CFastLED::setDither(uint8_t ditherMode) { CLEDController *pCur = CLEDController::head(); - while(pCur) { + while(pCur) { pCur->setDither(ditherMode); pCur = pCur->next(); } } +void CFastLED::countFPS(int nFrames) { + if(Serial) { + static uint32_t br = 0; + static uint32_t lastframe = millis(); + + br++; + if(br == nFrames) { + uint32_t now = millis() - lastframe; + uint32_t fps = (br * 1000) / now; + Serial.print(now); Serial.print("ms for "); Serial.print(br); Serial.print(" frames, aka "); + Serial.print(fps); Serial.println(" fps. "); + br = 0; + lastframe = millis(); + } + } +} diff --git a/FastLED.h b/FastLED.h index c3800bee..00d68696 100644 --- a/FastLED.h +++ b/FastLED.h @@ -17,6 +17,7 @@ #include "colorutils.h" #include "chipsets.h" #include "dmx.h" +#include "noise.h" enum ESPIChipsets { LPD8806, @@ -195,6 +196,10 @@ public: void setCorrection(const struct CRGB & correction); void setDither(uint8_t ditherMode = BINARY_DITHER); + // for debugging, will keep track of time between calls to countFPS, and every + // nFrames calls, it will print a summary of FPS info out to the serial port. + // If the serial port isn't opened, this function does nothing. + void countFPS(int nFrames=100); }; extern CFastLED & FastSPI_LED; diff --git a/examples/Noise/Noise.ino b/examples/Noise/Noise.ino new file mode 100644 index 00000000..dab26e7e --- /dev/null +++ b/examples/Noise/Noise.ino @@ -0,0 +1,113 @@ +#include + +// +// Mark's xy coordinate mapping code. See the XYMatrix for more information on it. +// + +// Params for width and height +const uint8_t kMatrixWidth = 16; +const uint8_t kMatrixHeight = 16; +#define MAX_DIMENSION ((kMatrixWidth>kMatrixHeight) ? kMatrixWidth : kMatrixHeight) +#define NUM_LEDS (kMatrixWidth * kMatrixHeight) +// Param for different pixel layouts +const bool kMatrixSerpentineLayout = true; + + +uint16_t XY( uint8_t x, uint8_t y) +{ + uint16_t i; + + if( kMatrixSerpentineLayout == false) { + i = (y * kMatrixWidth) + x; + } + + if( kMatrixSerpentineLayout == true) { + if( y & 0x01) { + // Odd rows run backwards + uint8_t reverseX = (kMatrixWidth - 1) - x; + i = (y * kMatrixWidth) + reverseX; + } else { + // Even rows run forwards + i = (y * kMatrixWidth) + x; + } + } + + return i; +} + +// The leds +CRGB leds[kMatrixWidth * kMatrixHeight]; + +// The 32bit version of our coordinates +static uint16_t x; +static uint16_t y; +static uint16_t z; + +// We're using the x/y dimensions to map to the x/y pixels on the matrix. We'll +// use the z-axis for "time". speed determines how fast time moves forward. Try +// 1 for a very slow moving effect, or 60 for something that ends up looking like +// water. +// uint16_t speed = 1; // almost looks like a painting, moves very slowly +uint16_t speed = 20; // a nice starting speed, mixes well with a scale of 100 +// uint16_t speed = 33; +// uint16_t speed = 100; // wicked fast! + +// Scale determines how far apart the pixels in our noise matrix are. Try +// changing these values around to see how it affects the motion of the display. The +// higher the value of scale, the more "zoomed out" the noise iwll be. A value +// of 1 will be so zoomed in, you'll mostly see solid colors. + +// uint16_t scale = 1; // mostly just solid colors +// uint16_t scale = 4011; // very zoomed out and shimmery +uint16_t scale = 311; + +// This is the array that we keep our computed noise values in +uint8_t noise[MAX_DIMENSION][MAX_DIMENSION]; + +void setup() { + // uncomment the following lines if you want to see FPS count information + // Serial.begin(38400); + // Serial.println("resetting!"); + delay(3000); + LEDS.addLeds(leds,NUM_LEDS); + LEDS.setBrightness(96); + + // Initialize our coordinates to some random values + x = random16(); + y = random16(); + z = random16(); +} + +// Fill the x/y array of 8-bit noise values using the inoise8 function. +void fillnoise8() { + for(int i = 0; i < MAX_DIMENSION; i++) { + int ioffset = scale * i; + for(int j = 0; j < MAX_DIMENSION; j++) { + int joffset = scale * j; + noise[i][j] = inoise8(x + ioffset,y + joffset,z); + } + } + z += speed; +} + + +void loop() { + static uint8_t ihue=0; + fillnoise8(); + for(int i = 0; i < kMatrixWidth; i++) { + for(int j = 0; j < kMatrixHeight; j++) { + // We use the value at the (i,j) coordinate in the noise + // array for our brightness, and the flipped value from (j,i) + // for our pixel's hue. + leds[XY(i,j)] = CHSV(noise[j][i],255,noise[i][j]); + + // You can also explore other ways to constrain the hue used, like below + // leds[XY(i,j)] = CHSV(ihue + (noise[j][i]>>2),255,noise[i][j]); + } + } + ihue+=1; + + LEDS.show(); + LEDS.countFPS(); + // delay(10); +} diff --git a/noise.cpp b/noise.cpp new file mode 100644 index 00000000..02557116 --- /dev/null +++ b/noise.cpp @@ -0,0 +1,339 @@ +#include + +static uint8_t p[] = { 151,160,137,91,90,15, + 131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,99,37,240,21,10,23, + 190, 6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,11,32,57,177,33, + 88,237,149,56,87,174,20,125,136,171,168, 68,175,74,165,71,134,139,48,27,166, + 77,146,158,231,83,111,229,122,60,211,133,230,220,105,92,41,55,46,245,40,244, + 102,143,54, 65,25,63,161, 1,216,80,73,209,76,132,187,208, 89,18,169,200,196, + 135,130,116,188,159,86,164,100,109,198,173,186, 3,64,52,217,226,250,124,123, + 5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182,189,28,42, + 223,183,170,213,119,248,152, 2,44,154,163, 70,221,153,101,155,167, 43,172,9, + 129,22,39,253, 19,98,108,110,79,113,224,232,178,185, 112,104,218,246,97,228, + 251,34,242,193,238,210,144,12,191,179,162,241, 81,51,145,235,249,14,239,107, + 49,192,214, 31,181,199,106,157,184, 84,204,176,115,121,50,45,127, 4,150,254, + 138,236,205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180,151 + }; +#define P(x) p[(x)] + +// +// #define FADE_12 +#define FADE_16 + +#ifdef FADE_12 +#define FADE logfade12 +#define LERP(a,b,u) lerp15by12(a,b,u) +#else +#define FADE(x) scale16(x,x) +#define LERP(a,b,u) lerp15by16(a,b,u) +#endif + +static int16_t __attribute__((always_inline)) grad16(uint8_t hash, int16_t x, int16_t y, int16_t z) { +#if 0 + switch(hash & 0xF) { + case 0: return (( x) + ( y))>>1; + case 1: return ((-x) + ( y))>>1; + case 2: return (( x) + (-y))>>1; + case 3: return ((-x) + (-y))>>1; + case 4: return (( x) + ( z))>>1; + case 5: return ((-x) + ( z))>>1; + case 6: return (( x) + (-z))>>1; + case 7: return ((-x) + (-z))>>1; + case 8: return (( y) + ( z))>>1; + case 9: return ((-y) + ( z))>>1; + case 10: return (( y) + (-z))>>1; + case 11: return ((-y) + (-z))>>1; + case 12: return (( y) + ( x))>>1; + case 13: return ((-y) + ( z))>>1; + case 14: return (( y) + (-x))>>1; + case 15: return ((-y) + (-z))>>1; + } +#else + hash = hash&15; + int16_t u = hash<8?x:y; + int16_t v = hash<4?y:hash==12||hash==14?x:z; + if(hash&1) { u = -u; } + if(hash&2) { v = -v; } + + return (u+v)>>1; +#endif +} + +static int8_t __attribute__((always_inline)) grad8(uint8_t hash, int8_t x, int8_t y, int8_t z) { +#if 0 + switch(hash & 0xF) { + case 0: return (( x) + ( y))>>1; + case 1: return ((-x) + ( y))>>1; + case 2: return (( x) + (-y))>>1; + case 3: return ((-x) + (-y))>>1; + case 4: return (( x) + ( z))>>1; + case 5: return ((-x) + ( z))>>1; + case 6: return (( x) + (-z))>>1; + case 7: return ((-x) + (-z))>>1; + case 8: return (( y) + ( z))>>1; + case 9: return ((-y) + ( z))>>1; + case 10: return (( y) + (-z))>>1; + case 11: return ((-y) + (-z))>>1; + case 12: return (( y) + ( x))>>1; + case 13: return ((-y) + ( z))>>1; + case 14: return (( y) + (-x))>>1; + case 15: return ((-y) + (-z))>>1; + } +#else + hash &= 0xF; + int8_t u = (hash&8)?y:x; + int8_t v = hash<4?y:hash==12||hash==14?x:z; + if(hash&1) { u = -u; } + if(hash&2) { v = -v; } + + return (u+v)>>1; +#endif +} + +#ifdef FADE_12 +uint16_t logfade12(uint16_t val) { + return scale16(val,val)>>4; +} + +static int16_t __attribute__((always_inline)) lerp15by12( int16_t a, int16_t b, fract16 frac) +{ + //if(1) return (lerp(frac,a,b)); + int16_t result; + if( b > a) { + uint16_t delta = b - a; + uint16_t scaled = scale16(delta,frac<<4); + result = a + scaled; + } else { + uint16_t delta = a - b; + uint16_t scaled = scale16(delta,frac<<4); + result = a - scaled; + } + return result; +} +#endif + +static int8_t __attribute__((always_inline)) lerp7by8( int8_t a, int8_t b, fract8 frac) +{ + // int8_t delta = b - a; + // int16_t prod = (uint16_t)delta * (uint16_t)frac; + // int8_t scaled = prod >> 8; + // int8_t result = a + scaled; + // return result; + int8_t result; + if( b > a) { + uint8_t delta = b - a; + uint8_t scaled = scale8( delta, frac); + result = a + scaled; + } else { + uint8_t delta = a - b; + uint8_t scaled = scale8( delta, frac); + result = a - scaled; + } + return result; +} + +uint16_t inoise16(uint32_t x, uint32_t y, uint32_t z) +{ + // Find the unit cube containing the point + uint8_t X = x>>16; + uint8_t Y = y>>16; + uint8_t Z = z>>16; + + // Hash cube corner coordinates + uint8_t A = P(X)+Y; + uint8_t AA = P(A)+Z; + uint8_t AB = P(A+1)+Z; + uint8_t B = P(X+1)+Y; + uint8_t BA = P(B) + Z; + uint8_t BB = P(B+1)+Z; + + // Get the relative position of the point in the cube + uint16_t u = x & 0xFFFF; + uint16_t v = y & 0xFFFF; + uint16_t w = z & 0xFFFF; + + // Get a signed version of the above for the grad function + int16_t xx = (u >> 1) & 0x7FFF; + int16_t yy = (v >> 1) & 0x7FFF; + int16_t zz = (w >> 1) & 0x7FFF; + uint16_t N = 0x8000L; + + u = FADE(u); v = FADE(v); w = FADE(w); + + + // skip the log fade adjustment for the moment, otherwise here we would + // adjust fade values for u,v,w + int16_t X1 = LERP(grad16(P(AA), xx, yy, zz), grad16(P(BA), xx - N, yy, zz), u); + int16_t X2 = LERP(grad16(P(AB), xx, yy-N, zz), grad16(P(BB), xx - N, yy - N, zz), u); + int16_t X3 = LERP(grad16(P(AA+1), xx, yy, zz-N), grad16(P(BA+1), xx - N, yy, zz-N), u); + int16_t X4 = LERP(grad16(P(AB+1), xx, yy-N, zz-N), grad16(P(BB+1), xx - N, yy - N, zz - N), u); + + int16_t Y1 = LERP(X1,X2,v); + int16_t Y2 = LERP(X3,X4,v); + + int16_t ans = LERP(Y1,Y2,w); + + return scale16by8(ans+15900,245)<<1; + // return N+ans; +} + +uint16_t inoise16(uint32_t x, uint32_t y) +{ + // Find the unit cube containing the point + uint8_t X = x>>16; + uint8_t Y = y>>16; + + // Hash cube corner coordinates + uint8_t A = P(X)+Y; + uint8_t AA = P(A); + uint8_t AB = P(A+1); + uint8_t B = P(X+1)+Y; + uint8_t BA = P(B); + uint8_t BB = P(B+1); + + // Get the relative position of the point in the cube + uint16_t u = x & 0xFFFF; + uint16_t v = y & 0xFFFF; + + // Get a signed version of the above for the grad function + int16_t xx = (u >> 1) & 0x7FFF; + int16_t yy = (v >> 1) & 0x7FFF; + uint16_t N = 0x8000L; + + u = FADE(u); v = FADE(v); + + int16_t X1 = LERP(grad16(P(AA), xx, yy, 0), grad16(P(BA), xx - N, yy, 0), u); + int16_t X2 = LERP(grad16(P(AB), xx, yy-N, 0), grad16(P(BB), xx - N, yy - N, 0), u); + + int16_t ans = LERP(X1,X2,v); + + return scale16by8(ans+15900,245)<<1; + // return N+ans; +} + +uint16_t inoise16(uint32_t x) +{ + // Find the unit cube containing the point + uint8_t X = x>>16; + + // Hash cube corner coordinates + uint8_t A = P(X); + uint8_t AA = P(A); + uint8_t B = P(X+1); + uint8_t BA = P(B); + + // Get the relative position of the point in the cube + uint16_t u = x & 0xFFFF; + + // Get a signed version of the above for the grad function + int16_t xx = (u >> 1) & 0x7FFF; + uint16_t N = 0x8000L; + + u = FADE(u); + + int16_t ans = LERP(grad16(P(AA), xx, 0, 0), grad16(P(BA), xx - N, 0, 0), u); + + return scale16by8(ans+15900,245)<<1; + // return N+ans; +} + +uint8_t inoise8(uint16_t x, uint16_t y, uint16_t z) +{ + // Find the unit cube containing the point + uint8_t X = x>>8; + uint8_t Y = y>>8; + uint8_t Z = z>>8; + + // Hash cube corner coordinates + uint8_t A = P(X)+Y; + uint8_t AA = P(A)+Z; + uint8_t AB = P(A+1)+Z; + uint8_t B = P(X+1)+Y; + uint8_t BA = P(B) + Z; + uint8_t BB = P(B+1)+Z; + + // Get the relative position of the point in the cube + uint8_t u = x; + uint8_t v = y; + uint8_t w = z; + + // Get a signed version of the above for the grad function + int8_t xx = (x>>1) & 0x7F; + int8_t yy = (y>>1) & 0x7F; + int8_t zz = (z>>1) & 0x7F; + uint8_t N = 0x80; + + // u = FADE(u); v = FADE(v); w = FADE(w); + u = scale8_LEAVING_R1_DIRTY(u,u); v = scale8_LEAVING_R1_DIRTY(v,v); w = scale8(w,w); + + int8_t X1 = lerp7by8(grad8(P(AA), xx, yy, zz), grad8(P(BA), xx - N, yy, zz), u); + int8_t X2 = lerp7by8(grad8(P(AB), xx, yy-N, zz), grad8(P(BB), xx - N, yy - N, zz), u); + int8_t X3 = lerp7by8(grad8(P(AA+1), xx, yy, zz-N), grad8(P(BA+1), xx - N, yy, zz-N), u); + int8_t X4 = lerp7by8(grad8(P(AB+1), xx, yy-N, zz-N), grad8(P(BB+1), xx - N, yy - N, zz - N), u); + + int8_t Y1 = lerp7by8(X1,X2,v); + int8_t Y2 = lerp7by8(X3,X4,v); + + int8_t ans = lerp7by8(Y1,Y2,w); + + return scale8((70+(ans)),234)<<1; +} + +uint8_t inoise8(uint16_t x, uint16_t y) +{ + // Find the unit cube containing the point + uint8_t X = x>>8; + uint8_t Y = y>>8; + + // Hash cube corner coordinates + uint8_t A = P(X)+Y; + uint8_t AA = P(A); + uint8_t AB = P(A+1); + uint8_t B = P(X+1)+Y; + uint8_t BA = P(B); + uint8_t BB = P(B+1); + + // Get the relative position of the point in the cube + uint8_t u = x; + uint8_t v = y; + + // Get a signed version of the above for the grad function + int8_t xx = (x>>1) & 0x7F; + int8_t yy = (y>>1) & 0x7F; + uint8_t N = 0x80; + + // u = FADE(u); v = FADE(v); w = FADE(w); + u = scale8_LEAVING_R1_DIRTY(u,u); v = scale8(v,v); + + int8_t X1 = lerp7by8(grad8(P(AA), xx, yy, 0), grad8(P(BA), xx - N, yy, 0), u); + int8_t X2 = lerp7by8(grad8(P(AB), xx, yy-N, 0), grad8(P(BB), xx - N, yy - N, 0), u); + + int8_t ans = lerp7by8(X1,X2,v); + + return scale8((70+(ans)),234)<<1; +} + +uint8_t inoise8(uint16_t x) +{ + // Find the unit cube containing the point + uint8_t X = x>>8; + + // Hash cube corner coordinates + uint8_t A = P(X); + uint8_t AA = P(A); + uint8_t B = P(X+1); + uint8_t BA = P(B); + + // Get the relative position of the point in the cube + uint8_t u = x; + + // Get a signed version of the above for the grad function + int8_t xx = (x>>1) & 0x7F; + uint8_t N = 0x80; + + u = scale8(u,u); + + int8_t ans = lerp7by8(grad8(P(AA), xx, 0, 0), grad8(P(BA), xx - N, 0, 0), u); + + return scale8((70+(ans)),234)<<1; +} diff --git a/noise.h b/noise.h new file mode 100644 index 00000000..07d12226 --- /dev/null +++ b/noise.h @@ -0,0 +1,20 @@ +#ifndef __INC_NOISE_H +#define __INC_NOISE_H + +// 16 bit, fixed point implementation of perlin's Simplex Noise. Coordinates are +// 16.16 fixed point values, 32 bit integers with integral coordinates in the high 16 +// bits and fractional in the low 16 bits, and the function takes 1d, 2d, and 3d coordinate +// values. +extern uint16_t inoise16(uint32_t x, uint32_t y, uint32_t z); +extern uint16_t inoise16(uint32_t x, uint32_t y); +extern uint16_t inoise16(uint32_t x); + +// 8 bit, fixed point implementation of perlin's Simplex Noise. Coordinates are +// 8.8 fixed point values, 16 bit integers with integral coordinates in the high 8 +// bits and fractional in the low 8 bits, and the function takes 1d, 2d, and 3d coordinate +// values. +extern uint8_t inoise8(uint16_t x, uint16_t y, uint16_t z); +extern uint8_t inoise8(uint16_t x, uint16_t y); +extern uint8_t inoise8(uint16_t x); + +#endif -- cgit v1.2.3 From 590309873a75d10f51fef4ee116b1bb5b1a16254 Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Sat, 31 May 2014 18:52:49 -0400 Subject: bumping release notes. --- preview_changes.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/preview_changes.txt b/preview_changes.txt index bc69c59f..da565b0e 100644 --- a/preview_changes.txt +++ b/preview_changes.txt @@ -17,3 +17,5 @@ * Adjusted VIRTAL_BITS of dithering from a flickery 8 to a more solid 3 * Added array versions of fade_video, fade_raw, and some variations * Added fill_gradient +* Added inoise8/inoise16 and example program +* Added LEDS.countFPS() for debugging framerate counts. Bit rough at the moment, thought -- cgit v1.2.3 From f3af26399d9a3da5284936a0c4b95103c2c9b39b Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Mon, 2 Jun 2014 02:10:28 -0400 Subject: Adding some sample fill functions and the NoisePlayground example for folks to play in. --- examples/NoisePlayground/NoisePlayground.ino | 71 +++++++++++ noise.cpp | 178 ++++++++++++++++++++++++++- noise.h | 24 ++++ 3 files changed, 270 insertions(+), 3 deletions(-) create mode 100644 examples/NoisePlayground/NoisePlayground.ino diff --git a/examples/NoisePlayground/NoisePlayground.ino b/examples/NoisePlayground/NoisePlayground.ino new file mode 100644 index 00000000..bc92acaa --- /dev/null +++ b/examples/NoisePlayground/NoisePlayground.ino @@ -0,0 +1,71 @@ +#include + +#define kMatrixWidth 16 +#define kMatrixHeight 16 + +#define NUM_LEDS (kMatrixWidth * kMatrixHeight) +// Param for different pixel layouts +#define kMatrixSerpentineLayout true + +// led array +CRGB leds[kMatrixWidth * kMatrixHeight]; + +// x,y, & time values +uint32_t x,y,time,hue_time; + +// Play with the values of the variables below and see what kinds of effects they +// have! More octaves will make things slower. + +// how many octaves to use for the brightness and hue functions +uint8_t octaves=2; +uint8_t hue_octaves=2; + +// the 'distance' between points on the x and y axis +int xscale=131; +int yscale=yscale; + +// the 'distance' between x/y points for the hue noise +int hue_scale=11; + +// how fast we move through time & hue noise +int time_speed=101; +int hue_speed=2; + +// adjust these values to move along the x or y axis between frames +int x_speed=0; +int y_speed=0; + +void loop() { + // fill the led array 2/16-bit noise values + fill_2dnoise16(leds, kMatrixWidth, kMatrixHeight, kMatrixSerpentineLayout, + octaves,x,xscale,y,yscale,time, + hue_octaves,x,hue_scale,y,hue_scale,hue_time, false); + LEDS.show(); + LEDS.countFPS(); + + // adjust the intra-frame time values + x += x_speed; + y += y_speed; + time += time_speed; + hue_time += hue_speed; +} + + +void setup() { + Serial.begin(38400); + Serial.println("resetting!"); + + delay(3000); + LEDS.addLeds(leds,NUM_LEDS); + LEDS.setBrightness(48); + + // initialize the x/y and time values + random16_set_seed(8934); + random16_add_entropy(analogRead(3)); + + x = (uint32_t)((uint32_t)random16() << 16) | random16(); + y = (uint32_t)((uint32_t)random16() << 16) | random16(); + time = (uint32_t)((uint32_t)random16() << 16) | random16(); + hue_time = (uint32_t)((uint32_t)random16() << 16) | random16(); + +} diff --git a/noise.cpp b/noise.cpp index 02557116..ce329d4c 100644 --- a/noise.cpp +++ b/noise.cpp @@ -173,7 +173,7 @@ uint16_t inoise16(uint32_t x, uint32_t y, uint32_t z) int16_t ans = LERP(Y1,Y2,w); - return scale16by8(ans+15900,245)<<1; + return scale16by8(ans+15900,250)<<1; // return N+ans; } @@ -207,7 +207,7 @@ uint16_t inoise16(uint32_t x, uint32_t y) int16_t ans = LERP(X1,X2,v); - return scale16by8(ans+15900,245)<<1; + return scale16by8(ans+15900,250)<<1; // return N+ans; } @@ -233,7 +233,7 @@ uint16_t inoise16(uint32_t x) int16_t ans = LERP(grad16(P(AA), xx, 0, 0), grad16(P(BA), xx - N, 0, 0), u); - return scale16by8(ans+15900,245)<<1; + return scale16by8(ans+15900,250)<<1; // return N+ans; } @@ -337,3 +337,175 @@ uint8_t inoise8(uint16_t x) return scale8((70+(ans)),234)<<1; } + +void fill_raw_noise8(uint8_t *pData, uint8_t num_points, uint8_t octaves, uint16_t x, int scale, uint16_t time) { + uint32_t _xx = x; + uint32_t scx = scale; + for(int o = 0; o < octaves; o++) { + for(int i = 0,xx=_xx; i < num_points; i++, xx+=scx) { + pData[i] = qadd8(pData[i],inoise8(xx,time)>>o); + } + + _xx <<= 1; + scx <<= 1; + } +} + +void fill_raw_noise16into8(uint8_t *pData, uint8_t num_points, uint8_t octaves, uint32_t x, int scale, uint32_t time) { + uint32_t _xx = x; + uint32_t scx = scale; + for(int o = 0; o < octaves; o++) { + for(int i = 0,xx=_xx; i < num_points; i++, xx+=scx) { + uint32_t accum = (inoise16(xx,time))>>o; + accum += (pData[i]<<8); + if(accum > 65535) { accum = 65535; } + pData[i] = accum>>8; + } + + _xx <<= 1; + scx <<= 1; + } +} + +void fill_raw_2dnoise8(uint8_t *pData, int width, int height, uint8_t octaves, uint16_t x, int scalex, uint16_t y, int scaley, uint16_t time) { + uint32_t _xx = x; + uint32_t _yy = y; + uint32_t scx = scalex; + uint32_t scy = scaley; + for(int o = 0; o < octaves; o++) { + for(int i = 0,yy=_yy; i < height; i++,yy+=scy) { + uint8_t *pRow = pData + (i * width); + for(int j = 0,xx=_xx; j < width; j++,xx+=scx) { + pRow[j] = qadd8(pRow[j],inoise8(xx,yy,time)>>o); + } + } + _xx <<= 1; + scx <<= 1; + _yy <<= 1; + scy <<= 1; + } +} + +void fill_raw_2dnoise16into8(uint8_t *pData, int width, int height, uint8_t octaves, uint32_t x, int scalex, uint32_t y, int scaley, uint32_t time) { + uint32_t _xx = x; + uint32_t _yy = y; + uint32_t scx = scalex; + uint32_t scy = scaley; + for(int o = 0; o < octaves; o++) { + for(int i = 0,yy=_yy; i < height; i++,yy+=scy) { + uint8_t *pRow = pData + (i * width); + for(int j = 0,xx=_xx; j < width; j++,xx+=scx) { + uint32_t accum = (inoise16(xx,yy,time))>>o; + accum += (pRow[j]<<8); + if(accum > 65535) { accum = 65535; } + pRow[j] = accum>>8; + } + } + _xx <<= 1; + scx <<= 1; + _yy <<= 1; + scy <<= 1; + } +} + +void fill_noise8(CRGB *leds, int num_leds, + uint8_t octaves, uint16_t x, int scale, + uint8_t hue_octaves, uint16_t hue_x, int hue_scale, + uint16_t time) { + uint8_t V[num_leds]; + uint8_t H[num_leds]; + + memset(V,0,num_leds); + memset(H,0,num_leds); + + fill_raw_noise8(V,num_leds,octaves,x,scale,time); + fill_raw_noise8(H,num_leds,hue_octaves,hue_x,hue_scale,time); + + for(int i = 0; i < num_leds; i++) { + leds[i] = CHSV(H[i],255,V[i]); + } +} + +void fill_noise16(CRGB *leds, int num_leds, + uint8_t octaves, uint16_t x, int scale, + uint8_t hue_octaves, uint16_t hue_x, int hue_scale, + uint16_t time) { + uint8_t V[num_leds]; + uint8_t H[num_leds]; + + memset(V,0,num_leds); + memset(H,0,num_leds); + + fill_raw_noise16into8(V,num_leds,octaves,x,scale,time); + fill_raw_noise8(H,num_leds,hue_octaves,hue_x,hue_scale,time); + + for(int i = 0; i < num_leds; i++) { + leds[i] = CHSV(H[i],255,V[i]); + } +} + +void fill_2dnoise8(CRGB *leds, int width, int height, bool serpentine, + uint8_t octaves, uint16_t x, int xscale, uint16_t y, int yscale, uint16_t time, + uint8_t hue_octaves, uint16_t hue_x, int hue_xscale, uint16_t hue_y, uint16_t hue_yscale,uint16_t hue_time,bool blend) { + uint8_t V[height][width]; + uint8_t H[height][width]; + + memset(V,0,height*width); + memset(H,0,height*width); + + fill_raw_2dnoise8((uint8_t*)V,width,height,octaves,x,xscale,y,yscale,time); + fill_raw_2dnoise8((uint8_t*)H,width,height,hue_octaves,hue_x,hue_xscale,hue_y,hue_yscale,hue_time); + + int w1 = width-1; + int h1 = height-1; + for(int i = 0; i < height; i++) { + int wb = i*width; + for(int j = 0; j < width; j++) { + CRGB led(CHSV(H[h1-i][w1-j],255,V[i][j])); + + int pos = j; + if(serpentine && (i&0x1)) { + pos = w1-j; + } + + if(blend) { + leds[wb+pos] >>= 1; leds[wb+pos] += (led>>=1); + } else { + leds[wb+pos] = led; + } + } + } +} + +void fill_2dnoise16(CRGB *leds, int width, int height, bool serpentine, + uint8_t octaves, uint32_t x, int xscale, uint32_t y, int yscale, uint32_t time, + uint8_t hue_octaves, uint16_t hue_x, int hue_xscale, uint16_t hue_y, uint16_t hue_yscale,uint16_t hue_time, bool blend) { + uint8_t V[height][width]; + uint8_t H[height][width]; + + memset(V,0,height*width); + memset(H,0,height*width); + + fill_raw_2dnoise16into8((uint8_t*)V,width,height,octaves,x,xscale,y,yscale,time); + fill_raw_2dnoise8((uint8_t*)H,width,height,hue_octaves,hue_x,hue_xscale,hue_y,hue_yscale,hue_time); + + int w1 = width-1; + int h1 = height-1; + for(int i = 0; i < height; i++) { + int wb = i*width; + for(int j = 0; j < width; j++) { + CRGB led(CHSV(H[h1-i][w1-j],255,V[i][j])); + + int pos = j; + if(serpentine && (i&0x1)) { + pos = w1-j; + } + + if(blend) { + leds[wb+pos] >>= 1; leds[wb+pos] += (led>>=1); + } else { + leds[wb+pos] = led; + } + } + } +} diff --git a/noise.h b/noise.h index 07d12226..84513f9d 100644 --- a/noise.h +++ b/noise.h @@ -17,4 +17,28 @@ extern uint8_t inoise8(uint16_t x, uint16_t y, uint16_t z); extern uint8_t inoise8(uint16_t x, uint16_t y); extern uint8_t inoise8(uint16_t x); +// Raw noise fill functions - fill into a 1d or 2d array of 8-bit values using either 8-bit noise or 16-bit noise +// functions. +void fill_raw_noise8(uint8_t *pData, uint8_t num_points, uint8_t octaves, uint16_t x, int scale, uint16_t time); +void fill_raw_noise16into8(uint8_t *pData, uint8_t num_points, uint8_t octaves, uint32_t x, int scale, uint32_t time); +void fill_raw_2dnoise8(uint8_t *pData, int width, int height, uint8_t octaves, uint16_t x, int scalex, uint16_t y, int scaley, uint16_t time); +void fill_raw_2dnoise16into8(uint8_t *pData, int width, int height, uint8_t octaves, uint32_t x, int scalex, uint32_t y, int scaley, uint32_t time); + + +// fill functions to fill leds with values based on noise functions. These functions use the fill_raw_* functions as appropriate. +void fill_noise8(CRGB *leds, int num_leds, + uint8_t octaves, uint16_t x, int scale, + uint8_t hue_octaves, uint16_t hue_x, int hue_scale, + uint16_t time); +void fill_noise16(CRGB *leds, int num_leds, + uint8_t octaves, uint16_t x, int scale, + uint8_t hue_octaves, uint16_t hue_x, int hue_scale, + uint16_t time); +void fill_2dnoise8(CRGB *leds, int width, int height, bool serpentine, + uint8_t octaves, uint16_t x, int xscale, uint16_t y, int yscale, uint16_t time, + uint8_t hue_octaves, uint16_t hue_x, int hue_xscale, uint16_t hue_y, uint16_t hue_yscale,uint16_t hue_time,bool blend); +void fill_2dnoise16(CRGB *leds, int width, int height, bool serpentine, + uint8_t octaves, uint32_t x, int xscale, uint32_t y, int yscale, uint32_t time, + uint8_t hue_octaves, uint16_t hue_x, int hue_xscale, uint16_t hue_y, uint16_t hue_yscale,uint16_t hue_time, bool blend); + #endif -- cgit v1.2.3 From 2b9c17be316c70440bc5568202a5b869589f2e14 Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Mon, 2 Jun 2014 02:35:23 -0400 Subject: tweaking the playground and fixing a small initialization bug --- examples/NoisePlayground/NoisePlayground.ino | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/examples/NoisePlayground/NoisePlayground.ino b/examples/NoisePlayground/NoisePlayground.ino index bc92acaa..cc4ed79b 100644 --- a/examples/NoisePlayground/NoisePlayground.ino +++ b/examples/NoisePlayground/NoisePlayground.ino @@ -21,19 +21,19 @@ uint8_t octaves=2; uint8_t hue_octaves=2; // the 'distance' between points on the x and y axis -int xscale=131; -int yscale=yscale; +int xscale=301; +int yscale=301; // the 'distance' between x/y points for the hue noise int hue_scale=11; // how fast we move through time & hue noise int time_speed=101; -int hue_speed=2; +int hue_speed=3; // adjust these values to move along the x or y axis between frames int x_speed=0; -int y_speed=0; +int y_speed=1; void loop() { // fill the led array 2/16-bit noise values @@ -52,16 +52,16 @@ void loop() { void setup() { + // initialize the x/y and time values + random16_set_seed(18934); + random16_add_entropy(analogRead(3)); + Serial.begin(38400); Serial.println("resetting!"); delay(3000); LEDS.addLeds(leds,NUM_LEDS); - LEDS.setBrightness(48); - - // initialize the x/y and time values - random16_set_seed(8934); - random16_add_entropy(analogRead(3)); + LEDS.setBrightness(32); x = (uint32_t)((uint32_t)random16() << 16) | random16(); y = (uint32_t)((uint32_t)random16() << 16) | random16(); -- cgit v1.2.3 From bc82af3c413bbc8d301f8d9c477885cc0353d0fb Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Mon, 2 Jun 2014 13:11:12 -0400 Subject: Adding leds/[] operators on controllers and LEDS. --- FastLED.cpp | 14 +++++++++- FastLED.h | 30 ++++++++++++--------- controller.h | 85 +++++++++++++++++++++++++++++++++--------------------------- noise.cpp | 18 +++++-------- 4 files changed, 85 insertions(+), 62 deletions(-) diff --git a/FastLED.cpp b/FastLED.cpp index d93b765e..1e6ecf2f 100644 --- a/FastLED.cpp +++ b/FastLED.cpp @@ -21,7 +21,7 @@ CFastLED::CFastLED() { } CLEDController &CFastLED::addLeds(CLEDController *pLed, - const struct CRGB *data, + struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset) { int nOffset = (nLedsIfOffset > 0) ? nLedsOrOffset : 0; int nLeds = (nLedsIfOffset > 0) ? nLedsIfOffset : nLedsOrOffset; @@ -39,6 +39,18 @@ void CFastLED::show(uint8_t scale) { } } +CLEDController & CFastLED::operator[](int x) { + CLEDController *pCur = CLEDController::head(); + while(x-- && pCur) { + pCur = pCur->next(); + } + if(pCur == NULL) { + return *(CLEDController::head()); + } else { + return *pCur; + } +} + void CFastLED::showColor(const struct CRGB & color, uint8_t scale) { CLEDController *pCur = CLEDController::head(); while(pCur) { diff --git a/FastLED.h b/FastLED.h index 00d68696..c1349fd9 100644 --- a/FastLED.h +++ b/FastLED.h @@ -81,7 +81,7 @@ class CFastLED { public: CFastLED(); - static CLEDController &addLeds(CLEDController *pLed, const struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0); + static CLEDController &addLeds(CLEDController *pLed, struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0); template static CLEDController &addLeds(const struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) { switch(CHIPSET) { @@ -93,7 +93,7 @@ public: } } - template static CLEDController &addLeds(const struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) { + template static CLEDController &addLeds(struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) { switch(CHIPSET) { case LPD8806: { static LPD8806Controller c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); } case WS2801: { static WS2801Controller c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); } @@ -103,7 +103,7 @@ public: } } - template CLEDController &addLeds(const struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) { + template CLEDController &addLeds(struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) { switch(CHIPSET) { case LPD8806: { static LPD8806Controller c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); } case WS2801: { static WS2801Controller c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); } @@ -114,34 +114,34 @@ public: } #ifdef SPI_DATA - template static CLEDController &addLeds(const struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) { + template static CLEDController &addLeds(struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) { return addLeds(data, nLedsOrOffset, nLedsIfOffset); } - template static CLEDController &addLeds(const struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) { + template static CLEDController &addLeds(struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) { return addLeds(data, nLedsOrOffset, nLedsIfOffset); } - template static CLEDController &addLeds(const struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) { + template static CLEDController &addLeds(struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) { return addLeds(data, nLedsOrOffset, nLedsIfOffset); } #endif template class CHIPSET, uint8_t DATA_PIN> - static CLEDController &addLeds(const struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) { + static CLEDController &addLeds(struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) { static CHIPSET c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); } template class CHIPSET, uint8_t DATA_PIN, EOrder RGB_ORDER> - static CLEDController &addLeds(const struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) { + static CLEDController &addLeds(struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) { static CHIPSET c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); } template class CHIPSET, uint8_t DATA_PIN> - static CLEDController &addLeds(const struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) { + static CLEDController &addLeds(struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) { static CHIPSET c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); } @@ -149,7 +149,7 @@ public: #ifdef FASTSPI_USE_DMX_SIMPLE template - static CLEDController &addLeds(const struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) + static CLEDController &addLeds(struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) { switch(CHIPSET) { case DMX: { static DMXController controller; return addLeds(&controller, data, nLedsOrOffset, nLedsIfOffset); } @@ -157,7 +157,7 @@ public: } template - static CLEDController &addLeds(const struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) { + static CLEDController &addLeds(struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) { switch(CHIPSET) { case DMX: {static DMXController controller; return addLeds(&controller, data, nLedsOrOffset, nLedsIfOffset); } } @@ -166,7 +166,7 @@ public: #ifdef HAS_BLOCKLESS template - static CLEDController &addLeds(const struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) { + static CLEDController &addLeds(struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) { switch(CHIPSET) { case WS2811_PORTC: return addLeds(new BlockClocklessController(), data, nLedsOrOffset, nLedsIfOffset); } @@ -200,6 +200,12 @@ public: // nFrames calls, it will print a summary of FPS info out to the serial port. // If the serial port isn't opened, this function does nothing. void countFPS(int nFrames=100); + + CLEDController & operator[](int x); + + int size() { return (*this)[0].size(); } + + CRGB *leds() { return (*this)[0].leds(); } }; extern CFastLED & FastSPI_LED; diff --git a/controller.h b/controller.h index 80de389d..a2519e1f 100644 --- a/controller.h +++ b/controller.h @@ -8,8 +8,8 @@ #define RO(X) RGB_BYTE(RGB_ORDER, X) #define RGB_BYTE(RO,X) (((RO)>>(3*(2-(X)))) & 0x3) -#define RGB_BYTE0(RO) ((RO>>6) & 0x3) -#define RGB_BYTE1(RO) ((RO>>3) & 0x3) +#define RGB_BYTE0(RO) ((RO>>6) & 0x3) +#define RGB_BYTE1(RO) ((RO>>3) & 0x3) #define RGB_BYTE2(RO) ((RO) & 0x3) // operator byte *(struct CRGB[] arr) { return (byte*)arr; } @@ -19,20 +19,20 @@ typedef uint8_t EDitherMode; ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// +// // LED Controller interface definition // ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -/// Base definition for an LED controller. Pretty much the methods that every LED controller object will make available. +/// Base definition for an LED controller. Pretty much the methods that every LED controller object will make available. /// Note that the showARGB method is not impelemented for all controllers yet. Note also the methods for eventual checking /// of background writing of data (I'm looking at you, teensy 3.0 DMA controller!). If you want to pass LED controllers around /// to methods, make them references to this type, keeps your code saner. However, most people won't be seeing/using these objects /// directly at all -class CLEDController { +class CLEDController { protected: friend class CFastLED; - const CRGB *m_Data; + CRGB *m_Data; CLEDController *m_pNext; CRGB m_ColorCorrection; CRGB m_ColorTemperature; @@ -44,7 +44,7 @@ protected: // set all the leds on the controller to a given color virtual void showColor(const struct CRGB & data, int nLeds, CRGB scale) = 0; - // note that the uint8_ts will be in the order that you want them sent out to the device. + // note that the uint8_ts will be in the order that you want them sent out to the device. // nLeds is the number of RGB leds being written to virtual void show(const struct CRGB *data, int nLeds, CRGB scale) = 0; @@ -77,11 +77,11 @@ public: } // show function using the "attached to this controller" led data - void showLeds(uint8_t brightness=255) { + void showLeds(uint8_t brightness=255) { show(m_Data, m_nLeds, getAdjustment(brightness)); } - void showColor(const struct CRGB & data, uint8_t brightness=255) { + void showColor(const struct CRGB & data, uint8_t brightness=255) { showColor(data, m_nLeds, getAdjustment(brightness)); } @@ -95,19 +95,28 @@ public: show(data, nLeds, getAdjustment(brightness)) } #endif - - CLEDController & setLeds(const CRGB *data, int nLeds) { + + CLEDController & setLeds(CRGB *data, int nLeds) { m_Data = data; m_nLeds = nLeds; return *this; } void clearLedData() { - if(m_Data) { + if(m_Data) { memset8((void*)m_Data, 0, sizeof(struct CRGB) * m_nLeds); } } + // How many leds does this controller manage? + int size() { return m_nLeds; } + + // Pointer to the CRGB array for this controller + CRGB* leds() { return m_Data; } + + // Reference to the n'th item in the controller + CRGB &operator[](int x) { return m_Data[x]; } + inline CLEDController & setDither(uint8_t ditherMode = BINARY_DITHER) { m_DitherMode = ditherMode; return *this; } inline uint8_t getDither() { return m_DitherMode; } @@ -119,17 +128,17 @@ public: CLEDController & setTemperature(ColorTemperature temperature) { m_ColorTemperature = temperature; return *this; } CRGB getTemperature() { return m_ColorTemperature; } - CRGB getAdjustment(uint8_t scale) { + CRGB getAdjustment(uint8_t scale) { #if defined(NO_CORRECTION) && (NO_CORRECTION==1) return CRGB(scale,scale,scale); #else CRGB adj(0,0,0); - if(scale > 0) { - for(uint8_t i = 0; i < 3; i++) { + if(scale > 0) { + for(uint8_t i = 0; i < 3; i++) { uint8_t cc = m_ColorCorrection.raw[i]; uint8_t ct = m_ColorTemperature.raw[i]; - if(cc > 0 && ct > 0) { + if(cc > 0 && ct > 0) { uint32_t work = (((uint32_t)cc)+1) * (((uint32_t)ct)+1) * scale; work /= 0x10000L; adj.raw[i] = work & 0xFF; @@ -143,11 +152,11 @@ public: }; // Pixel controller class. This is the class that we use to centralize pixel access in a block of data, including -// support for things like RGB reordering, scaling, dithering, skipping (for ARGB data), and eventually, we will +// support for things like RGB reordering, scaling, dithering, skipping (for ARGB data), and eventually, we will // centralize 8/12/16 conversions here as well. template struct PixelController { - const uint8_t *mData; + const uint8_t *mData; int mLen; uint8_t d[3]; uint8_t e[3]; @@ -186,7 +195,7 @@ struct PixelController { #ifdef SUPPORT_ARGB PixelController(const CARGB &d, int len, CRGB & s, EDitherMode dither = BINARY_DITHER) : mData((const uint8_t*)&d), mLen(len), mScale(s) { enable_dithering(dither); - // skip the A in CARGB + // skip the A in CARGB mData += 1; mAdvance = 0; } @@ -195,7 +204,7 @@ struct PixelController { enable_dithering(dither); // skip the A in CARGB mData += 1; - mAdvance = 4; + mAdvance = 4; } #endif @@ -239,7 +248,7 @@ struct PixelController { // It's initialized to the reversed bits of R. // If 'ditherBits' is 2, Q here will cycle through (0,128,64,192) byte Q = 0; - + // Reverse bits in a byte { if(R & 0x01) { Q |= 0x80; } @@ -251,7 +260,7 @@ struct PixelController { if(R & 0x40) { Q |= 0x02; } if(R & 0x80) { Q |= 0x01; } } - + // Now we adjust Q to fall in the center of each range, // instead of at the start of the range. // If ditherBits is 2, Q will be (0, 128, 64, 192) at first, @@ -259,13 +268,13 @@ struct PixelController { if( ditherBits < 8) { Q += 0x01 << (7 - ditherBits); } - + // D and E form the "scaled dither signal" // which is added to pixel values to affect the // actual dithering. - + // Setup the initial D and E values - for(int i = 0; i < 3; i++) { + for(int i = 0; i < 3; i++) { byte s = mScale.raw[i]; e[i] = s ? (256/s) + 1 : 0; d[i] = scale8(Q, e[i]); @@ -275,10 +284,10 @@ struct PixelController { } // Do we have n pixels left to process? - __attribute__((always_inline)) inline bool has(int n) { + __attribute__((always_inline)) inline bool has(int n) { return mLen >= n; } - + // toggle dithering enable void enable_dithering(EDitherMode dither) { switch(dither) { @@ -287,15 +296,15 @@ struct PixelController { } } - // get the amount to advance the pointer by + // get the amount to advance the pointer by __attribute__((always_inline)) inline int advanceBy() { return mAdvance; } - + // advance the data pointer forward, adjust position counter __attribute__((always_inline)) inline void advanceData() { mData += mAdvance; mLen--;} - // step the dithering forward + // step the dithering forward __attribute__((always_inline)) inline void stepDithering() { - // IF UPDATING HERE, BE SURE TO UPDATE THE ASM VERSION IN + // IF UPDATING HERE, BE SURE TO UPDATE THE ASM VERSION IN // clockless_trinket.h! d[0] = e[0] - d[0]; d[1] = e[1] - d[1]; @@ -303,7 +312,7 @@ struct PixelController { } // Some chipsets pre-cycle the first byte, which means we want to cycle byte 0's dithering separately - __attribute__((always_inline)) inline void preStepFirstByteDithering() { + __attribute__((always_inline)) inline void preStepFirstByteDithering() { d[RO(0)] = e[RO(0)] - d[RO(0)]; } @@ -316,11 +325,11 @@ struct PixelController { template __attribute__((always_inline)) inline static uint8_t advanceAndLoadAndScale(PixelController & pc) { pc.advanceData(); return pc.loadAndScale(pc); } // Helper functions to get around gcc stupidities - __attribute__((always_inline)) inline uint8_t loadAndScale0() { return loadAndScale<0>(*this); } - __attribute__((always_inline)) inline uint8_t loadAndScale1() { return loadAndScale<1>(*this); } - __attribute__((always_inline)) inline uint8_t loadAndScale2() { return loadAndScale<2>(*this); } - __attribute__((always_inline)) inline uint8_t advanceAndLoadAndScale0() { return advanceAndLoadAndScale<0>(*this); } - __attribute__((always_inline)) inline uint8_t stepAdvanceAndLoadAndScale0() { stepDithering(); return advanceAndLoadAndScale<0>(*this); } + __attribute__((always_inline)) inline uint8_t loadAndScale0() { return loadAndScale<0>(*this); } + __attribute__((always_inline)) inline uint8_t loadAndScale1() { return loadAndScale<1>(*this); } + __attribute__((always_inline)) inline uint8_t loadAndScale2() { return loadAndScale<2>(*this); } + __attribute__((always_inline)) inline uint8_t advanceAndLoadAndScale0() { return advanceAndLoadAndScale<0>(*this); } + __attribute__((always_inline)) inline uint8_t stepAdvanceAndLoadAndScale0() { stepDithering(); return advanceAndLoadAndScale<0>(*this); } }; -#endif \ No newline at end of file +#endif diff --git a/noise.cpp b/noise.cpp index ce329d4c..1117c2b6 100644 --- a/noise.cpp +++ b/noise.cpp @@ -386,25 +386,21 @@ void fill_raw_2dnoise8(uint8_t *pData, int width, int height, uint8_t octaves, u } } -void fill_raw_2dnoise16into8(uint8_t *pData, int width, int height, uint8_t octaves, uint32_t x, int scalex, uint32_t y, int scaley, uint32_t time) { - uint32_t _xx = x; - uint32_t _yy = y; - uint32_t scx = scalex; - uint32_t scy = scaley; +inline void fill_raw_2dnoise16into8(uint8_t *pData, int width, int height, uint8_t octaves, uint32_t x, int scalex, uint32_t y, int scaley, uint32_t time) { for(int o = 0; o < octaves; o++) { - for(int i = 0,yy=_yy; i < height; i++,yy+=scy) { + for(int i = 0,yy=y; i < height; i++,yy+=scaley) { uint8_t *pRow = pData + (i * width); - for(int j = 0,xx=_xx; j < width; j++,xx+=scx) { + for(int j = 0,xx=x; j < width; j++,xx+=scalex) { uint32_t accum = (inoise16(xx,yy,time))>>o; accum += (pRow[j]<<8); if(accum > 65535) { accum = 65535; } pRow[j] = accum>>8; } } - _xx <<= 1; - scx <<= 1; - _yy <<= 1; - scy <<= 1; + x <<= 1; + scalex <<= 1; + y <<= 1; + scaley <<= 1; } } -- cgit v1.2.3 From 70ea308f624bd760a6b5540363dacf681bcda92c Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Mon, 2 Jun 2014 13:18:51 -0400 Subject: Here, have some more memory. PROGMEM has some cost, but getting 257 bytes of ram back is more important. --- noise.cpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/noise.cpp b/noise.cpp index 1117c2b6..6d2db292 100644 --- a/noise.cpp +++ b/noise.cpp @@ -1,6 +1,16 @@ #include +#include -static uint8_t p[] = { 151,160,137,91,90,15, +#define USE_PROGMEM +#ifdef USE_PROGMEM +#define FL_PROGMEM PROGMEM +#define P(x) pgm_read_byte_near(p + x) +#else +#define FL_PROGMEM +#define P(x) p[(x)] +#endif + +PROGMEM static uint8_t p[] = { 151,160,137,91,90,15, 131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,99,37,240,21,10,23, 190, 6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,11,32,57,177,33, 88,237,149,56,87,174,20,125,136,171,168, 68,175,74,165,71,134,139,48,27,166, @@ -14,7 +24,6 @@ static uint8_t p[] = { 151,160,137,91,90,15, 49,192,214, 31,181,199,106,157,184, 84,204,176,115,121,50,45,127, 4,150,254, 138,236,205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180,151 }; -#define P(x) p[(x)] // // #define FADE_12 -- cgit v1.2.3 From 66bddbcacec68cb078a2df73f1c2191a070e4506 Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Mon, 2 Jun 2014 13:19:14 -0400 Subject: Hey look, new APIs for getting at leds.. --- examples/NoisePlayground/NoisePlayground.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/NoisePlayground/NoisePlayground.ino b/examples/NoisePlayground/NoisePlayground.ino index cc4ed79b..7d13cbef 100644 --- a/examples/NoisePlayground/NoisePlayground.ino +++ b/examples/NoisePlayground/NoisePlayground.ino @@ -37,7 +37,7 @@ int y_speed=1; void loop() { // fill the led array 2/16-bit noise values - fill_2dnoise16(leds, kMatrixWidth, kMatrixHeight, kMatrixSerpentineLayout, + fill_2dnoise16(LEDS.leds(), kMatrixWidth, kMatrixHeight, kMatrixSerpentineLayout, octaves,x,xscale,y,yscale,time, hue_octaves,x,hue_scale,y,hue_scale,hue_time, false); LEDS.show(); -- cgit v1.2.3 From 6079de290ed535656a2167f704b487c4c7fb7d41 Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Mon, 2 Jun 2014 13:32:06 -0400 Subject: Tweaking a bit. --- noise.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/noise.cpp b/noise.cpp index 6d2db292..fd13cd79 100644 --- a/noise.cpp +++ b/noise.cpp @@ -469,7 +469,7 @@ void fill_2dnoise8(CRGB *leds, int width, int height, bool serpentine, CRGB led(CHSV(H[h1-i][w1-j],255,V[i][j])); int pos = j; - if(serpentine && (i&0x1)) { + if(serpentine) { pos = w1-j; } @@ -502,7 +502,7 @@ void fill_2dnoise16(CRGB *leds, int width, int height, bool serpentine, CRGB led(CHSV(H[h1-i][w1-j],255,V[i][j])); int pos = j; - if(serpentine && (i&0x1)) { + if(serpentine) { pos = w1-j; } -- cgit v1.2.3 From 433a672b0ed6783397518a70c21b52253bdc65a9 Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Mon, 2 Jun 2014 13:38:08 -0400 Subject: Only want progmem on avr --- examples/NoisePlayground/NoisePlayground.ino | 2 +- noise.cpp | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/examples/NoisePlayground/NoisePlayground.ino b/examples/NoisePlayground/NoisePlayground.ino index 7d13cbef..08277093 100644 --- a/examples/NoisePlayground/NoisePlayground.ino +++ b/examples/NoisePlayground/NoisePlayground.ino @@ -61,7 +61,7 @@ void setup() { delay(3000); LEDS.addLeds(leds,NUM_LEDS); - LEDS.setBrightness(32); + LEDS.setBrightness(96); x = (uint32_t)((uint32_t)random16() << 16) | random16(); y = (uint32_t)((uint32_t)random16() << 16) | random16(); diff --git a/noise.cpp b/noise.cpp index fd13cd79..8500f21c 100644 --- a/noise.cpp +++ b/noise.cpp @@ -1,7 +1,10 @@ #include #include +#ifdef FASTLED_AVR #define USE_PROGMEM +#endf + #ifdef USE_PROGMEM #define FL_PROGMEM PROGMEM #define P(x) pgm_read_byte_near(p + x) -- cgit v1.2.3 From 4b47a7c7512e5fd6ff8126bbfe2b7439999e2149 Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Mon, 2 Jun 2014 13:43:45 -0400 Subject: fix typo --- noise.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/noise.cpp b/noise.cpp index 8500f21c..4b41bf35 100644 --- a/noise.cpp +++ b/noise.cpp @@ -3,7 +3,7 @@ #ifdef FASTLED_AVR #define USE_PROGMEM -#endf +#endif #ifdef USE_PROGMEM #define FL_PROGMEM PROGMEM -- cgit v1.2.3 From 5abbf749036e0c684ab08e562c7485361dda3888 Mon Sep 17 00:00:00 2001 From: Mark Kriegsman Date: Mon, 2 Jun 2014 15:56:24 -0400 Subject: Restoring 'serpentine' functionality. Might be faster to move it out of the loop, but at least it's functional this way. --- noise.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/noise.cpp b/noise.cpp index 4b41bf35..ecd2b181 100644 --- a/noise.cpp +++ b/noise.cpp @@ -472,7 +472,7 @@ void fill_2dnoise8(CRGB *leds, int width, int height, bool serpentine, CRGB led(CHSV(H[h1-i][w1-j],255,V[i][j])); int pos = j; - if(serpentine) { + if(serpentine && (i & 0x1)) { pos = w1-j; } @@ -505,7 +505,7 @@ void fill_2dnoise16(CRGB *leds, int width, int height, bool serpentine, CRGB led(CHSV(H[h1-i][w1-j],255,V[i][j])); int pos = j; - if(serpentine) { + if(serpentine && (i & 0x1)) { pos = w1-j; } -- cgit v1.2.3 From d6b5f717981f3936a4d56375b06b21ad0f2e3556 Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Mon, 2 Jun 2014 22:30:33 -0400 Subject: Adding fractional types. Expanding the raw fill functions to include real 16 bit as well as take parameters for frequency and amplitude. --- lib8tion.h | 24 ++++++++++ noise.cpp | 151 +++++++++++++++++++++++++++++++++++++++++++++++++------------ noise.h | 2 + 3 files changed, 148 insertions(+), 29 deletions(-) diff --git a/lib8tion.h b/lib8tion.h index 233132e8..86d3012a 100644 --- a/lib8tion.h +++ b/lib8tion.h @@ -1574,4 +1574,28 @@ LIB8STATIC uint8_t cubicwave8(uint8_t in) +template class q { + T i:I; + T f:F; +public: + q(float fx) { i = fx; f = (fx-i) * (1<>F); } + uint16_t operator*(uint16_t v) { return (v*i) + ((v*f)>>F); } + int32_t operator*(int32_t v) { return (v*i) + ((v*f)>>F); } + int16_t operator*(int16_t v) { return (v*i) + ((v*f)>>F); } + int operator*(int v) { return (v*i) + ((v*f)>>F); } +}; + +template static uint32_t operator*(uint32_t v, q & q) { return q * v; } +template static uint16_t operator*(uint16_t v, q & q) { return q * v; } +template static int32_t operator*(int32_t v, q & q) { return q * v; } +template static int16_t operator*(int16_t v, q & q) { return q * v; } +template static int operator*(int v, q & q) { return q * v; } + +typedef q q44; +typedef q q62; +typedef q q88; +typedef q q124; + #endif diff --git a/noise.cpp b/noise.cpp index 4b41bf35..341fc21a 100644 --- a/noise.cpp +++ b/noise.cpp @@ -350,6 +350,20 @@ uint8_t inoise8(uint16_t x) return scale8((70+(ans)),234)<<1; } +// struct q44 { +// uint8_t i:4; +// uint8_t f:4; +// q44(uint8_t _i, uint8_t _f) {i=_i; f=_f; } +// }; + +// uint32_t mul44(uint32_t v, q44 mulby44) { +// return (v *mulby44.i) + ((v * mulby44.f) >> 4); +// } +// +// uint16_t mul44_16(uint16_t v, q44 mulby44) { +// return (v *mulby44.i) + ((v * mulby44.f) >> 4); +// } + void fill_raw_noise8(uint8_t *pData, uint8_t num_points, uint8_t octaves, uint16_t x, int scale, uint16_t time) { uint32_t _xx = x; uint32_t scx = scale; @@ -379,43 +393,122 @@ void fill_raw_noise16into8(uint8_t *pData, uint8_t num_points, uint8_t octaves, } } +void fill_raw_2dnoise8(uint8_t *pData, int width, int height, uint8_t octaves, q44 freq44, fract8 amplitude, uint16_t x, int scalex, uint16_t y, int scaley, uint16_t time) { + if(octaves > 1) { + fill_raw_2dnoise8(pData, width, height, octaves-1, freq44, amplitude, x, freq44 * scalex, y, freq44 * scaley, time); + } else { + // amplitude is always 255 on the lowest level + amplitude=255; + } + + fract8 invamp = 255-amplitude; + for(int i = 0; i < height; i++, y+=scaley) { + uint8_t *pRow = pData + (i*width); + for(int j = 0; j < width; j++, x+=scalex) { + pRow[j] = scale8(pRow[j],invamp) + scale8((inoise8(x,y,time)) , amplitude); + } + } +} + void fill_raw_2dnoise8(uint8_t *pData, int width, int height, uint8_t octaves, uint16_t x, int scalex, uint16_t y, int scaley, uint16_t time) { - uint32_t _xx = x; - uint32_t _yy = y; - uint32_t scx = scalex; - uint32_t scy = scaley; - for(int o = 0; o < octaves; o++) { - for(int i = 0,yy=_yy; i < height; i++,yy+=scy) { - uint8_t *pRow = pData + (i * width); - for(int j = 0,xx=_xx; j < width; j++,xx+=scx) { - pRow[j] = qadd8(pRow[j],inoise8(xx,yy,time)>>o); + fill_raw_2dnoise8(pData, width, height, octaves, q44(2,0), 171, x, scalex, y, scaley, time); + // uint32_t _xx = x; + // uint32_t _yy = y; + // uint32_t scx = scalex; + // uint32_t scy = scaley; + // for(int o = 0; o < octaves; o++) { + // for(int i = 0,yy=_yy; i < height; i++,yy+=scy) { + // uint8_t *pRow = pData + (i * width); + // for(int j = 0,xx=_xx; j < width; j++,xx+=scx) { + // pRow[j] = qadd8(pRow[j],inoise8(xx,yy,time)>>o); + // } + // } + // _xx <<= 1; + // scx <<= 1; + // _yy <<= 1; + // scy <<= 1; + // } +} + +void fill_raw_2dnoise16(uint16_t *pData, int width, int height, uint8_t octaves, q88 freq88, fract16 amplitude, int skip, uint32_t x, int scalex, uint32_t y, int scaley, uint32_t time) { + if(octaves > 1) { + fill_raw_2dnoise16(pData, width, height, octaves-1, freq88, amplitude, skip+1, x, scalex *freq88, y, scaley * freq88, time); + } else { + // amplitude is always 255 on the lowest level + amplitude=65535; + } + + scalex *= skip; + scaley *= skip; + + fract16 invamp = 65535-amplitude; + for(int i = 0; i < height; i+=skip, y+=scaley) { + uint16_t *pRow = pData + (i*width); + for(int j = 0; j < width; j+=skip, x+=scalex) { + uint16_t nb = scale16((inoise16(x,y,time)) , amplitude); + if(skip==1) { + pRow[j] = scale16(pRow[j],invamp) + nb; + } else { + for(int ii = i; ii<(i+skip) && ii>o; - accum += (pRow[j]<<8); - if(accum > 65535) { accum = 65535; } - pRow[j] = accum>>8; +void fill_raw_2dnoise16into8(uint8_t *pData, int width, int height, uint8_t octaves, q44 freq44, fract8 amplitude, int skip, uint32_t x, int scalex, uint32_t y, int scaley, uint32_t time) { + if(octaves > 1) { + fill_raw_2dnoise16into8(pData, width, height, octaves-1, freq44, amplitude, skip+1, x, scalex *freq44, y, scaley * freq44, time); + } else { + // amplitude is always 255 on the lowest level + amplitude=255; + } + + scalex *= skip; + scaley *= skip; + + fract8 invamp = 255-amplitude; + for(int i = 0; i < height; i+=skip, y+=scaley) { + uint8_t *pRow = pData + (i*width); + for(int j = 0; j < width; j+=skip, x+=scalex) { + uint8_t nb = scale8((inoise16(x,y,time)>>8) , amplitude); + if(skip==1) { + pRow[j] = scale8(pRow[j],invamp) + nb; + } else { + for(int ii = i; ii<(i+skip) && ii>o; + // accum += (pRow[j]<<8); + // if(accum > 65535) { accum = 65535; } + // pRow[j] = accum>>8; + // } + // } + // x <<= 1; + // scalex <<= 1; + // y <<= 1; + // scaley <<= 1; + // } +} + void fill_noise8(CRGB *leds, int num_leds, uint8_t octaves, uint16_t x, int scale, uint8_t hue_octaves, uint16_t hue_x, int hue_scale, @@ -472,7 +565,7 @@ void fill_2dnoise8(CRGB *leds, int width, int height, bool serpentine, CRGB led(CHSV(H[h1-i][w1-j],255,V[i][j])); int pos = j; - if(serpentine) { + if(serpentine && (i & 0x1)) { pos = w1-j; } @@ -494,7 +587,7 @@ void fill_2dnoise16(CRGB *leds, int width, int height, bool serpentine, memset(V,0,height*width); memset(H,0,height*width); - fill_raw_2dnoise16into8((uint8_t*)V,width,height,octaves,x,xscale,y,yscale,time); + fill_raw_2dnoise16into8((uint8_t*)V,width,height,octaves,q44(0.5),171,1,x,xscale,y,yscale,time); fill_raw_2dnoise8((uint8_t*)H,width,height,hue_octaves,hue_x,hue_xscale,hue_y,hue_yscale,hue_time); int w1 = width-1; @@ -505,7 +598,7 @@ void fill_2dnoise16(CRGB *leds, int width, int height, bool serpentine, CRGB led(CHSV(H[h1-i][w1-j],255,V[i][j])); int pos = j; - if(serpentine) { + if(serpentine && (i &0x1)) { pos = w1-j; } diff --git a/noise.h b/noise.h index 84513f9d..d93e2b76 100644 --- a/noise.h +++ b/noise.h @@ -24,6 +24,8 @@ void fill_raw_noise16into8(uint8_t *pData, uint8_t num_points, uint8_t octaves, void fill_raw_2dnoise8(uint8_t *pData, int width, int height, uint8_t octaves, uint16_t x, int scalex, uint16_t y, int scaley, uint16_t time); void fill_raw_2dnoise16into8(uint8_t *pData, int width, int height, uint8_t octaves, uint32_t x, int scalex, uint32_t y, int scaley, uint32_t time); +void fill_raw_2dnoise16(uint16_t *pData, int width, int height, uint8_t octaves, q88 freq88, fract16 amplitude, int skip, uint32_t x, int scalex, uint32_t y, int scaley, uint32_t time); +void fill_raw_2dnoise16into8(uint8_t *pData, int width, int height, uint8_t octaves, q44 freq44, fract8 amplitude, int skip, uint32_t x, int scalex, uint32_t y, int scaley, uint32_t time); // fill functions to fill leds with values based on noise functions. These functions use the fill_raw_* functions as appropriate. void fill_noise8(CRGB *leds, int num_leds, -- cgit v1.2.3 From b08060b68d575d4e8fe31a9afbb1bf212d2e8f42 Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Mon, 2 Jun 2014 22:33:20 -0400 Subject: Fixing build issue w/NoisePlayground on due --- examples/NoisePlayground/NoisePlayground.ino | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/NoisePlayground/NoisePlayground.ino b/examples/NoisePlayground/NoisePlayground.ino index 08277093..2e39fafb 100644 --- a/examples/NoisePlayground/NoisePlayground.ino +++ b/examples/NoisePlayground/NoisePlayground.ino @@ -11,7 +11,7 @@ CRGB leds[kMatrixWidth * kMatrixHeight]; // x,y, & time values -uint32_t x,y,time,hue_time; +uint32_t x,y,v_time,hue_time; // Play with the values of the variables below and see what kinds of effects they // have! More octaves will make things slower. @@ -38,7 +38,7 @@ int y_speed=1; void loop() { // fill the led array 2/16-bit noise values fill_2dnoise16(LEDS.leds(), kMatrixWidth, kMatrixHeight, kMatrixSerpentineLayout, - octaves,x,xscale,y,yscale,time, + octaves,x,xscale,y,yscale,v_time, hue_octaves,x,hue_scale,y,hue_scale,hue_time, false); LEDS.show(); LEDS.countFPS(); @@ -46,7 +46,7 @@ void loop() { // adjust the intra-frame time values x += x_speed; y += y_speed; - time += time_speed; + v_time += time_speed; hue_time += hue_speed; } @@ -65,7 +65,7 @@ void setup() { x = (uint32_t)((uint32_t)random16() << 16) | random16(); y = (uint32_t)((uint32_t)random16() << 16) | random16(); - time = (uint32_t)((uint32_t)random16() << 16) | random16(); + v_time = (uint32_t)((uint32_t)random16() << 16) | random16(); hue_time = (uint32_t)((uint32_t)random16() << 16) | random16(); } -- cgit v1.2.3 From 81fce972f8ff0ba9fdeaf35f5fc9441a3cb1d18b Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Mon, 2 Jun 2014 22:34:17 -0400 Subject: Make the default frequency 2.0 --- noise.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/noise.cpp b/noise.cpp index 7aa569c9..25c7f467 100644 --- a/noise.cpp +++ b/noise.cpp @@ -491,7 +491,7 @@ void fill_raw_2dnoise16into8(uint8_t *pData, int width, int height, uint8_t octa } void fill_raw_2dnoise16into8(uint8_t *pData, int width, int height, uint8_t octaves, uint32_t x, int scalex, uint32_t y, int scaley, uint32_t time) { - fill_raw_2dnoise16into8(pData, width, height, octaves, q44(0,8), 171, 1, x, scalex, y, scaley, time); + fill_raw_2dnoise16into8(pData, width, height, octaves, q44(2.0), 171, 1, x, scalex, y, scaley, time); // for(int o = 0; o < octaves; o++) { // for(int i = 0,yy=y; i < height; i++,yy+=scaley) { // uint8_t *pRow = pData + (i * width); @@ -587,7 +587,7 @@ void fill_2dnoise16(CRGB *leds, int width, int height, bool serpentine, memset(V,0,height*width); memset(H,0,height*width); - fill_raw_2dnoise16into8((uint8_t*)V,width,height,octaves,q44(0.5),171,1,x,xscale,y,yscale,time); + fill_raw_2dnoise16into8((uint8_t*)V,width,height,octaves,q44(2.0),171,1,x,xscale,y,yscale,time); fill_raw_2dnoise8((uint8_t*)H,width,height,hue_octaves,hue_x,hue_xscale,hue_y,hue_yscale,hue_time); int w1 = width-1; -- cgit v1.2.3 From cbb495cbc1df8d6176e40562d731c4190243919d Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Mon, 2 Jun 2014 22:43:29 -0400 Subject: tweaking q44 values --- noise.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/noise.cpp b/noise.cpp index 25c7f467..f91d5a3c 100644 --- a/noise.cpp +++ b/noise.cpp @@ -491,7 +491,7 @@ void fill_raw_2dnoise16into8(uint8_t *pData, int width, int height, uint8_t octa } void fill_raw_2dnoise16into8(uint8_t *pData, int width, int height, uint8_t octaves, uint32_t x, int scalex, uint32_t y, int scaley, uint32_t time) { - fill_raw_2dnoise16into8(pData, width, height, octaves, q44(2.0), 171, 1, x, scalex, y, scaley, time); + fill_raw_2dnoise16into8(pData, width, height, octaves, q44(2,0), 171, 1, x, scalex, y, scaley, time); // for(int o = 0; o < octaves; o++) { // for(int i = 0,yy=y; i < height; i++,yy+=scaley) { // uint8_t *pRow = pData + (i * width); @@ -587,7 +587,7 @@ void fill_2dnoise16(CRGB *leds, int width, int height, bool serpentine, memset(V,0,height*width); memset(H,0,height*width); - fill_raw_2dnoise16into8((uint8_t*)V,width,height,octaves,q44(2.0),171,1,x,xscale,y,yscale,time); + fill_raw_2dnoise16into8((uint8_t*)V,width,height,octaves,q44(2,0),171,1,x,xscale,y,yscale,time); fill_raw_2dnoise8((uint8_t*)H,width,height,hue_octaves,hue_x,hue_xscale,hue_y,hue_yscale,hue_time); int w1 = width-1; -- cgit v1.2.3 From 552411bc6df525f291fa3cf2d823d980a5992c25 Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Tue, 3 Jun 2014 10:23:00 -0700 Subject: Fix 8bit compile issue --- lib8tion.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib8tion.h b/lib8tion.h index 86d3012a..457aae88 100644 --- a/lib8tion.h +++ b/lib8tion.h @@ -1584,14 +1584,18 @@ public: uint16_t operator*(uint16_t v) { return (v*i) + ((v*f)>>F); } int32_t operator*(int32_t v) { return (v*i) + ((v*f)>>F); } int16_t operator*(int16_t v) { return (v*i) + ((v*f)>>F); } +#ifdef FASTLED_ARM int operator*(int v) { return (v*i) + ((v*f)>>F); } +#endif }; template static uint32_t operator*(uint32_t v, q & q) { return q * v; } template static uint16_t operator*(uint16_t v, q & q) { return q * v; } template static int32_t operator*(int32_t v, q & q) { return q * v; } template static int16_t operator*(int16_t v, q & q) { return q * v; } +#ifdef FASTLED_ARM template static int operator*(int v, q & q) { return q * v; } +#endif typedef q q44; typedef q q62; -- cgit v1.2.3 From 6aeed0155e41bbf1cca15b3430cfd663ab702eb8 Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Tue, 3 Jun 2014 20:03:03 -0700 Subject: Tweaked the scaling values of noise8/16 to better line up with the real range of values (found via doing 4 billion runs over each on my laptop). Also added better gradient functions for 1d and 2d noise (though i'm not happy with the 1d distribution, yet). Finally, added raw versions of the noise functions to give back the unadjusted, unscaled, roughly -0.6,0.6 range of values. --- FastLED.cpp | 4 +++ noise.cpp | 117 +++++++++++++++++++++++++++++++++++++++++++++++------------- noise.h | 16 +++++++-- 3 files changed, 111 insertions(+), 26 deletions(-) diff --git a/FastLED.cpp b/FastLED.cpp index 1e6ecf2f..0645aaea 100644 --- a/FastLED.cpp +++ b/FastLED.cpp @@ -107,6 +107,9 @@ void CFastLED::setDither(uint8_t ditherMode) { } } +extern int noise_min; +extern int noise_max; + void CFastLED::countFPS(int nFrames) { if(Serial) { static uint32_t br = 0; @@ -116,6 +119,7 @@ void CFastLED::countFPS(int nFrames) { if(br == nFrames) { uint32_t now = millis() - lastframe; uint32_t fps = (br * 1000) / now; + /*Serial.print('('); Serial.print(noise_min); Serial.print(','); Serial.print(noise_max); Serial.print(") "); */ Serial.print(now); Serial.print("ms for "); Serial.print(br); Serial.print(" frames, aka "); Serial.print(fps); Serial.println(" fps. "); br = 0; diff --git a/noise.cpp b/noise.cpp index f91d5a3c..d0ae45fd 100644 --- a/noise.cpp +++ b/noise.cpp @@ -1,7 +1,7 @@ #include -#include #ifdef FASTLED_AVR +#include #define USE_PROGMEM #endif @@ -13,7 +13,7 @@ #define P(x) p[(x)] #endif -PROGMEM static uint8_t p[] = { 151,160,137,91,90,15, +FL_PROGMEM static uint8_t p[] = { 151,160,137,91,90,15, 131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,99,37,240,21,10,23, 190, 6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,11,32,57,177,33, 88,237,149,56,87,174,20,125,136,171,168, 68,175,74,165,71,134,139,48,27,166, @@ -39,7 +39,6 @@ PROGMEM static uint8_t p[] = { 151,160,137,91,90,15, #define FADE(x) scale16(x,x) #define LERP(a,b,u) lerp15by16(a,b,u) #endif - static int16_t __attribute__((always_inline)) grad16(uint8_t hash, int16_t x, int16_t y, int16_t z) { #if 0 switch(hash & 0xF) { @@ -71,6 +70,28 @@ static int16_t __attribute__((always_inline)) grad16(uint8_t hash, int16_t x, i #endif } +static int16_t __attribute__((always_inline)) grad16(uint8_t hash, int16_t x, int16_t y) { + hash = hash & 7; + int16_t u,v; + if(hash < 4) { u = x; v = y; } else { u = y; v = x; } + if(hash&1) { u = -u; } + if(hash&2) { v = -v; } + + return (u+v)>>1; +} + +static int16_t __attribute__((always_inline)) grad16(uint8_t hash, int16_t x) { + hash = hash & 15; + int16_t u,v; + if(hash > 8) { u=x;v=x; } + else if(hash < 4) { u=x;v=1; } + else { u=1;v=x; } + if(hash&1) { u = -u; } + if(hash&2) { v = -v; } + + return (u+v)>>1; +} + static int8_t __attribute__((always_inline)) grad8(uint8_t hash, int8_t x, int8_t y, int8_t z) { #if 0 switch(hash & 0xF) { @@ -102,6 +123,29 @@ static int8_t __attribute__((always_inline)) grad8(uint8_t hash, int8_t x, int8 #endif } +static int8_t __attribute__((always_inline)) grad8(uint8_t hash, int8_t x, int8_t y) { + hash = hash & 7; + int8_t u,v; + if(hash < 4) { u = x; v = y; } else { u = y; v = x; } + if(hash&1) { u = -u; } + if(hash&2) { v = -v; } + + return (u+v)>>1; +} + +static int8_t __attribute__((always_inline)) grad8(uint8_t hash, int8_t x) { + hash = hash & 15; + int8_t u,v; + if(hash > 8) { u=x;v=x; } + else if(hash < 4) { u=x;v=1; } + else { u=1;v=x; } + if(hash&1) { u = -u; } + if(hash&2) { v = -v; } + + return (u+v)>>1; +} + + #ifdef FADE_12 uint16_t logfade12(uint16_t val) { return scale16(val,val)>>4; @@ -144,7 +188,7 @@ static int8_t __attribute__((always_inline)) lerp7by8( int8_t a, int8_t b, fract return result; } -uint16_t inoise16(uint32_t x, uint32_t y, uint32_t z) +int16_t inoise16_raw(uint32_t x, uint32_t y, uint32_t z) { // Find the unit cube containing the point uint8_t X = x>>16; @@ -185,11 +229,16 @@ uint16_t inoise16(uint32_t x, uint32_t y, uint32_t z) int16_t ans = LERP(Y1,Y2,w); - return scale16by8(ans+15900,250)<<1; + return ans; +} + +uint16_t inoise16(uint32_t x, uint32_t y, uint32_t z) { + // return scale16by8(ans+15900,250)<<1; // return N+ans; + return scale16by8(inoise16_raw(x,y,z)+19052,220)<<1; } -uint16_t inoise16(uint32_t x, uint32_t y) +int16_t inoise16_raw(uint32_t x, uint32_t y) { // Find the unit cube containing the point uint8_t X = x>>16; @@ -214,16 +263,19 @@ uint16_t inoise16(uint32_t x, uint32_t y) u = FADE(u); v = FADE(v); - int16_t X1 = LERP(grad16(P(AA), xx, yy, 0), grad16(P(BA), xx - N, yy, 0), u); - int16_t X2 = LERP(grad16(P(AB), xx, yy-N, 0), grad16(P(BB), xx - N, yy - N, 0), u); + int16_t X1 = LERP(grad16(P(AA), xx, yy), grad16(P(BA), xx - N, yy), u); + int16_t X2 = LERP(grad16(P(AB), xx, yy-N), grad16(P(BB), xx - N, yy - N), u); int16_t ans = LERP(X1,X2,v); - return scale16by8(ans+15900,250)<<1; - // return N+ans; + return ans; } -uint16_t inoise16(uint32_t x) +uint16_t inoise16(uint32_t x, uint32_t y) { + return scale16by8(inoise16_raw(x,y)+17308,242)<<1; +} + +int16_t inoise16_raw(uint32_t x) { // Find the unit cube containing the point uint8_t X = x>>16; @@ -243,13 +295,16 @@ uint16_t inoise16(uint32_t x) u = FADE(u); - int16_t ans = LERP(grad16(P(AA), xx, 0, 0), grad16(P(BA), xx - N, 0, 0), u); + int16_t ans = LERP(grad16(P(AA), xx), grad16(P(BA), xx - N), u); - return scale16by8(ans+15900,250)<<1; - // return N+ans; + return ans; } -uint8_t inoise8(uint16_t x, uint16_t y, uint16_t z) +uint16_t inoise16(uint32_t x) { + return (inoise16_raw(x) + 17308) << 1; +} + +int8_t inoise8_raw(uint16_t x, uint16_t y, uint16_t z) { // Find the unit cube containing the point uint8_t X = x>>8; @@ -288,10 +343,14 @@ uint8_t inoise8(uint16_t x, uint16_t y, uint16_t z) int8_t ans = lerp7by8(Y1,Y2,w); - return scale8((70+(ans)),234)<<1; + return ans; +} + +uint8_t inoise8(uint16_t x, uint16_t y, uint16_t z) { + return scale8(76+(inoise8_raw(x,y,z)),215)<<1; } -uint8_t inoise8(uint16_t x, uint16_t y) +int8_t inoise8_raw(uint16_t x, uint16_t y) { // Find the unit cube containing the point uint8_t X = x>>8; @@ -317,15 +376,20 @@ uint8_t inoise8(uint16_t x, uint16_t y) // u = FADE(u); v = FADE(v); w = FADE(w); u = scale8_LEAVING_R1_DIRTY(u,u); v = scale8(v,v); - int8_t X1 = lerp7by8(grad8(P(AA), xx, yy, 0), grad8(P(BA), xx - N, yy, 0), u); - int8_t X2 = lerp7by8(grad8(P(AB), xx, yy-N, 0), grad8(P(BB), xx - N, yy - N, 0), u); + int8_t X1 = lerp7by8(grad8(P(AA), xx, yy), grad8(P(BA), xx - N, yy), u); + int8_t X2 = lerp7by8(grad8(P(AB), xx, yy-N), grad8(P(BB), xx - N, yy - N), u); int8_t ans = lerp7by8(X1,X2,v); - return scale8((70+(ans)),234)<<1; + return ans; + // return scale8((70+(ans)),234)<<1; +} + +uint8_t inoise8(uint16_t x, uint16_t y) { + return scale8(69+inoise8_raw(x,y),237)<<1; } -uint8_t inoise8(uint16_t x) +int8_t inoise8_raw(uint16_t x) { // Find the unit cube containing the point uint8_t X = x>>8; @@ -345,9 +409,14 @@ uint8_t inoise8(uint16_t x) u = scale8(u,u); - int8_t ans = lerp7by8(grad8(P(AA), xx, 0, 0), grad8(P(BA), xx - N, 0, 0), u); + int8_t ans = lerp7by8(grad8(P(AA), xx), grad8(P(BA), xx - N), u); + + return ans; + // return scale8((70+(ans)),234)<<1; +} - return scale8((70+(ans)),234)<<1; +uint8_t inoise8(uint16_t x) { + return scale8(69+inoise8_raw(x), 255)<<1; } // struct q44 { @@ -432,7 +501,7 @@ void fill_raw_2dnoise8(uint8_t *pData, int width, int height, uint8_t octaves, u void fill_raw_2dnoise16(uint16_t *pData, int width, int height, uint8_t octaves, q88 freq88, fract16 amplitude, int skip, uint32_t x, int scalex, uint32_t y, int scaley, uint32_t time) { if(octaves > 1) { - fill_raw_2dnoise16(pData, width, height, octaves-1, freq88, amplitude, skip+1, x, scalex *freq88, y, scaley * freq88, time); + fill_raw_2dnoise16(pData, width, height, octaves-1, freq88, amplitude, skip+1, x * freq88, scalex *freq88, y *freq88, scaley * freq88, time); } else { // amplitude is always 255 on the lowest level amplitude=65535; diff --git a/noise.h b/noise.h index d93e2b76..79567148 100644 --- a/noise.h +++ b/noise.h @@ -4,19 +4,31 @@ // 16 bit, fixed point implementation of perlin's Simplex Noise. Coordinates are // 16.16 fixed point values, 32 bit integers with integral coordinates in the high 16 // bits and fractional in the low 16 bits, and the function takes 1d, 2d, and 3d coordinate -// values. +// values. These functions are scaled to return 0-65535 extern uint16_t inoise16(uint32_t x, uint32_t y, uint32_t z); extern uint16_t inoise16(uint32_t x, uint32_t y); extern uint16_t inoise16(uint32_t x); +// 16 bit raw versions of the noise functions. These values are not scaled/altered and have +// output values roughly in the range (-18k,18k) +extern int16_t inoise16_raw(uint32_t x, uint32_t y, uint32_t z); +extern int16_t inoise16_raw(uint32_t x, uint32_t y); +extern int16_t inoise16_raw(uint32_t x); + // 8 bit, fixed point implementation of perlin's Simplex Noise. Coordinates are // 8.8 fixed point values, 16 bit integers with integral coordinates in the high 8 // bits and fractional in the low 8 bits, and the function takes 1d, 2d, and 3d coordinate -// values. +// values. These functions are scaled to return 0-255 extern uint8_t inoise8(uint16_t x, uint16_t y, uint16_t z); extern uint8_t inoise8(uint16_t x, uint16_t y); extern uint8_t inoise8(uint16_t x); +// 8 bit raw versions of the noise functions. These values are not scaled/altered and have +// output values roughly in the range (-70,70) +extern int8_t inoise8_raw(uint16_t x, uint16_t y, uint16_t z); +extern int8_t inoise8_raw(uint16_t x, uint16_t y); +extern int8_t inoise8_raw(uint16_t x); + // Raw noise fill functions - fill into a 1d or 2d array of 8-bit values using either 8-bit noise or 16-bit noise // functions. void fill_raw_noise8(uint8_t *pData, uint8_t num_points, uint8_t octaves, uint16_t x, int scale, uint16_t time); -- cgit v1.2.3 From 87bb883680c09bff44bcf24fb3c33b430ac5ee89 Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Tue, 3 Jun 2014 20:45:48 -0700 Subject: fixing on avr noise generation, something was unhappy there... --- examples/NoisePlayground/NoisePlayground.ino | 4 ++-- noise.cpp | 7 ++++--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/examples/NoisePlayground/NoisePlayground.ino b/examples/NoisePlayground/NoisePlayground.ino index 2e39fafb..4327adb9 100644 --- a/examples/NoisePlayground/NoisePlayground.ino +++ b/examples/NoisePlayground/NoisePlayground.ino @@ -56,11 +56,11 @@ void setup() { random16_set_seed(18934); random16_add_entropy(analogRead(3)); - Serial.begin(38400); + Serial.begin(57600); Serial.println("resetting!"); delay(3000); - LEDS.addLeds(leds,NUM_LEDS); + LEDS.addLeds(leds,NUM_LEDS); LEDS.setBrightness(96); x = (uint32_t)((uint32_t)random16() << 16) | random16(); diff --git a/noise.cpp b/noise.cpp index d0ae45fd..066873c3 100644 --- a/noise.cpp +++ b/noise.cpp @@ -233,9 +233,8 @@ int16_t inoise16_raw(uint32_t x, uint32_t y, uint32_t z) } uint16_t inoise16(uint32_t x, uint32_t y, uint32_t z) { - // return scale16by8(ans+15900,250)<<1; - // return N+ans; - return scale16by8(inoise16_raw(x,y,z)+19052,220)<<1; + return ((inoise16_raw(x,y,z)+19052)*220)>>7; + // return scale16by8(inoise16_raw(x,y,z)+19052,220)<<1; } int16_t inoise16_raw(uint32_t x, uint32_t y) @@ -272,6 +271,7 @@ int16_t inoise16_raw(uint32_t x, uint32_t y) } uint16_t inoise16(uint32_t x, uint32_t y) { + return ((inoise16_raw(x,y)+17308)*242)>>7; return scale16by8(inoise16_raw(x,y)+17308,242)<<1; } @@ -657,6 +657,7 @@ void fill_2dnoise16(CRGB *leds, int width, int height, bool serpentine, memset(H,0,height*width); fill_raw_2dnoise16into8((uint8_t*)V,width,height,octaves,q44(2,0),171,1,x,xscale,y,yscale,time); + // fill_raw_2dnoise8((uint8_t*)V,width,height,hue_octaves,x,xscale,y,yscale,time); fill_raw_2dnoise8((uint8_t*)H,width,height,hue_octaves,hue_x,hue_xscale,hue_y,hue_yscale,hue_time); int w1 = width-1; -- cgit v1.2.3 From 244b23b70c70b53ae28a57fbdde579e8c2cd1a6f Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Tue, 3 Jun 2014 22:09:31 -0700 Subject: Fixing noise on avr with the new raw noise functions --- FastLED.h | 2 +- examples/NoisePlayground/NoisePlayground.ino | 36 +++++++++++++++++----------- noise.cpp | 33 ++++++++++++++++++------- 3 files changed, 47 insertions(+), 24 deletions(-) diff --git a/FastLED.h b/FastLED.h index c1349fd9..c7557126 100644 --- a/FastLED.h +++ b/FastLED.h @@ -199,7 +199,7 @@ public: // for debugging, will keep track of time between calls to countFPS, and every // nFrames calls, it will print a summary of FPS info out to the serial port. // If the serial port isn't opened, this function does nothing. - void countFPS(int nFrames=100); + void countFPS(int nFrames=25); CLEDController & operator[](int x); diff --git a/examples/NoisePlayground/NoisePlayground.ino b/examples/NoisePlayground/NoisePlayground.ino index 4327adb9..f3cd7f9e 100644 --- a/examples/NoisePlayground/NoisePlayground.ino +++ b/examples/NoisePlayground/NoisePlayground.ino @@ -1,11 +1,11 @@ #include -#define kMatrixWidth 16 -#define kMatrixHeight 16 +#define kMatrixWidth 8 +#define kMatrixHeight 5 #define NUM_LEDS (kMatrixWidth * kMatrixHeight) // Param for different pixel layouts -#define kMatrixSerpentineLayout true +#define kMatrixSerpentineLayout false // led array CRGB leds[kMatrixWidth * kMatrixHeight]; @@ -17,29 +17,33 @@ uint32_t x,y,v_time,hue_time; // have! More octaves will make things slower. // how many octaves to use for the brightness and hue functions -uint8_t octaves=2; -uint8_t hue_octaves=2; +uint8_t octaves=3; +uint8_t hue_octaves=3; // the 'distance' between points on the x and y axis -int xscale=301; -int yscale=301; +int xscale=3311; +int yscale=3311; // the 'distance' between x/y points for the hue noise -int hue_scale=11; +int hue_scale=1; // how fast we move through time & hue noise -int time_speed=101; -int hue_speed=3; +int time_speed=5101; +int hue_speed=1; // adjust these values to move along the x or y axis between frames int x_speed=0; -int y_speed=1; +int y_speed=0; void loop() { // fill the led array 2/16-bit noise values fill_2dnoise16(LEDS.leds(), kMatrixWidth, kMatrixHeight, kMatrixSerpentineLayout, octaves,x,xscale,y,yscale,v_time, hue_octaves,x,hue_scale,y,hue_scale,hue_time, false); + static byte beacon = 0; + beacon++; + leds[0] = CHSV( beacon, 255, 255); + LEDS.show(); LEDS.countFPS(); @@ -48,6 +52,7 @@ void loop() { y += y_speed; v_time += time_speed; hue_time += hue_speed; + // delay(50); } @@ -63,9 +68,12 @@ void setup() { LEDS.addLeds(leds,NUM_LEDS); LEDS.setBrightness(96); - x = (uint32_t)((uint32_t)random16() << 16) | random16(); - y = (uint32_t)((uint32_t)random16() << 16) | random16(); - v_time = (uint32_t)((uint32_t)random16() << 16) | random16(); + // x = (uint32_t)((uint32_t)random16() << 16) | random16(); + // y = (uint32_t)((uint32_t)random16() << 16) | random16(); + // v_time = (uint32_t)((uint32_t)random16() << 16) | random16(); + x = 1; + y = 1; + v_time = 1; hue_time = (uint32_t)((uint32_t)random16() << 16) | random16(); } diff --git a/noise.cpp b/noise.cpp index 066873c3..cacbf667 100644 --- a/noise.cpp +++ b/noise.cpp @@ -191,9 +191,9 @@ static int8_t __attribute__((always_inline)) lerp7by8( int8_t a, int8_t b, fract int16_t inoise16_raw(uint32_t x, uint32_t y, uint32_t z) { // Find the unit cube containing the point - uint8_t X = x>>16; - uint8_t Y = y>>16; - uint8_t Z = z>>16; + uint8_t X = (x>>16)&0xFF; + uint8_t Y = (y>>16)&0xFF; + uint8_t Z = (z>>16)&0xFF; // Hash cube corner coordinates uint8_t A = P(X)+Y; @@ -233,7 +233,12 @@ int16_t inoise16_raw(uint32_t x, uint32_t y, uint32_t z) } uint16_t inoise16(uint32_t x, uint32_t y, uint32_t z) { - return ((inoise16_raw(x,y,z)+19052)*220)>>7; + int32_t ans = inoise16_raw(x,y,z); + ans = ans + 19052L; + uint32_t pan = ans; + return (pan*220L)>>7; + // // return scale16by8(pan,220)<<1; + // return ((inoise16_raw(x,y,z)+19052)*220)>>7; // return scale16by8(inoise16_raw(x,y,z)+19052,220)<<1; } @@ -271,8 +276,12 @@ int16_t inoise16_raw(uint32_t x, uint32_t y) } uint16_t inoise16(uint32_t x, uint32_t y) { - return ((inoise16_raw(x,y)+17308)*242)>>7; - return scale16by8(inoise16_raw(x,y)+17308,242)<<1; + int32_t ans = inoise16_raw(x,y); + ans = ans + 17308L; + uint32_t pan = ans; + return (pan*242L)>>7; + // return (uint32_t)(((int32_t)inoise16_raw(x,y)+(uint32_t)17308)*242)>>7; + // return scale16by8(inoise16_raw(x,y)+17308,242)<<1; } int16_t inoise16_raw(uint32_t x) @@ -301,7 +310,7 @@ int16_t inoise16_raw(uint32_t x) } uint16_t inoise16(uint32_t x) { - return (inoise16_raw(x) + 17308) << 1; + return ((uint32_t)((int32_t)inoise16_raw(x) + 17308L)) << 1; } int8_t inoise8_raw(uint16_t x, uint16_t y, uint16_t z) @@ -565,7 +574,12 @@ void fill_raw_2dnoise16into8(uint8_t *pData, int width, int height, uint8_t octa // for(int i = 0,yy=y; i < height; i++,yy+=scaley) { // uint8_t *pRow = pData + (i * width); // for(int j = 0,xx=x; j < width; j++,xx+=scalex) { - // uint32_t accum = (inoise16(xx,yy,time))>>o; + // // uint32_t accum = (65536/2) + abs(inoise16_raw(xx,yy,time))>>o; + // uint32_t accum = inoise16(xx,yy,time)>>o; + // // if(i==0 && j == 0) { + // // Serial.print(accum); Serial.print("/"); Serial.print(inoise16_raw(xx,yy,time)); Serial.print(" "); + // // } + // // accum += (pRow[j]<<8); // if(accum > 65535) { accum = 65535; } // pRow[j] = accum>>8; @@ -656,10 +670,11 @@ void fill_2dnoise16(CRGB *leds, int width, int height, bool serpentine, memset(V,0,height*width); memset(H,0,height*width); - fill_raw_2dnoise16into8((uint8_t*)V,width,height,octaves,q44(2,0),171,1,x,xscale,y,yscale,time); + fill_raw_2dnoise16into8((uint8_t*)V,width,height,octaves,q44(2,0),128,1,x,xscale,y,yscale,time); // fill_raw_2dnoise8((uint8_t*)V,width,height,hue_octaves,x,xscale,y,yscale,time); fill_raw_2dnoise8((uint8_t*)H,width,height,hue_octaves,hue_x,hue_xscale,hue_y,hue_yscale,hue_time); + int w1 = width-1; int h1 = height-1; for(int i = 0; i < height; i++) { -- cgit v1.2.3 From e7edaf91a93cf446f8b1e3358898e052dba1a58e Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Wed, 4 Jun 2014 11:04:42 -0700 Subject: sam timing tweak --- clockless_arm_sam.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clockless_arm_sam.h b/clockless_arm_sam.h index d71e8162..d4c3d36f 100644 --- a/clockless_arm_sam.h +++ b/clockless_arm_sam.h @@ -165,7 +165,7 @@ public: while((VAL - next_mark) > (T3)); } else { // we're a 0, wait until there's less than (T2+T3+slop) clocks left in this bit - while((VAL-next_mark) > (T2+T3+4+TADJUST+TADJUST)); + while((VAL-next_mark) > (T2+T3+6+TADJUST+TADJUST)); } *port=0; b <<= 1; -- cgit v1.2.3 From 7073454b0b881d46f95d747d000032af6eb7a034 Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Wed, 4 Jun 2014 21:27:04 -0700 Subject: Fix a handful of stupid math/loop errors that were causing a lot of smearing/distortion --- noise.cpp | 79 ++++++++++++++++++++++----------------------------------------- 1 file changed, 27 insertions(+), 52 deletions(-) diff --git a/noise.cpp b/noise.cpp index cacbf667..e5bb93a8 100644 --- a/noise.cpp +++ b/noise.cpp @@ -480,37 +480,23 @@ void fill_raw_2dnoise8(uint8_t *pData, int width, int height, uint8_t octaves, q } fract8 invamp = 255-amplitude; + uint16_t xx = x; for(int i = 0; i < height; i++, y+=scaley) { uint8_t *pRow = pData + (i*width); - for(int j = 0; j < width; j++, x+=scalex) { - pRow[j] = scale8(pRow[j],invamp) + scale8((inoise8(x,y,time)) , amplitude); + xx = x; + for(int j = 0; j < width; j++, xx+=scalex) { + pRow[j] = scale8(pRow[j],invamp) + scale8((inoise8(xx,y,time)) , amplitude); } } } void fill_raw_2dnoise8(uint8_t *pData, int width, int height, uint8_t octaves, uint16_t x, int scalex, uint16_t y, int scaley, uint16_t time) { fill_raw_2dnoise8(pData, width, height, octaves, q44(2,0), 171, x, scalex, y, scaley, time); - // uint32_t _xx = x; - // uint32_t _yy = y; - // uint32_t scx = scalex; - // uint32_t scy = scaley; - // for(int o = 0; o < octaves; o++) { - // for(int i = 0,yy=_yy; i < height; i++,yy+=scy) { - // uint8_t *pRow = pData + (i * width); - // for(int j = 0,xx=_xx; j < width; j++,xx+=scx) { - // pRow[j] = qadd8(pRow[j],inoise8(xx,yy,time)>>o); - // } - // } - // _xx <<= 1; - // scx <<= 1; - // _yy <<= 1; - // scy <<= 1; - // } } void fill_raw_2dnoise16(uint16_t *pData, int width, int height, uint8_t octaves, q88 freq88, fract16 amplitude, int skip, uint32_t x, int scalex, uint32_t y, int scaley, uint32_t time) { if(octaves > 1) { - fill_raw_2dnoise16(pData, width, height, octaves-1, freq88, amplitude, skip+1, x * freq88, scalex *freq88, y *freq88, scaley * freq88, time); + fill_raw_2dnoise16(pData, width, height, octaves-1, freq88, amplitude, skip, x * freq88, scalex *freq88, y *freq88, scaley * freq88, time); } else { // amplitude is always 255 on the lowest level amplitude=65535; @@ -518,19 +504,21 @@ void fill_raw_2dnoise16(uint16_t *pData, int width, int height, uint8_t octaves, scalex *= skip; scaley *= skip; - + uint32_t xx = x; fract16 invamp = 65535-amplitude; for(int i = 0; i < height; i+=skip, y+=scaley) { uint16_t *pRow = pData + (i*width); - for(int j = 0; j < width; j+=skip, x+=scalex) { - uint16_t nb = scale16((inoise16(x,y,time)) , amplitude); + for(int j = 0,xx=x; j < width; j+=skip, xx+=scalex) { + uint16_t noise_base = inoise16(xx,y,time); + noise_base = (0x8000 & noise_base) ? noise_base - (32767) : 32767 - noise_base; + noise_base = scale16(noise_base, amplitude); if(skip==1) { - pRow[j] = scale16(pRow[j],invamp) + nb; + pRow[j] = scale16(pRow[j],invamp) + noise_base; } else { for(int ii = i; ii<(i+skip) && ii 1) { - fill_raw_2dnoise16into8(pData, width, height, octaves-1, freq44, amplitude, skip+1, x, scalex *freq44, y, scaley * freq44, time); + fill_raw_2dnoise16into8(pData, width, height, octaves-1, freq44, amplitude, skip, x, scalex *freq44, y, scaley * freq44, time); } else { // amplitude is always 255 on the lowest level amplitude=255; @@ -548,19 +539,22 @@ void fill_raw_2dnoise16into8(uint8_t *pData, int width, int height, uint8_t octa scalex *= skip; scaley *= skip; - + uint32_t xx; fract8 invamp = 255-amplitude; for(int i = 0; i < height; i+=skip, y+=scaley) { uint8_t *pRow = pData + (i*width); - for(int j = 0; j < width; j+=skip, x+=scalex) { - uint8_t nb = scale8((inoise16(x,y,time)>>8) , amplitude); + xx = x; + for(int j = 0; j < width; j+=skip, xx+=scalex) { + uint16_t noise_base = inoise16(xx,y,time); + noise_base = (0x8000 & noise_base) ? noise_base - (32767) : 32767 - noise_base; + noise_base = scale8(noise_base>>7,amplitude); if(skip==1) { - pRow[j] = scale8(pRow[j],invamp) + nb; + pRow[j] = qadd8(scale8(pRow[j],invamp),noise_base); } else { for(int ii = i; ii<(i+skip) && ii>o; - // uint32_t accum = inoise16(xx,yy,time)>>o; - // // if(i==0 && j == 0) { - // // Serial.print(accum); Serial.print("/"); Serial.print(inoise16_raw(xx,yy,time)); Serial.print(" "); - // // } - // - // accum += (pRow[j]<<8); - // if(accum > 65535) { accum = 65535; } - // pRow[j] = accum>>8; - // } - // } - // x <<= 1; - // scalex <<= 1; - // y <<= 1; - // scaley <<= 1; - // } } void fill_noise8(CRGB *leds, int num_leds, @@ -670,7 +644,8 @@ void fill_2dnoise16(CRGB *leds, int width, int height, bool serpentine, memset(V,0,height*width); memset(H,0,height*width); - fill_raw_2dnoise16into8((uint8_t*)V,width,height,octaves,q44(2,0),128,1,x,xscale,y,yscale,time); + fill_raw_2dnoise16into8((uint8_t*)V,width,height,octaves,q44(2,0),171,1,x,xscale,y,yscale,time); + // fill_raw_2dnoise16into8((uint8_t*)V,width,height,octaves,x,xscale,y,yscale,time); // fill_raw_2dnoise8((uint8_t*)V,width,height,hue_octaves,x,xscale,y,yscale,time); fill_raw_2dnoise8((uint8_t*)H,width,height,hue_octaves,hue_x,hue_xscale,hue_y,hue_yscale,hue_time); @@ -680,7 +655,7 @@ void fill_2dnoise16(CRGB *leds, int width, int height, bool serpentine, for(int i = 0; i < height; i++) { int wb = i*width; for(int j = 0; j < width; j++) { - CRGB led(CHSV(H[h1-i][w1-j],255,V[i][j])); + CRGB led(CHSV(H[h1-i][h1-j],255,V[i][j])); int pos = j; if(serpentine && (i & 0x1)) { -- cgit v1.2.3 From ac2210725ac239157933b81d91fcb8dc0c4ecfd1 Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Thu, 5 Jun 2014 10:45:10 -0700 Subject: For the fill_raw functions for all of 8bit, 16bit, and 16bit into 8 bit, shift the centerpoint of the noise function from 127/32767 to 0. For the fill_noise functions this will result in the colors centering on reds instead of blues --- examples/NoisePlayground/NoisePlayground.ino | 41 ++++++++++++---------------- noise.cpp | 29 +++++++++++++++----- 2 files changed, 40 insertions(+), 30 deletions(-) diff --git a/examples/NoisePlayground/NoisePlayground.ino b/examples/NoisePlayground/NoisePlayground.ino index f3cd7f9e..35890146 100644 --- a/examples/NoisePlayground/NoisePlayground.ino +++ b/examples/NoisePlayground/NoisePlayground.ino @@ -1,48 +1,45 @@ #include -#define kMatrixWidth 8 -#define kMatrixHeight 5 +#define kMatrixWidth 16 +#define kMatrixHeight 16 #define NUM_LEDS (kMatrixWidth * kMatrixHeight) // Param for different pixel layouts -#define kMatrixSerpentineLayout false +#define kMatrixSerpentineLayout true // led array CRGB leds[kMatrixWidth * kMatrixHeight]; // x,y, & time values -uint32_t x,y,v_time,hue_time; +uint32_t x,y,v_time,hue_time,hxy; // Play with the values of the variables below and see what kinds of effects they // have! More octaves will make things slower. // how many octaves to use for the brightness and hue functions -uint8_t octaves=3; +uint8_t octaves=1; uint8_t hue_octaves=3; // the 'distance' between points on the x and y axis -int xscale=3311; -int yscale=3311; +int xscale=57771; +int yscale=57771; // the 'distance' between x/y points for the hue noise int hue_scale=1; // how fast we move through time & hue noise -int time_speed=5101; -int hue_speed=1; +int time_speed=1111; +int hue_speed=31; // adjust these values to move along the x or y axis between frames -int x_speed=0; -int y_speed=0; +int x_speed=331; +int y_speed=1111; void loop() { // fill the led array 2/16-bit noise values fill_2dnoise16(LEDS.leds(), kMatrixWidth, kMatrixHeight, kMatrixSerpentineLayout, octaves,x,xscale,y,yscale,v_time, - hue_octaves,x,hue_scale,y,hue_scale,hue_time, false); - static byte beacon = 0; - beacon++; - leds[0] = CHSV( beacon, 255, 255); + hue_octaves,hxy,hue_scale,hxy,hue_scale,hue_time, false); LEDS.show(); LEDS.countFPS(); @@ -58,7 +55,7 @@ void loop() { void setup() { // initialize the x/y and time values - random16_set_seed(18934); + random16_set_seed(8934); random16_add_entropy(analogRead(3)); Serial.begin(57600); @@ -68,12 +65,10 @@ void setup() { LEDS.addLeds(leds,NUM_LEDS); LEDS.setBrightness(96); - // x = (uint32_t)((uint32_t)random16() << 16) | random16(); - // y = (uint32_t)((uint32_t)random16() << 16) | random16(); - // v_time = (uint32_t)((uint32_t)random16() << 16) | random16(); - x = 1; - y = 1; - v_time = 1; - hue_time = (uint32_t)((uint32_t)random16() << 16) | random16(); + hxy = (uint32_t)((uint32_t)random16() << 16) + (uint32_t)random16(); + x = (uint32_t)((uint32_t)random16() << 16) + (uint32_t)random16(); + y = (uint32_t)((uint32_t)random16() << 16) + (uint32_t)random16(); + v_time = (uint32_t)((uint32_t)random16() << 16) + (uint32_t)random16(); + hue_time = (uint32_t)((uint32_t)random16() << 16) + (uint32_t)random16(); } diff --git a/noise.cpp b/noise.cpp index e5bb93a8..3b0dc599 100644 --- a/noise.cpp +++ b/noise.cpp @@ -471,32 +471,47 @@ void fill_raw_noise16into8(uint8_t *pData, uint8_t num_points, uint8_t octaves, } } -void fill_raw_2dnoise8(uint8_t *pData, int width, int height, uint8_t octaves, q44 freq44, fract8 amplitude, uint16_t x, int scalex, uint16_t y, int scaley, uint16_t time) { +void fill_raw_2dnoise8(uint8_t *pData, int width, int height, uint8_t octaves, q44 freq44, fract8 amplitude, int skip, uint16_t x, int scalex, uint16_t y, int scaley, uint16_t time) { if(octaves > 1) { - fill_raw_2dnoise8(pData, width, height, octaves-1, freq44, amplitude, x, freq44 * scalex, y, freq44 * scaley, time); + fill_raw_2dnoise8(pData, width, height, octaves-1, freq44, amplitude, skip+1, x*freq44, freq44 * scalex, y*freq44, freq44 * scaley, time); } else { // amplitude is always 255 on the lowest level amplitude=255; } + scalex *= skip; + scaley *= skip; + fract8 invamp = 255-amplitude; uint16_t xx = x; for(int i = 0; i < height; i++, y+=scaley) { uint8_t *pRow = pData + (i*width); xx = x; for(int j = 0; j < width; j++, xx+=scalex) { - pRow[j] = scale8(pRow[j],invamp) + scale8((inoise8(xx,y,time)) , amplitude); + uint8_t noise_base = inoise8(xx,y,time); + noise_base = (0x80 & noise_base) ? (noise_base - 127) : (127 - noise_base); + noise_base = scale8(noise_base<<1,amplitude); + if(skip == 1) { + pRow[j] = scale8(pRow[j],invamp) + noise_base; + } else { + for(int ii = i; ii<(i+skip) && ii 1) { - fill_raw_2dnoise16(pData, width, height, octaves-1, freq88, amplitude, skip, x * freq88, scalex *freq88, y *freq88, scaley * freq88, time); + fill_raw_2dnoise16(pData, width, height, octaves-1, freq88, amplitude, skip+1, x *freq88 , scalex *freq88, y * freq88, scaley * freq88, time); } else { // amplitude is always 255 on the lowest level amplitude=65535; @@ -511,7 +526,7 @@ void fill_raw_2dnoise16(uint16_t *pData, int width, int height, uint8_t octaves, for(int j = 0,xx=x; j < width; j+=skip, xx+=scalex) { uint16_t noise_base = inoise16(xx,y,time); noise_base = (0x8000 & noise_base) ? noise_base - (32767) : 32767 - noise_base; - noise_base = scale16(noise_base, amplitude); + noise_base = scale16(noise_base<<1, amplitude); if(skip==1) { pRow[j] = scale16(pRow[j],invamp) + noise_base; } else { @@ -531,7 +546,7 @@ int32_t nmax=0; void fill_raw_2dnoise16into8(uint8_t *pData, int width, int height, uint8_t octaves, q44 freq44, fract8 amplitude, int skip, uint32_t x, int scalex, uint32_t y, int scaley, uint32_t time) { if(octaves > 1) { - fill_raw_2dnoise16into8(pData, width, height, octaves-1, freq44, amplitude, skip, x, scalex *freq44, y, scaley * freq44, time); + fill_raw_2dnoise16into8(pData, width, height, octaves-1, freq44, amplitude, skip+1, x*freq44, scalex *freq44, y*freq44, scaley * freq44, time); } else { // amplitude is always 255 on the lowest level amplitude=255; -- cgit v1.2.3 From 4ac475b57b12cbb2f5eb48d376e250caeaac28f0 Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Fri, 6 Jun 2014 23:00:40 -0700 Subject: placeholder/reference code --- noise.h | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/noise.h b/noise.h index 79567148..b71bf0a6 100644 --- a/noise.h +++ b/noise.h @@ -1,6 +1,64 @@ #ifndef __INC_NOISE_H #define __INC_NOISE_H +#if 0 +/// Class for accessing 16 bit noise. Provides methods for setting origin, scale, +/// frequency, alplitude, time, octave blurring +class CFastNoise16 { +public: + CFastNoise16 &setOrigin(uint32_t x, uint32_t y, uint32_t z); + CFastNoise16 &setOrigin(uint32_t x, uint32_t y); + CFastNoise16 &setOrigin(uint32_t x); + + uint32_t getX(); + uint32_t getY(); + uint32_t getZ(); + uint32_t getTime(); + + uint32_t getOrigin(uint32_t & x, uint32_t & y, uint32_t & z); + uint32_t getOrigin(uint32_t & x, uint32_t & y); + uint32_t getOrigin(uint32_t & x); + + CFastNoise16 &advance(int32_t x, int32_t y, int32_t z); + CFastNoise16 &advance(int32_t x, int32_t y; + CFastNoise16 &advance(int32_t x); + + CFastNoise16 &advanceTime(int32_t t); + + CFastNoise16 &setScale(int32_t x_scale, int32_t y_scale, int32_t z_scale); + CFastNoise16 &setScale(int32_t x_scale, int32_t y_scale); + CFastNoise16 &setScale(int32_t x_scale); + + int32_t getScaleX(); + int32_t getScaleY(); + int32_t getScaleZ(); + void getScale(int32_t & x, int32_t & y, int32_t & z); + void getScale(int32_t & x, int32_t & y); + void getScale(int32_t & x); + + CFastNoise16 &setAmplitude(fract16 amplitude); + + CFastNoise16 &setFrequency(q88 frequency); + CFastNoise16 &setTime(uint32_t time); + + CFastNoise16 &setOctaves(int octaves); + + CFastNoise16 &setOctaveBlur(bool blurOctaves); + + void getNoise(uint32_t x, uint32_t y, uint32_t z); + void getNoise(uint32_t x, uint32_t y); + void getNoise(uint32_t x); + + void fillNoise(uint16_t *pData, int size); + void fillNoise(uint16_t *pData, int width, int height); + void fillNoise(uint16_t *pData, int width, int height, int depth); + + void fillNoise(uint8_t *pData, int size); + void fillNoise(uint8_t *pData, int width, int height); + void fillNoise(uint8_t *pData, int width, int height, int depth); +}; +#endif + // 16 bit, fixed point implementation of perlin's Simplex Noise. Coordinates are // 16.16 fixed point values, 32 bit integers with integral coordinates in the high 16 // bits and fractional in the low 16 bits, and the function takes 1d, 2d, and 3d coordinate -- cgit v1.2.3 From 0d2be502357e49730523021980f4124d5c4e6c41 Mon Sep 17 00:00:00 2001 From: Mark Kriegsman Date: Tue, 10 Jun 2014 09:41:33 -0400 Subject: Added FastLED.count() which returns the number of registered controllers (strips). All of these iteration functions currently have a linked-list walk in them, so access to the Nth item takes linear time over N. As long as this is kept out of the innermost loops, this is OK. --- FastLED.cpp | 10 ++++++++++ FastLED.h | 10 +++++++++- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/FastLED.cpp b/FastLED.cpp index 0645aaea..ab182d06 100644 --- a/FastLED.cpp +++ b/FastLED.cpp @@ -39,6 +39,16 @@ void CFastLED::show(uint8_t scale) { } } +int CFastLED::count() { + int x = 0; + CLEDController *pCur = CLEDController::head(); + while( pCur) { + x++; + pCur = pCur->next(); + } + return x; +} + CLEDController & CFastLED::operator[](int x) { CLEDController *pCur = CLEDController::head(); while(x-- && pCur) { diff --git a/FastLED.h b/FastLED.h index c7557126..a305762b 100644 --- a/FastLED.h +++ b/FastLED.h @@ -201,10 +201,18 @@ public: // If the serial port isn't opened, this function does nothing. void countFPS(int nFrames=25); + // returns the number of controllers (strips) that have been added with addLeds + int count(); + + // returns the Nth controller CLEDController & operator[](int x); + // Convenience functions for single-strip setups: + + // returns the number of LEDs in the first strip int size() { return (*this)[0].size(); } - + + // returns pointer to the CRGB buffer for the first strip CRGB *leds() { return (*this)[0].leds(); } }; -- cgit v1.2.3 From 92f740c23dd15f1040fc9cca502fbe9497610c58 Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Sun, 15 Jun 2014 04:04:28 -0700 Subject: Add define for clock doubled clock rates --- led_sysdefs.h | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/led_sysdefs.h b/led_sysdefs.h index 47ee5076..f9f4578b 100644 --- a/led_sysdefs.h +++ b/led_sysdefs.h @@ -1,17 +1,24 @@ #ifndef __INC_LED_SYSDEFS_H #define __INC_LED_SYSDEFS_H -#if defined(__MK20DX128__) || defined(__MK20DX256__) +#if defined(__MK20DX128__) || defined(__MK20DX256__) #define FASTLED_TEENSY3 #define FASTLED_ARM -#elif defined(__SAM3X8E__) +#if (F_CPU == 96000000) +#define CLK_DBL 1 +#endif +#elif defined(__SAM3X8E__) #define FASTLED_ARM #else #define FASTLED_AVR #endif -#if defined(FASTLED_AVR) || defined(FASTLED_TEENSY3) -#include +#ifndef CLK_DBL +#define CLK_DBL 0 +#endif + +#if defined(FASTLED_AVR) || defined(FASTLED_TEENSY3) +#include #include // for cli/se definitions // Define the rgister types @@ -39,4 +46,4 @@ typedef volatile uint8_t RwReg; /**< Read-Write 8-bit register (volatile u # define INLINE_SCALE(B, SCALE) B = scale8_video(B, SCALE) #endif -#endif \ No newline at end of file +#endif -- cgit v1.2.3 From 36bc6b94e6e09cd5fdb653e1b0b9a12d22f6e92a Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Sun, 15 Jun 2014 04:05:21 -0700 Subject: Adding DATA_RATE_ defs for clock doubled environments. Also, teensy 3.1 SPI on pins 7/14 still uses SPI0, not SPI1. --- fastspi.h | 17 +++++++++++------ fastspi_arm_k20.h | 27 +++++++++++++++++++-------- 2 files changed, 30 insertions(+), 14 deletions(-) diff --git a/fastspi.h b/fastspi.h index d6a73352..f80956f4 100644 --- a/fastspi.h +++ b/fastspi.h @@ -17,17 +17,17 @@ /// byte worked on. Recommendation, make the adjust method aggressively inlined. /// /// TODO: Convinience macro for building these -class DATA_NOP { +class DATA_NOP { public: - static __attribute__((always_inline)) inline uint8_t adjust(register uint8_t data) { return data; } - static __attribute__((always_inline)) inline uint8_t adjust(register uint8_t data, register uint8_t scale) { return scale8(data, scale); } + static __attribute__((always_inline)) inline uint8_t adjust(register uint8_t data) { return data; } + static __attribute__((always_inline)) inline uint8_t adjust(register uint8_t data, register uint8_t scale) { return scale8(data, scale); } static __attribute__((always_inline)) inline void postBlock(int len) {} }; #define FLAG_START_BIT 0x80 #define MASK_SKIP_BITS 0x3F -// Clock speed dividers +// Clock speed dividers #define SPEED_DIV_2 2 #define SPEED_DIV_4 4 #define SPEED_DIV_8 8 @@ -37,8 +37,13 @@ public: #define SPEED_DIV_128 128 #define MAX_DATA_RATE 0 +#if (CLK_DBL == 1) +#define DATA_RATE_MHZ(X) (((F_CPU / 1000000L) / X)/2) +#define DATA_RATE_KHZ(X) (((F_CPU / 1000L) / X)/2) +#else #define DATA_RATE_MHZ(X) ((F_CPU / 1000000L) / X) #define DATA_RATE_KHZ(X) ((F_CPU / 1000L) / X) +#endif // Include the various specific SPI implementations #include "fastspi_bitbang.h" @@ -71,7 +76,7 @@ class SPIOutput : public ARMHardwareSPIOutput -class SPIOutput : public ARMHardwareSPIOutput {}; +class SPIOutput : public ARMHardwareSPIOutput {}; #endif #elif defined(__SAM3X8E__) @@ -98,6 +103,6 @@ class SPIOutput : public AVRHardwareSPIOutput Date: Wed, 18 Jun 2014 01:37:18 -0400 Subject: Initial Palette support. --- colorutils.cpp | 243 ++++++++++++++++++++++++++++++++++++++++++++++++++++ colorutils.h | 100 +++++++++++++++++++++ preview_changes.txt | 1 + 3 files changed, 344 insertions(+) diff --git a/colorutils.cpp b/colorutils.cpp index 12e9b0ad..399b2372 100644 --- a/colorutils.cpp +++ b/colorutils.cpp @@ -1,5 +1,7 @@ #include +#include + #include "hsv2rgb.h" #include "colorutils.h" @@ -185,3 +187,244 @@ CRGB HeatColor( uint8_t temperature) return heatcolor; } + + + +CRGB ColorFromPalette( const CRGBPalette16& pal, uint8_t index, uint8_t brightness, TInterpolationType interpolationType) +{ + uint8_t hi4 = index >> 4; + uint8_t lo4 = index & 0x0F; + + // CRGB rgb1 = pal[ hi4]; + const CRGB* entry = pal + hi4; + uint8_t red1 = entry->red; + uint8_t green1 = entry->green; + uint8_t blue1 = entry->blue; + + uint8_t interpolate = lo4 && (interpolationType != INTERPOLATION_NONE); + + if( interpolate ) { + + if( hi4 == 15 ) { + entry = pal; + } else { + entry++; + } + + uint8_t f2 = lo4 << 4; + uint8_t f1 = 256 - f2; + + // rgb1.nscale8(f1); + red1 = scale8_LEAVING_R1_DIRTY( red1, f1); + green1 = scale8_LEAVING_R1_DIRTY( green1, f1); + blue1 = scale8_LEAVING_R1_DIRTY( blue1, f1); + + // cleanup_R1(); + + // CRGB rgb2 = pal[ hi4]; + // rgb2.nscale8(f2); + uint8_t red2 = entry->red; + uint8_t green2 = entry->green; + uint8_t blue2 = entry->blue; + red2 = scale8_LEAVING_R1_DIRTY( red2, f2); + green2 = scale8_LEAVING_R1_DIRTY( green2, f2); + blue2 = scale8_LEAVING_R1_DIRTY( blue2, f2); + + cleanup_R1(); + + // These sums can't overflow, so no qadd8 needed. + red1 += red2; + green1 += green2; + blue1 += blue2; + + } + + if( brightness != 255) { + nscale8x3_video( red1, green1, blue1, brightness); + } + + return CRGB( red1, green1, blue1); +} + + +CRGB ColorFromPalette( const CRGBPalette256& pal, uint8_t index, uint8_t brightness, TInterpolationType) +{ + const CRGB* entry = pal + index; + + uint8_t red = entry->red; + uint8_t green = entry->green; + uint8_t blue = entry->blue; + + if( brightness != 255) { + nscale8x3_video( red, green, blue, brightness); + } + + return CRGB( red, green, blue); +} + +typedef prog_uint32_t TProgmemPalette16[16]; + +const TProgmemPalette16 CloudPalette_p PROGMEM = +{ + CRGB::Blue, + CRGB::DarkBlue, + CRGB::DarkBlue, + CRGB::DarkBlue, + + CRGB::DarkBlue, + CRGB::DarkBlue, + CRGB::DarkBlue, + CRGB::DarkBlue, + + CRGB::Blue, + CRGB::DarkBlue, + CRGB::SkyBlue, + CRGB::SkyBlue, + + CRGB::LightBlue, + CRGB::White, + CRGB::LightBlue, + CRGB::SkyBlue +}; + +const TProgmemPalette16 LavaPalette_p PROGMEM = +{ + CRGB::Black, + CRGB::Maroon, + CRGB::Black, + CRGB::Maroon, + + CRGB::DarkRed, + CRGB::Maroon, + CRGB::DarkRed, + + CRGB::DarkRed, + CRGB::DarkRed, + CRGB::Red, + CRGB::Orange, + + CRGB::White, + CRGB::Orange, + CRGB::Red, + CRGB::DarkRed +}; + + +const TProgmemPalette16 OceanPalette_p PROGMEM = +{ + CRGB::MidnightBlue, + CRGB::DarkBlue, + CRGB::MidnightBlue, + CRGB::Navy, + + CRGB::DarkBlue, + CRGB::MediumBlue, + CRGB::SeaGreen, + CRGB::Teal, + + CRGB::CadetBlue, + CRGB::Blue, + CRGB::DarkCyan, + CRGB::CornflowerBlue, + + CRGB::Aquamarine, + CRGB::SeaGreen, + CRGB::Aqua, + CRGB::LightSkyBlue +}; + +const TProgmemPalette16 ForestPalette_p PROGMEM = +{ + CRGB::DarkGreen, + CRGB::DarkGreen, + CRGB::DarkOliveGreen, + CRGB::DarkGreen, + + CRGB::Green, + CRGB::ForestGreen, + CRGB::OliveDrab, + CRGB::Green, + + CRGB::SeaGreen, + CRGB::MediumAquamarine, + CRGB::LimeGreen, + CRGB::YellowGreen, + + CRGB::LightGreen, + CRGB::LawnGreen, + CRGB::MediumAquamarine, + CRGB::ForestGreen +}; + + +void InitPalette(CRGBPalette16& pal, const TProgmemPalette16 ppp) +{ + for( uint8_t i = 0; i < 16; i++) { + pal[i] = pgm_read_dword_near( ppp + i); + } +} + +void UpscalePalette(const CRGBPalette16& srcpal16, CRGBPalette256& destpal256) +{ + for( int i = 0; i < 256; i++) { + destpal256[i] = ColorFromPalette( srcpal16, i); + } +} + +void SetCloudPalette(CRGBPalette16& pal) +{ + InitPalette( pal, CloudPalette_p); +} + +void SetLavaPalette(CRGBPalette16& pal) +{ + InitPalette( pal, LavaPalette_p); +} + +void SetOceanPalette(CRGBPalette16& pal) +{ + InitPalette( pal, OceanPalette_p); +} + +void SetForestPalette(CRGBPalette16& pal) +{ + InitPalette( pal, ForestPalette_p); +} + +void SetRainbowPalette(CRGBPalette16& pal) +{ + for( uint8_t c = 0; c < 16; c += 1) { + uint8_t hue = c << 4; + pal[c] = CHSV( hue, 255, 255); + } +} + +void SetRainbowStripesPalette(CRGBPalette16& pal) +{ + for( uint8_t c = 0; c < 16; c += 2) { + uint8_t hue = c << 4; + pal[c] = CHSV( hue, 255, 255); + pal[c+1] = CRGB::Black; + } +} + +void fill_palette(CRGB* L, uint16_t N, uint8_t startIndex, uint8_t incIndex, + const CRGBPalette16& pal, uint8_t brightness, TInterpolationType interpType) +{ + uint8_t colorIndex = startIndex; + for( uint16_t i = 0; i < N; i++) { + L[i] = ColorFromPalette( pal, colorIndex, brightness, interpType); + colorIndex += incIndex; + } +} + + +void fill_palette(CRGB* L, uint16_t N, uint8_t startIndex, uint8_t incIndex, + const CRGBPalette256& pal, uint8_t brightness, TInterpolationType interpType) +{ + uint8_t colorIndex = startIndex; + for( uint16_t i = 0; i < N; i++) { + L[i] = ColorFromPalette( pal, colorIndex, brightness, interpType); + colorIndex += incIndex; + } +} diff --git a/colorutils.h b/colorutils.h index 44b2855b..001b8d36 100644 --- a/colorutils.h +++ b/colorutils.h @@ -74,4 +74,104 @@ void nscale8( CRGB* leds, uint16_t num_leds, uint8_t scale); // spectrum, but it's surprisingly close, and it's fast and small. CRGB HeatColor( uint8_t temperature); + +// Palettes +// +// Palettes map an 8-bit value (0..255) to an RGB color. +// +// You can create any color palette you wish; a couple of starters +// are provided: Forest, Clouds, Lava, Ocean, Rainbow, and Rainbow Stripes. +// +// Palettes come in the traditional 256-entry variety, which take +// up 768 bytes of RAM, and lightweight 16-entry varieties. The 16-entry +// variety automatically interpolates between its entries to produce +// a full 256-element color map, but at a cost of only 48 bytes or RAM. +// +// Basic operation is like this: (example shows the 16-entry variety) +// 1. Declare your palette storage: +// CRGBPalette16 myPalette; +// +// 2. Fill myPalette with your own 16 colors, or with a preset color scheme. +// You can specify your 16 colors a variety of ways: +// CRGBPalette16 myPalette = +// { +// CRGB::Black, +// CRGB::Black, +// CRGB::Red, +// CRGB::Yellow, +// CRGB::Green, +// CRGB::Blue, +// CRGB::Purple, +// CRGB::Black, +// +// 0x100000, +// 0x200000, +// 0x400000, +// 0x800000, +// +// CHSV( 30,255,255), +// CHSV( 50,255,255), +// CHSV( 70,255,255), +// CHSV( 90,255,255) +// }; +// +// Or you can initiaize your palette with a preset color scheme: +// SetRainbowStripesPalette( myPalette); +// +// 3. Any time you want to set a pixel to a color from your palette, use +// "ColorFromPalette(...)" as shown: +// +// uint8_t index = /* any value 0..255 */; +// leds[i] = ColorFromPalette( myPalette, index); +// +// Even though your palette has only 16 explicily defined entries, you +// can use an 'index' from 0..255. The 16 explicit palette entries will +// be spread evenly across the 0..255 range, and the intermedate values +// will be RGB-interpolated between adjacent explicit entries. +// +// It's easier to use than it sounds. +// + +typedef CRGB CRGBPalette16[16]; +typedef CRGB CRGBPalette256[256]; + +typedef enum { INTERPOLATION_NONE=0, INTERPOLATION_BLEND=1 } TInterpolationType; + +CRGB ColorFromPalette( const CRGBPalette16& pal, + uint8_t index, + uint8_t brightness=255, + TInterpolationType interpolationType=INTERPOLATION_BLEND); + +CRGB ColorFromPalette( const CRGBPalette256& pal, + uint8_t index, + uint8_t brightness=255, + TInterpolationType interpolationType=INTERPOLATION_NONE ); + +// Preset color schemes, such as they are. +// Try Rainbow Stripes or Lava first. +void SetForestPalette(CRGBPalette16& pal); +void SetCloudPalette(CRGBPalette16& pal); +void SetLavaPalette(CRGBPalette16& pal); +void SetOceanPalette(CRGBPalette16& pal); +void SetRainbowPalette(CRGBPalette16& pal); +void SetRainbowStripesPalette(CRGBPalette16& pal); + + +// Convert a 16-entry palette to a 256-entry palette +void UpscalePalette(const CRGBPalette16& srcpal16, CRGBPalette256& destpal256); + +// Fill a range of LEDs with a sequece of entryies from a palette +void fill_palette(CRGB* L, uint16_t N, + uint8_t startIndex, uint8_t incIndex, + const CRGBPalette16& pal, + uint8_t brightness=255, + TInterpolationType interpType=INTERPOLATION_BLEND); + +void fill_palette(CRGB* L, uint16_t N, + uint8_t startIndex, uint8_t incIndex, + const CRGBPalette256& pal, + uint8_t brightness=255, + TInterpolationType interpType=INTERPOLATION_NONE); + + #endif diff --git a/preview_changes.txt b/preview_changes.txt index da565b0e..88a9f9bc 100644 --- a/preview_changes.txt +++ b/preview_changes.txt @@ -19,3 +19,4 @@ * Added fill_gradient * Added inoise8/inoise16 and example program * Added LEDS.countFPS() for debugging framerate counts. Bit rough at the moment, thought +* Added Palettes and associated functions and presets -- cgit v1.2.3 From 07d8c0cb281537a3dda5529fb232c5eb84836615 Mon Sep 17 00:00:00 2001 From: Mark Kriegsman Date: Wed, 18 Jun 2014 15:16:16 -0400 Subject: Changing names after some further thought, before we announce. Todo: clean up palette example. --- colorutils.cpp | 18 ++++++++++++------ colorutils.h | 15 ++++++++------- 2 files changed, 20 insertions(+), 13 deletions(-) diff --git a/colorutils.cpp b/colorutils.cpp index 399b2372..af71c4cc 100644 --- a/colorutils.cpp +++ b/colorutils.cpp @@ -371,27 +371,27 @@ void UpscalePalette(const CRGBPalette16& srcpal16, CRGBPalette256& destpal256) } } -void SetCloudPalette(CRGBPalette16& pal) +void SetupCloudColors(CRGBPalette16& pal) { InitPalette( pal, CloudPalette_p); } -void SetLavaPalette(CRGBPalette16& pal) +void SetupLavaColors(CRGBPalette16& pal) { InitPalette( pal, LavaPalette_p); } -void SetOceanPalette(CRGBPalette16& pal) +void SetupOceanColors(CRGBPalette16& pal) { InitPalette( pal, OceanPalette_p); } -void SetForestPalette(CRGBPalette16& pal) +void SetupForestColors(CRGBPalette16& pal) { InitPalette( pal, ForestPalette_p); } -void SetRainbowPalette(CRGBPalette16& pal) +void SetupRainbowColors(CRGBPalette16& pal) { for( uint8_t c = 0; c < 16; c += 1) { uint8_t hue = c << 4; @@ -399,7 +399,7 @@ void SetRainbowPalette(CRGBPalette16& pal) } } -void SetRainbowStripesPalette(CRGBPalette16& pal) +void SetupRainbowStripesColors(CRGBPalette16& pal) { for( uint8_t c = 0; c < 16; c += 2) { uint8_t hue = c << 4; @@ -408,6 +408,12 @@ void SetRainbowStripesPalette(CRGBPalette16& pal) } } +void SetupPartyColors(CRGBPalette16& pal) +{ + fill_gradient( pal, 0, CHSV( HUE_PURPLE,255,255), 7, CHSV(HUE_YELLOW - 12,255,255), FORWARD_HUES); + fill_gradient( pal, 8, CHSV( HUE_ORANGE,255,255), 15, CHSV(HUE_BLUE + 12,255,255), BACKWARD_HUES); +} + void fill_palette(CRGB* L, uint16_t N, uint8_t startIndex, uint8_t incIndex, const CRGBPalette16& pal, uint8_t brightness, TInterpolationType interpType) { diff --git a/colorutils.h b/colorutils.h index 001b8d36..bcc1efcb 100644 --- a/colorutils.h +++ b/colorutils.h @@ -116,7 +116,7 @@ CRGB HeatColor( uint8_t temperature); // }; // // Or you can initiaize your palette with a preset color scheme: -// SetRainbowStripesPalette( myPalette); +// SetupRainbowStripesPalette( myPalette); // // 3. Any time you want to set a pixel to a color from your palette, use // "ColorFromPalette(...)" as shown: @@ -149,12 +149,13 @@ CRGB ColorFromPalette( const CRGBPalette256& pal, // Preset color schemes, such as they are. // Try Rainbow Stripes or Lava first. -void SetForestPalette(CRGBPalette16& pal); -void SetCloudPalette(CRGBPalette16& pal); -void SetLavaPalette(CRGBPalette16& pal); -void SetOceanPalette(CRGBPalette16& pal); -void SetRainbowPalette(CRGBPalette16& pal); -void SetRainbowStripesPalette(CRGBPalette16& pal); +void SetupForestColors(CRGBPalette16& pal); +void SetupCloudColors(CRGBPalette16& pal); +void SetupLavaColors(CRGBPalette16& pal); +void SetupOceanColor(CRGBPalette16& pal); +void SetupRainbowColors(CRGBPalette16& pal); +void SetupRainbowStripesColors(CRGBPalette16& pal); +void SetupPartyColors(CRGBPalette16& pal); // Convert a 16-entry palette to a 256-entry palette -- cgit v1.2.3 From d80c32ff614907f919b2401209aecbccaacd9e47 Mon Sep 17 00:00:00 2001 From: Mark Kriegsman Date: Wed, 18 Jun 2014 15:17:27 -0400 Subject: Corrected a color --- colorutils.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/colorutils.cpp b/colorutils.cpp index af71c4cc..c4f78bd4 100644 --- a/colorutils.cpp +++ b/colorutils.cpp @@ -410,7 +410,7 @@ void SetupRainbowStripesColors(CRGBPalette16& pal) void SetupPartyColors(CRGBPalette16& pal) { - fill_gradient( pal, 0, CHSV( HUE_PURPLE,255,255), 7, CHSV(HUE_YELLOW - 12,255,255), FORWARD_HUES); + fill_gradient( pal, 0, CHSV( HUE_PURPLE,255,255), 7, CHSV(HUE_YELLOW - 16,255,255), FORWARD_HUES); fill_gradient( pal, 8, CHSV( HUE_ORANGE,255,255), 15, CHSV(HUE_BLUE + 12,255,255), BACKWARD_HUES); } -- cgit v1.2.3 From 56d02e449bd48dc8b949409c7aa8659825dcc5a0 Mon Sep 17 00:00:00 2001 From: Mark Kriegsman Date: Thu, 19 Jun 2014 19:28:32 -0400 Subject: Restructured palettes into actual classes. Think we're good to go now. --- colorutils.cpp | 168 +++-------------------------- colorutils.h | 327 ++++++++++++++++++++++++++++++++++++++++++++++++++++----- lib8tion.h | 4 + 3 files changed, 323 insertions(+), 176 deletions(-) diff --git a/colorutils.cpp b/colorutils.cpp index c4f78bd4..f480c9d9 100644 --- a/colorutils.cpp +++ b/colorutils.cpp @@ -190,23 +190,23 @@ CRGB HeatColor( uint8_t temperature) -CRGB ColorFromPalette( const CRGBPalette16& pal, uint8_t index, uint8_t brightness, TInterpolationType interpolationType) +CRGB ColorFromPalette( const CRGBPalette16& pal, uint8_t index, uint8_t brightness, TBlendType blendType) { uint8_t hi4 = index >> 4; uint8_t lo4 = index & 0x0F; // CRGB rgb1 = pal[ hi4]; - const CRGB* entry = pal + hi4; + const CRGB* entry = &(pal[0]) + hi4; uint8_t red1 = entry->red; uint8_t green1 = entry->green; uint8_t blue1 = entry->blue; - uint8_t interpolate = lo4 && (interpolationType != INTERPOLATION_NONE); + uint8_t blend = lo4 && (blendType != NOBLEND); - if( interpolate ) { + if( blend ) { if( hi4 == 15 ) { - entry = pal; + entry = &(pal[0]); } else { entry++; } @@ -247,9 +247,9 @@ CRGB ColorFromPalette( const CRGBPalette16& pal, uint8_t index, uint8_t brightne } -CRGB ColorFromPalette( const CRGBPalette256& pal, uint8_t index, uint8_t brightness, TInterpolationType) +CRGB ColorFromPalette( const CRGBPalette256& pal, uint8_t index, uint8_t brightness, TBlendType) { - const CRGB* entry = pal + index; + const CRGB* entry = &(pal[0]) + index; uint8_t red = entry->red; uint8_t green = entry->green; @@ -262,175 +262,39 @@ CRGB ColorFromPalette( const CRGBPalette256& pal, uint8_t index, uint8_t brightn return CRGB( red, green, blue); } -typedef prog_uint32_t TProgmemPalette16[16]; - -const TProgmemPalette16 CloudPalette_p PROGMEM = -{ - CRGB::Blue, - CRGB::DarkBlue, - CRGB::DarkBlue, - CRGB::DarkBlue, - - CRGB::DarkBlue, - CRGB::DarkBlue, - CRGB::DarkBlue, - CRGB::DarkBlue, - - CRGB::Blue, - CRGB::DarkBlue, - CRGB::SkyBlue, - CRGB::SkyBlue, - - CRGB::LightBlue, - CRGB::White, - CRGB::LightBlue, - CRGB::SkyBlue -}; - -const TProgmemPalette16 LavaPalette_p PROGMEM = -{ - CRGB::Black, - CRGB::Maroon, - CRGB::Black, - CRGB::Maroon, - - CRGB::DarkRed, - CRGB::Maroon, - CRGB::DarkRed, - - CRGB::DarkRed, - CRGB::DarkRed, - CRGB::Red, - CRGB::Orange, - - CRGB::White, - CRGB::Orange, - CRGB::Red, - CRGB::DarkRed -}; - - -const TProgmemPalette16 OceanPalette_p PROGMEM = -{ - CRGB::MidnightBlue, - CRGB::DarkBlue, - CRGB::MidnightBlue, - CRGB::Navy, - - CRGB::DarkBlue, - CRGB::MediumBlue, - CRGB::SeaGreen, - CRGB::Teal, - - CRGB::CadetBlue, - CRGB::Blue, - CRGB::DarkCyan, - CRGB::CornflowerBlue, - - CRGB::Aquamarine, - CRGB::SeaGreen, - CRGB::Aqua, - CRGB::LightSkyBlue -}; - -const TProgmemPalette16 ForestPalette_p PROGMEM = -{ - CRGB::DarkGreen, - CRGB::DarkGreen, - CRGB::DarkOliveGreen, - CRGB::DarkGreen, - - CRGB::Green, - CRGB::ForestGreen, - CRGB::OliveDrab, - CRGB::Green, - - CRGB::SeaGreen, - CRGB::MediumAquamarine, - CRGB::LimeGreen, - CRGB::YellowGreen, - - CRGB::LightGreen, - CRGB::LawnGreen, - CRGB::MediumAquamarine, - CRGB::ForestGreen -}; - - -void InitPalette(CRGBPalette16& pal, const TProgmemPalette16 ppp) -{ - for( uint8_t i = 0; i < 16; i++) { - pal[i] = pgm_read_dword_near( ppp + i); - } -} void UpscalePalette(const CRGBPalette16& srcpal16, CRGBPalette256& destpal256) { for( int i = 0; i < 256; i++) { - destpal256[i] = ColorFromPalette( srcpal16, i); - } -} - -void SetupCloudColors(CRGBPalette16& pal) -{ - InitPalette( pal, CloudPalette_p); -} - -void SetupLavaColors(CRGBPalette16& pal) -{ - InitPalette( pal, LavaPalette_p); -} - -void SetupOceanColors(CRGBPalette16& pal) -{ - InitPalette( pal, OceanPalette_p); -} - -void SetupForestColors(CRGBPalette16& pal) -{ - InitPalette( pal, ForestPalette_p); -} - -void SetupRainbowColors(CRGBPalette16& pal) -{ - for( uint8_t c = 0; c < 16; c += 1) { - uint8_t hue = c << 4; - pal[c] = CHSV( hue, 255, 255); - } -} - -void SetupRainbowStripesColors(CRGBPalette16& pal) -{ - for( uint8_t c = 0; c < 16; c += 2) { - uint8_t hue = c << 4; - pal[c] = CHSV( hue, 255, 255); - pal[c+1] = CRGB::Black; + destpal256[(uint8_t)(i)] = ColorFromPalette( srcpal16, i); } } void SetupPartyColors(CRGBPalette16& pal) { - fill_gradient( pal, 0, CHSV( HUE_PURPLE,255,255), 7, CHSV(HUE_YELLOW - 16,255,255), FORWARD_HUES); - fill_gradient( pal, 8, CHSV( HUE_ORANGE,255,255), 15, CHSV(HUE_BLUE + 12,255,255), BACKWARD_HUES); + fill_gradient( pal, 0, CHSV( HUE_PURPLE,255,255), 7, CHSV(HUE_YELLOW - 18,255,255), FORWARD_HUES); + fill_gradient( pal, 8, CHSV( HUE_ORANGE,255,255), 15, CHSV(HUE_BLUE + 18,255,255), BACKWARD_HUES); } void fill_palette(CRGB* L, uint16_t N, uint8_t startIndex, uint8_t incIndex, - const CRGBPalette16& pal, uint8_t brightness, TInterpolationType interpType) + const CRGBPalette16& pal, uint8_t brightness, TBlendType blendType) { uint8_t colorIndex = startIndex; for( uint16_t i = 0; i < N; i++) { - L[i] = ColorFromPalette( pal, colorIndex, brightness, interpType); + L[i] = ColorFromPalette( pal, colorIndex, brightness, blendType); colorIndex += incIndex; } } void fill_palette(CRGB* L, uint16_t N, uint8_t startIndex, uint8_t incIndex, - const CRGBPalette256& pal, uint8_t brightness, TInterpolationType interpType) + const CRGBPalette256& pal, uint8_t brightness, TBlendType blendType) { uint8_t colorIndex = startIndex; for( uint16_t i = 0; i < N; i++) { - L[i] = ColorFromPalette( pal, colorIndex, brightness, interpType); + L[i] = ColorFromPalette( pal, colorIndex, brightness, blendType); colorIndex += incIndex; } } + + diff --git a/colorutils.h b/colorutils.h index bcc1efcb..2925422b 100644 --- a/colorutils.h +++ b/colorutils.h @@ -93,8 +93,7 @@ CRGB HeatColor( uint8_t temperature); // // 2. Fill myPalette with your own 16 colors, or with a preset color scheme. // You can specify your 16 colors a variety of ways: -// CRGBPalette16 myPalette = -// { +// CRGBPalette16 myPalette( // CRGB::Black, // CRGB::Black, // CRGB::Red, @@ -113,10 +112,10 @@ CRGB HeatColor( uint8_t temperature); // CHSV( 50,255,255), // CHSV( 70,255,255), // CHSV( 90,255,255) -// }; +// ); // // Or you can initiaize your palette with a preset color scheme: -// SetupRainbowStripesPalette( myPalette); +// myPalette = RainbowStripesColors_p; // // 3. Any time you want to set a pixel to a color from your palette, use // "ColorFromPalette(...)" as shown: @@ -132,47 +131,327 @@ CRGB HeatColor( uint8_t temperature); // It's easier to use than it sounds. // -typedef CRGB CRGBPalette16[16]; -typedef CRGB CRGBPalette256[256]; +class CRGBPalette16; +class CRGBPalette256; +typedef prog_uint32_t TProgmemPalette16[16]; -typedef enum { INTERPOLATION_NONE=0, INTERPOLATION_BLEND=1 } TInterpolationType; +// Convert a 16-entry palette to a 256-entry palette +void UpscalePalette(const CRGBPalette16& srcpal16, CRGBPalette256& destpal256); + + +class CRGBPalette16 { +public: + CRGB entries[16]; + CRGBPalette16() {}; + CRGBPalette16( const CRGB& c00,const CRGB& c01,const CRGB& c02,const CRGB& c03, + const CRGB& c04,const CRGB& c05,const CRGB& c06,const CRGB& c07, + const CRGB& c08,const CRGB& c09,const CRGB& c10,const CRGB& c11, + const CRGB& c12,const CRGB& c13,const CRGB& c14,const CRGB& c15 ) + { + entries[0]=c00; entries[1]=c01; entries[2]=c02; entries[3]=c03; + entries[4]=c04; entries[5]=c05; entries[6]=c06; entries[7]=c07; + entries[8]=c08; entries[9]=c09; entries[10]=c10; entries[11]=c11; + entries[12]=c12; entries[13]=c13; entries[14]=c14; entries[15]=c15; + }; + + CRGBPalette16( const CRGBPalette16& rhs) + { + memmove8( &(entries[0]), &(rhs.entries[0]), sizeof( entries)); + } + CRGBPalette16& operator=( const CRGBPalette16& rhs) + { + memmove8( &(entries[0]), &(rhs.entries[0]), sizeof( entries)); + return *this; + } + + CRGBPalette16( const TProgmemPalette16& rhs) + { + for( uint8_t i = 0; i < 16; i++) { + entries[i] = pgm_read_dword_near( rhs + i); + } + } + CRGBPalette16& operator=( const TProgmemPalette16& rhs) + { + for( uint8_t i = 0; i < 16; i++) { + entries[i] = pgm_read_dword_near( rhs + i); + } + return *this; + } + + inline CRGB& operator[] (uint8_t x) __attribute__((always_inline)) + { + return entries[x]; + } + inline const CRGB& operator[] (uint8_t x) const __attribute__((always_inline)) + { + return entries[x]; + } + + inline CRGB& operator[] (int x) __attribute__((always_inline)) + { + return entries[(uint8_t)x]; + } + inline const CRGB& operator[] (int x) const __attribute__((always_inline)) + { + return entries[(uint8_t)x]; + } + + operator CRGB*() + { + return &(entries[0]); + } +}; + +class CRGBPalette256 { +public: + CRGB entries[256]; + CRGBPalette256() {}; + CRGBPalette256( const CRGB& c00,const CRGB& c01,const CRGB& c02,const CRGB& c03, + const CRGB& c04,const CRGB& c05,const CRGB& c06,const CRGB& c07, + const CRGB& c08,const CRGB& c09,const CRGB& c10,const CRGB& c11, + const CRGB& c12,const CRGB& c13,const CRGB& c14,const CRGB& c15 ) + { + CRGBPalette16 p16(c00,c01,c02,c03,c04,c05,c06,c07, + c08,c09,c10,c11,c12,c13,c14,c15); + *this = p16; + }; + + CRGBPalette256( const CRGBPalette256& rhs) + { + memmove8( &(entries[0]), &(rhs.entries[0]), sizeof( entries)); + } + CRGBPalette256& operator=( const CRGBPalette256& rhs) + { + memmove8( &(entries[0]), &(rhs.entries[0]), sizeof( entries)); + return *this; + } + + CRGBPalette256( const CRGBPalette16& rhs16) + { + UpscalePalette( rhs16, *this); + } + CRGBPalette256& operator=( const CRGBPalette16& rhs16) + { + UpscalePalette( rhs16, *this); + return *this; + } + + CRGBPalette256( const TProgmemPalette16& rhs) + { + CRGBPalette16 p16(rhs); + *this = p16; + } + CRGBPalette256& operator=( const TProgmemPalette16& rhs) + { + CRGBPalette16 p16(rhs); + *this = p16; + return *this; + } + + inline CRGB& operator[] (uint8_t x) __attribute__((always_inline)) + { + return entries[x]; + } + inline const CRGB& operator[] (uint8_t x) const __attribute__((always_inline)) + { + return entries[x]; + } + + inline CRGB& operator[] (int x) __attribute__((always_inline)) + { + return entries[(uint8_t)x]; + } + inline const CRGB& operator[] (int x) const __attribute__((always_inline)) + { + return entries[(uint8_t)x]; + } + + operator CRGB*() + { + return &(entries[0]); + } +}; + +typedef enum { NOBLEND=0, BLEND=1 } TBlendType; CRGB ColorFromPalette( const CRGBPalette16& pal, uint8_t index, uint8_t brightness=255, - TInterpolationType interpolationType=INTERPOLATION_BLEND); + TBlendType blendType=BLEND); CRGB ColorFromPalette( const CRGBPalette256& pal, uint8_t index, uint8_t brightness=255, - TInterpolationType interpolationType=INTERPOLATION_NONE ); - -// Preset color schemes, such as they are. -// Try Rainbow Stripes or Lava first. -void SetupForestColors(CRGBPalette16& pal); -void SetupCloudColors(CRGBPalette16& pal); -void SetupLavaColors(CRGBPalette16& pal); -void SetupOceanColor(CRGBPalette16& pal); -void SetupRainbowColors(CRGBPalette16& pal); -void SetupRainbowStripesColors(CRGBPalette16& pal); -void SetupPartyColors(CRGBPalette16& pal); + TBlendType blendType=NOBLEND ); -// Convert a 16-entry palette to a 256-entry palette -void UpscalePalette(const CRGBPalette16& srcpal16, CRGBPalette256& destpal256); - // Fill a range of LEDs with a sequece of entryies from a palette void fill_palette(CRGB* L, uint16_t N, uint8_t startIndex, uint8_t incIndex, const CRGBPalette16& pal, uint8_t brightness=255, - TInterpolationType interpType=INTERPOLATION_BLEND); + TBlendType blendType=BLEND); void fill_palette(CRGB* L, uint16_t N, uint8_t startIndex, uint8_t incIndex, const CRGBPalette256& pal, uint8_t brightness=255, - TInterpolationType interpType=INTERPOLATION_NONE); + TBlendType blendType=NOBLEND); + + +// Preset color schemes, such as they are. +const TProgmemPalette16 CloudColors_p PROGMEM = +{ + CRGB::Blue, + CRGB::DarkBlue, + CRGB::DarkBlue, + CRGB::DarkBlue, + + CRGB::DarkBlue, + CRGB::DarkBlue, + CRGB::DarkBlue, + CRGB::DarkBlue, + + CRGB::Blue, + CRGB::DarkBlue, + CRGB::SkyBlue, + CRGB::SkyBlue, + + CRGB::LightBlue, + CRGB::White, + CRGB::LightBlue, + CRGB::SkyBlue +}; + +const TProgmemPalette16 LavaColors_p PROGMEM = +{ + CRGB::Black, + CRGB::Maroon, + CRGB::Black, + CRGB::Maroon, + + CRGB::DarkRed, + CRGB::Maroon, + CRGB::DarkRed, + + CRGB::DarkRed, + CRGB::DarkRed, + CRGB::Red, + CRGB::Orange, + + CRGB::White, + CRGB::Orange, + CRGB::Red, + CRGB::DarkRed +}; + + +const TProgmemPalette16 OceanColors_p PROGMEM = +{ + CRGB::MidnightBlue, + CRGB::DarkBlue, + CRGB::MidnightBlue, + CRGB::Navy, + + CRGB::DarkBlue, + CRGB::MediumBlue, + CRGB::SeaGreen, + CRGB::Teal, + + CRGB::CadetBlue, + CRGB::Blue, + CRGB::DarkCyan, + CRGB::CornflowerBlue, + + CRGB::Aquamarine, + CRGB::SeaGreen, + CRGB::Aqua, + CRGB::LightSkyBlue +}; + +const TProgmemPalette16 ForestColors_p PROGMEM = +{ + CRGB::DarkGreen, + CRGB::DarkGreen, + CRGB::DarkOliveGreen, + CRGB::DarkGreen, + + CRGB::Green, + CRGB::ForestGreen, + CRGB::OliveDrab, + CRGB::Green, + + CRGB::SeaGreen, + CRGB::MediumAquamarine, + CRGB::LimeGreen, + CRGB::YellowGreen, + + CRGB::LightGreen, + CRGB::LawnGreen, + CRGB::MediumAquamarine, + CRGB::ForestGreen +}; + +const TProgmemPalette16 RainbowColors_p PROGMEM = +{ + 0xFF0000, + 0xD52A00, + 0xAB5500, + 0xAB7F00, + 0xABAB00, + 0x56D500, + 0x00FF00, + 0x00D52A, + 0x00AB55, + 0x0056AA, + 0x0000FF, + 0x2A00D5, + 0x5500AB, + 0x7F0081, + 0xAB0055, + 0xD5002B +}; + +#define RainbowStripesColors_p RainbowStripeColors_p +const TProgmemPalette16 RainbowStripeColors_p PROGMEM = +{ + 0xFF0000, + 0x000000, + 0xAB5500, + 0x000000, + 0xABAB00, + 0x000000, + 0x00FF00, + 0x000000, + 0x00AB55, + 0x000000, + 0x0000FF, + 0x000000, + 0x5500AB, + 0x000000, + 0xAB0055, + 0x000000 +}; + +const TProgmemPalette16 PartyColors_p PROGMEM = +{ + 0x5500AB, + 0x84007C, + 0xB5004B, + 0xE5001B, + 0xE81700, + 0xB84700, + 0xAB7700, + 0xABAB00, + 0xAB5500, + 0xDD2200, + 0xF2000E, + 0xC2003E, + 0x8F0071, + 0x5F00A1, + 0x2F00D0, + 0x0007F9, +}; #endif diff --git a/lib8tion.h b/lib8tion.h index 457aae88..0c8b32ac 100644 --- a/lib8tion.h +++ b/lib8tion.h @@ -145,6 +145,10 @@ Lib8tion is pronounced like 'libation': lie-BAY-shun #define LIB8STATIC __attribute__ ((unused)) static inline +#if !defined(__AVR__) +#include +// for memmove, memcpy, and memset if not defined here +#endif #if defined(__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__) || defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__) #define LIB8_ATTINY 1 -- cgit v1.2.3 From c271e729a4485eb8c2da596e2617c8045ece6986 Mon Sep 17 00:00:00 2001 From: Mark Kriegsman Date: Thu, 19 Jun 2014 19:29:18 -0400 Subject: Adding ColorPalette example --- examples/ColorPalette/ColorPalette.ino | 189 +++++++++++++++++++++++++++++++++ 1 file changed, 189 insertions(+) create mode 100644 examples/ColorPalette/ColorPalette.ino diff --git a/examples/ColorPalette/ColorPalette.ino b/examples/ColorPalette/ColorPalette.ino new file mode 100644 index 00000000..93318998 --- /dev/null +++ b/examples/ColorPalette/ColorPalette.ino @@ -0,0 +1,189 @@ +#include + +#define LED_PIN 5 +#define NUM_LEDS 50 +#define BRIGHTNESS 64 +#define LED_TYPE WS2811 +#define COLOR_ORDER GRB +CRGB leds[NUM_LEDS]; + +#define UPDATES_PER_SECOND 100 + +// This example shows several ways to set up and use 'palettes' of colors +// with FastLED. +// +// These compact palettes provide an easy way to re-colorize your +// animation on the fly, quickly, easily, and with low overhead. +// +// USING palettes is MUCH simpler in practice than in theory, so first just +// run this sketch, and watch the pretty lights as you then read through +// the code. Although this sketch has eight (or more) different color schemes, +// the entire sketch compiles down to about 6.5K on AVR. +// +// FastLED provides a few pre-configured color palettes, and makes it +// extremely easy to make up your own color schemes with palettes. +// +// Some notes on the more abstract 'theory and practice' of +// FastLED compact palettes are at the bottom of this file. + + + +CRGBPalette16 currentPalette; +TBlendType currentBlending; + +extern CRGBPalette16 myRedWhiteBluePalette; +extern const TProgmemPalette16 myRedWhiteBluePalette_p PROGMEM; + + +void setup() { + delay( 3000 ); // power-up safety delay + FastLED.addLeds(leds, NUM_LEDS).setCorrection( TypicalLEDStrip ); + FastLED.setBrightness( BRIGHTNESS ); + + currentPalette = RainbowColors_p; + currentBlending = BLEND; +} + + +void loop() +{ + ChangePalettePeriodically(); + + static uint8_t startIndex = 0; + startIndex = startIndex + 1; /* motion speed */ + + FillLEDsFromPaletteColors( startIndex); + + FastLED.show(); + FastLED.delay(1000 / UPDATES_PER_SECOND); +} + +void FillLEDsFromPaletteColors( uint8_t colorIndex) +{ + uint8_t brightness = 255; + + for( int i = 0; i < NUM_LEDS; i++) { + leds[i] = ColorFromPalette( currentPalette, colorIndex, brightness, currentBlending); + colorIndex += 3; + } +} + + +// There are several different palettes of colors demonstrated here. +// +// FastLED provides several 'preset' palettes: RainbowColors_p, RainbowStripeColors_p, +// OceanColors_p, CloudColors_p, LavaColors_p, ForestColors_p, and PartyColors_p. +// +// Additionally, you can manually define your own color palettes, or you can write +// code that creates color palettes on the fly. All are shown here. + +void ChangePalettePeriodically() +{ + uint8_t secondHand = (millis() / 1000) % 60; + static uint8_t lastSecond = 99; + + if( lastSecond != secondHand) { + lastSecond = secondHand; + if( secondHand == 0) { currentPalette = RainbowColors_p; currentBlending = BLEND; } + if( secondHand == 10) { currentPalette = RainbowStripeColors_p; currentBlending = NOBLEND; } + if( secondHand == 15) { currentPalette = RainbowStripeColors_p; currentBlending = BLEND; } + if( secondHand == 20) { SetupPurpleAndGreenPalette(); currentBlending = BLEND; } + if( secondHand == 25) { SetupTotallyRandomPalette(); currentBlending = BLEND; } + if( secondHand == 30) { SetupBlackAndWhiteStripedPalette(); currentBlending = NOBLEND; } + if( secondHand == 35) { SetupBlackAndWhiteStripedPalette(); currentBlending = BLEND; } + if( secondHand == 40) { currentPalette = CloudColors_p; currentBlending = BLEND; } + if( secondHand == 45) { currentPalette = PartyColors_p; currentBlending = BLEND; } + if( secondHand == 50) { currentPalette = myRedWhiteBluePalette_p; currentBlending = NOBLEND; } + if( secondHand == 55) { currentPalette = myRedWhiteBluePalette_p; currentBlending = BLEND; } + } +} + +// This function fills the palette with totally random colors. +void SetupTotallyRandomPalette() +{ + for( int i = 0; i < 16; i++) { + currentPalette[i] = CHSV( random8(), 255, random8()); + } +} + +// This function sets up a palette of black and white stripes, +// using code. Since the palette is effectively an array of +// sixteen CRGB colors, the various fill_* functions can be used +// to set them up. +void SetupBlackAndWhiteStripedPalette() +{ + // 'black out' all 16 palette entries... + fill_solid( currentPalette, 16, CRGB::Black); + // and set every fourth one to white. + currentPalette[0] = CRGB::White; + currentPalette[4] = CRGB::White; + currentPalette[8] = CRGB::White; + currentPalette[12] = CRGB::White; + +} + +// This function sets up a palette of purple and green stripes. +void SetupPurpleAndGreenPalette() +{ + CRGB purple = CHSV( HUE_PURPLE, 255, 255); + CRGB green = CHSV( HUE_GREEN, 255, 255); + CRGB black = CRGB::Black; + + currentPalette = CRGBPalette16( + green, green, black, black, + purple, purple, black, black, + green, green, black, black, + purple, purple, black, black ); +} + + +// This example shows how to set up a static color palette +// which is stored in PROGMEM (flash), which is almost always more +// plentiful than RAM. A static PROGMEM palette like this +// takes up 64 bytes of flash. +const TProgmemPalette16 myRedWhiteBluePalette_p PROGMEM = +{ + CRGB::Red, + CRGB::Gray, // 'white' is too bright compared to red and blue + CRGB::Blue, + CRGB::Black, + + CRGB::Red, + CRGB::Gray, + CRGB::Blue, + CRGB::Black, + + CRGB::Red, + CRGB::Red, + CRGB::Gray, + CRGB::Gray, + CRGB::Blue, + CRGB::Blue, + CRGB::Black, + CRGB::Black +}; + + + +// Additionl notes on FastLED compact palettes: +// +// Normally, in computer graphics, the palette (or "color lookup table") +// has 256 entries, each containing a specific 24-bit RGB color. You can then +// index into the color palette using a simple 8-bit (one byte) value. +// A 256-entry color palette takes up 768 bytes of RAM, which on Arduino +// is quite possibly "too many" bytes. +// +// FastLED does offer traditional 256-element palettes, for setups that +// can afford the 768-byte cost in RAM. +// +// However, FastLED also offers a compact alternative. FastLED offers +// palettes that store 16 distinct entries, but can be accessed AS IF +// they actually have 256 entries; this is accomplished by interpolating +// between the 16 explicit entries to create fifteen intermediate palette +// entries between each pair. +// +// So for example, if you set the first two explicit entries of a compact +// palette to Green (0,255,0) and Blue (0,0,255), and then retrieved +// the first sixteen entries from the virtual palette (of 256), you'd get +// Green, followed by a smooth gradient from green-to-blue, and then Blue. + -- cgit v1.2.3 From c3651c89bf48f335cfd80c688e7eb775ed8cc524 Mon Sep 17 00:00:00 2001 From: Mark Kriegsman Date: Fri, 27 Jun 2014 13:44:21 -0400 Subject: Added gradient variations, reorg'd palettes a bit. --- FastLED.h | 1 + colorpalettes.h | 153 +++++++++++++++++++++++++++++++ colorutils.cpp | 185 ++++++++++++++++++++++++++++++++++++- colorutils.h | 279 +++++++++++++++++++++++++------------------------------- 4 files changed, 461 insertions(+), 157 deletions(-) create mode 100644 colorpalettes.h diff --git a/FastLED.h b/FastLED.h index a305762b..78794336 100644 --- a/FastLED.h +++ b/FastLED.h @@ -15,6 +15,7 @@ #include "lib8tion.h" #include "hsv2rgb.h" #include "colorutils.h" +#include "colorpalettes.h" #include "chipsets.h" #include "dmx.h" #include "noise.h" diff --git a/colorpalettes.h b/colorpalettes.h new file mode 100644 index 00000000..0a127ef4 --- /dev/null +++ b/colorpalettes.h @@ -0,0 +1,153 @@ +#ifndef __INC_COLORPALETTES_H +#define __INC_COLORPALETTES_H + +#include "colorutils.h" + + +// Preset color schemes, such as they are. + +// These schemes are all declared as "PROGMEM", meaning +// that they won't take up SRAM on AVR chips until used. +// Furthermore, the compiler won't even include these +// in your PROGMEM (flash) storage unless you specifically +// use each one, so you only 'pay for' those you actually use. + + +const TProgmemPalette16 CloudColors_p PROGMEM = +{ + CRGB::Blue, + CRGB::DarkBlue, + CRGB::DarkBlue, + CRGB::DarkBlue, + + CRGB::DarkBlue, + CRGB::DarkBlue, + CRGB::DarkBlue, + CRGB::DarkBlue, + + CRGB::Blue, + CRGB::DarkBlue, + CRGB::SkyBlue, + CRGB::SkyBlue, + + CRGB::LightBlue, + CRGB::White, + CRGB::LightBlue, + CRGB::SkyBlue +}; + +const TProgmemPalette16 LavaColors_p PROGMEM = +{ + CRGB::Black, + CRGB::Maroon, + CRGB::Black, + CRGB::Maroon, + + CRGB::DarkRed, + CRGB::Maroon, + CRGB::DarkRed, + + CRGB::DarkRed, + CRGB::DarkRed, + CRGB::Red, + CRGB::Orange, + + CRGB::White, + CRGB::Orange, + CRGB::Red, + CRGB::DarkRed +}; + + +const TProgmemPalette16 OceanColors_p PROGMEM = +{ + CRGB::MidnightBlue, + CRGB::DarkBlue, + CRGB::MidnightBlue, + CRGB::Navy, + + CRGB::DarkBlue, + CRGB::MediumBlue, + CRGB::SeaGreen, + CRGB::Teal, + + CRGB::CadetBlue, + CRGB::Blue, + CRGB::DarkCyan, + CRGB::CornflowerBlue, + + CRGB::Aquamarine, + CRGB::SeaGreen, + CRGB::Aqua, + CRGB::LightSkyBlue +}; + +const TProgmemPalette16 ForestColors_p PROGMEM = +{ + CRGB::DarkGreen, + CRGB::DarkGreen, + CRGB::DarkOliveGreen, + CRGB::DarkGreen, + + CRGB::Green, + CRGB::ForestGreen, + CRGB::OliveDrab, + CRGB::Green, + + CRGB::SeaGreen, + CRGB::MediumAquamarine, + CRGB::LimeGreen, + CRGB::YellowGreen, + + CRGB::LightGreen, + CRGB::LawnGreen, + CRGB::MediumAquamarine, + CRGB::ForestGreen +}; + +// HSV Rainbow +const TProgmemPalette16 RainbowColors_p PROGMEM = +{ + 0xFF0000, 0xD52A00, 0xAB5500, 0xAB7F00, + 0xABAB00, 0x56D500, 0x00FF00, 0x00D52A, + 0x00AB55, 0x0056AA, 0x0000FF, 0x2A00D5, + 0x5500AB, 0x7F0081, 0xAB0055, 0xD5002B +}; + +// HSV Rainbow colors with alternatating stripes of black +#define RainbowStripesColors_p RainbowStripeColors_p +const TProgmemPalette16 RainbowStripeColors_p PROGMEM = +{ + 0xFF0000, 0x000000, 0xAB5500, 0x000000, + 0xABAB00, 0x000000, 0x00FF00, 0x000000, + 0x00AB55, 0x000000, 0x0000FF, 0x000000, + 0x5500AB, 0x000000, 0xAB0055, 0x000000 +}; + +// HSV color ramp: blue purple ping red orange yellow (and back) +// Basically, everything but the greens, which tend to make +// people's skin look unhealthy. This palette is good for +// lighting at a club or party, where it'll be shining on people. +const TProgmemPalette16 PartyColors_p PROGMEM = +{ + 0x5500AB, 0x84007C, 0xB5004B, 0xE5001B, + 0xE81700, 0xB84700, 0xAB7700, 0xABAB00, + 0xAB5500, 0xDD2200, 0xF2000E, 0xC2003E, + 0x8F0071, 0x5F00A1, 0x2F00D0, 0x0007F9 +}; + +// Approximate "black body radiation" palette, akin to +// the FastLED 'HeatColor' function. +// Recommend that you use values 0-240 rather than +// the usual 0-255, as the last 15 colors will be +// 'wrapping around' from the hot end to the cold end, +// which looks wrong. +const TProgmemPalette16 HeatColors_p PROGMEM = +{ + 0x000000, + 0x330000, 0x660000, 0x990000, 0xCC0000, 0xFF0000, + 0xFF3300, 0xFF6600, 0xFF9900, 0xFFCC00, 0xFFFF00, + 0xFFFF33, 0xFFFF66, 0xFFFF99, 0xFFFFCC, 0xFFFFFF +}; + +#endif diff --git a/colorutils.cpp b/colorutils.cpp index f480c9d9..a967aa17 100644 --- a/colorutils.cpp +++ b/colorutils.cpp @@ -1,7 +1,5 @@ #include -#include - #include "hsv2rgb.h" #include "colorutils.h" @@ -96,6 +94,133 @@ void fill_gradient( CRGB* leds, } } +void fill_gradient_RGB( CRGB* leds, + uint16_t startpos, CRGB startcolor, + uint16_t endpos, CRGB endcolor ) +{ + // if the points are in the wrong order, straighten them + if( endpos < startpos ) { + uint16_t t = endpos; + CRGB tc = endcolor; + startpos = t; + startcolor = tc; + endcolor = startcolor; + endpos = startpos; + } + + saccum87 rdistance87; + saccum87 gdistance87; + saccum87 bdistance87; + + rdistance87 = (endcolor.r - startcolor.r) << 7; + gdistance87 = (endcolor.g - startcolor.g) << 7; + bdistance87 = (endcolor.b - startcolor.b) << 7; + + uint16_t pixeldistance = endpos - startpos; + uint16_t p2 = pixeldistance / 2; + int16_t divisor = p2 ? p2 : 1; + saccum87 rdelta87 = rdistance87 / divisor; + saccum87 gdelta87 = gdistance87 / divisor; + saccum87 bdelta87 = bdistance87 / divisor; + + accum88 r88 = startcolor.r << 8; + accum88 g88 = startcolor.g << 8; + accum88 b88 = startcolor.b << 8; + for( uint16_t i = startpos; i <= endpos; i++) { + leds[i] = CRGB( r88 >> 8, g88 >> 8, b88 >> 8); + r88 += rdelta87; + g88 += gdelta87; + b88 += bdelta87; + } +} + + +void fill_gradient( CRGB* leds, uint16_t numLeds, const CHSV& c1, const CHSV& c2, TGradientDirectionCode directionCode ) +{ + uint16_t last = numLeds - 1; + fill_gradient( leds, 0, c1, last, c2, directionCode); +} + + +void fill_gradient( CRGB* leds, uint16_t numLeds, const CHSV& c1, const CHSV& c2, const CHSV& c3, TGradientDirectionCode directionCode ) +{ + uint16_t half = (numLeds / 2); + uint16_t last = numLeds - 1; + fill_gradient( leds, 0, c1, half, c2, directionCode); + fill_gradient( leds, half, c2, last, c3, directionCode); +} + +void fill_gradient( CRGB* leds, uint16_t numLeds, const CHSV& c1, const CHSV& c2, const CHSV& c3, const CHSV& c4, TGradientDirectionCode directionCode ) +{ + uint16_t onethird = (numLeds / 3); + uint16_t twothirds = ((numLeds * 2) / 3); + uint16_t last = numLeds - 1; + fill_gradient( leds, 0, c1, onethird, c2, directionCode); + fill_gradient( leds, onethird, c2, twothirds, c3, directionCode); + fill_gradient( leds, twothirds, c3, last, c4, directionCode); +} + +#if 0 +void fill_gradient( const CHSV& c1, const CHSV& c2) +{ + fill_gradient( FastLED[0].leds(), FastLED[0].size(), c1, c2); +} + +void fill_gradient( const CHSV& c1, const CHSV& c2, const CHSV& c3) +{ + fill_gradient( FastLED[0].leds(), FastLED[0].size(), c1, c2, c3); +} + +void fill_gradient( const CHSV& c1, const CHSV& c2, const CHSV& c3, const CHSV& c4) +{ + fill_gradient( FastLED[0].leds(), FastLED[0].size(), c1, c2, c3, c4); +} + +void fill_gradient_RGB( const CRGB& c1, const CRGB& c2) +{ + fill_gradient_RGB( FastLED[0].leds(), FastLED[0].size(), c1, c2); +} + +void fill_gradient_RGB( const CRGB& c1, const CRGB& c2, const CRGB& c3) +{ + fill_gradient_RGB( FastLED[0].leds(), FastLED[0].size(), c1, c2, c3); +} + +void fill_gradient_RGB( const CRGB& c1, const CRGB& c2, const CRGB& c3, const CRGB& c4) +{ + fill_gradient_RGB( FastLED[0].leds(), FastLED[0].size(), c1, c2, c3, c4); +} +#endif + + + + +void fill_gradient_RGB( CRGB* leds, uint16_t numLeds, const CRGB& c1, const CRGB& c2) +{ + uint16_t last = numLeds - 1; + fill_gradient_RGB( leds, 0, c1, last, c2); +} + + +void fill_gradient_RGB( CRGB* leds, uint16_t numLeds, const CRGB& c1, const CRGB& c2, const CRGB& c3) +{ + uint16_t half = (numLeds / 2); + uint16_t last = numLeds - 1; + fill_gradient_RGB( leds, 0, c1, half, c2); + fill_gradient_RGB( leds, half, c2, last, c3); +} + +void fill_gradient_RGB( CRGB* leds, uint16_t numLeds, const CRGB& c1, const CRGB& c2, const CRGB& c3, const CRGB& c4) +{ + uint16_t onethird = (numLeds / 3); + uint16_t twothirds = ((numLeds * 2) / 3); + uint16_t last = numLeds - 1; + fill_gradient_RGB( leds, 0, c1, onethird, c2); + fill_gradient_RGB( leds, onethird, c2, twothirds, c3); + fill_gradient_RGB( leds, twothirds, c3, last, c4); +} + + void nscale8_video( CRGB* leds, uint16_t num_leds, uint8_t scale) @@ -139,6 +264,59 @@ void nscale8( CRGB* leds, uint16_t num_leds, uint8_t scale) } +CRGB& nblend( CRGB& existing, const CRGB& overlay, fract8 amountOfOverlay ) +{ + if( amountOfOverlay == 0) { + return existing; + } + + if( amountOfOverlay == 255) { + existing = overlay; + return existing; + } + + fract8 amountOfKeep = 256 - amountOfOverlay; + + existing.red = scale8_LEAVING_R1_DIRTY( existing.red, amountOfKeep) + + scale8_LEAVING_R1_DIRTY( overlay.red, amountOfOverlay); + existing.green = scale8_LEAVING_R1_DIRTY( existing.green, amountOfKeep) + + scale8_LEAVING_R1_DIRTY( overlay.green, amountOfOverlay); + existing.blue = scale8_LEAVING_R1_DIRTY( existing.blue, amountOfKeep) + + scale8_LEAVING_R1_DIRTY( overlay.blue, amountOfOverlay); + + cleanup_R1(); + + return existing; +} + + + +void nblend( CRGB* existing, CRGB* overlay, uint16_t count, fract8 amountOfOverlay) +{ + for( uint16_t i = count; i; i--) { + nblend( *existing, *overlay, amountOfOverlay); + existing++; + overlay++; + } +} + +CRGB blend( const CRGB& p1, const CRGB& p2, fract8 amountOfP2 ) +{ + CRGB nu(p1); + nblend( nu, p2, amountOfP2); + return nu; +} + +CRGB* blend( const CRGB* src1, const CRGB* src2, CRGB* dest, uint16_t count, fract8 amountOfsrc2 ) +{ + for( uint16_t i = count; i; i--) { + dest[i] = blend(src1[i], src2[i], amountOfsrc2); + } + return dest; +} + + + // CRGB HeatColor( uint8_t temperature) // @@ -270,11 +448,14 @@ void UpscalePalette(const CRGBPalette16& srcpal16, CRGBPalette256& destpal256) } } +#if 0 +// replaced by PartyColors_p void SetupPartyColors(CRGBPalette16& pal) { fill_gradient( pal, 0, CHSV( HUE_PURPLE,255,255), 7, CHSV(HUE_YELLOW - 18,255,255), FORWARD_HUES); fill_gradient( pal, 8, CHSV( HUE_ORANGE,255,255), 15, CHSV(HUE_BLUE + 18,255,255), BACKWARD_HUES); } +#endif void fill_palette(CRGB* L, uint16_t N, uint8_t startIndex, uint8_t incIndex, const CRGBPalette16& pal, uint8_t brightness, TBlendType blendType) diff --git a/colorutils.h b/colorutils.h index 2925422b..c986838b 100644 --- a/colorutils.h +++ b/colorutils.h @@ -1,6 +1,8 @@ #ifndef __INC_COLORUTILS_H #define __INC_COLORUTILS_H +#include + #include "pixeltypes.h" @@ -15,7 +17,7 @@ void fill_rainbow( struct CRGB * pFirstLED, int numToFill, uint8_t deltahue = 5); -// fill_gradient - fill a range of LEDs with a smooth gradient +// fill_gradient - fill a range of LEDs with a smooth HSV gradient // between two specified HSV colors. // Since 'hue' is a value around a color wheel, // there are always two ways to sweep from one hue @@ -36,6 +38,33 @@ void fill_gradient( struct CRGB* leds, uint16_t endpos, CHSV endcolor, TGradientDirectionCode directionCode = SHORTEST_HUES ); +// Convenience functions to fill a range of leds[] with a +// two-color, three-color, or four-color gradient +void fill_gradient( struct CRGB* leds, uint16_t numLeds, + const CHSV& c1, const CHSV& c2, + TGradientDirectionCode directionCode = SHORTEST_HUES ); +void fill_gradient( struct CRGB* leds, uint16_t numLeds, + const CHSV& c1, const CHSV& c2, const CHSV& c3, + TGradientDirectionCode directionCode = SHORTEST_HUES ); +void fill_gradient( struct CRGB* leds, uint16_t numLeds, + const CHSV& c1, const CHSV& c2, const CHSV& c3, const CHSV& c4, + TGradientDirectionCode directionCode = SHORTEST_HUES ); + +// convenience synonym +#define fill_gradient_HSV fill_gradient + + +// fill_gradient_RGB - fill a range of LEDs with a smooth RGB gradient +// between two specified RGB colors. +// Unlike HSV, there is no 'color wheel' in RGB space, +// and therefore there's only one 'direction' for the +// gradient to go, and no 'direction code' is needed. +void fill_gradient_RGB( CRGB* leds, + uint16_t startpos, CRGB startcolor, + uint16_t endpos, CRGB endcolor ); +void fill_gradient_RGB( CRGB* leds, uint16_t numLeds, const CRGB& c1, const CRGB& c2); +void fill_gradient_RGB( CRGB* leds, uint16_t numLeds, const CRGB& c1, const CRGB& c2, const CRGB& c3); +void fill_gradient_RGB( CRGB* leds, uint16_t numLeds, const CRGB& c1, const CRGB& c2, const CRGB& c3, const CRGB& c4); // fadeLightBy and fade_video - reduce the brightness of an array @@ -65,6 +94,29 @@ void nscale8( CRGB* leds, uint16_t num_leds, uint8_t scale); +// Pixel blending +// +// blend - computes an RGB-blended some fraction of the way +// between two other RGB colors. +CRGB blend( const CRGB& p1, const CRGB& p2, fract8 amountOfP2 ); + +// blend - computes an RGB-blended array of colors, each +// a given fraction of the way between corresponding +// elements of two source arrays of colors. +// Useful for blending palettes. +CRGB* blend( const CRGB* src1, const CRGB* src2, CRGB* dest, + uint16_t count, fract8 amountOfsrc2 ); + +// nblend - destructively modifies one RGB color, blending +// in a given fraction of an overlay RGB color +CRGB& nblend( CRGB& existing, const CRGB& overlay, fract8 amountOfOverlay ); + +// nblend - destructively blends a given fraction of +// a new RGB array into an existing RGB array +void nblend( CRGB* existing, CRGB* overlay, uint16_t count, fract8 amountOfOverlay); + + + // CRGB HeatColor( uint8_t temperature) // // Approximates a 'black body radiation' spectrum for @@ -200,6 +252,42 @@ public: { return &(entries[0]); } + + CRGBPalette16( const CHSV& c1) + { + fill_solid( &(entries[0]), 16, c1); + } + CRGBPalette16( const CHSV& c1, const CHSV& c2) + { + fill_gradient( &(entries[0]), 16, c1, c2); + } + CRGBPalette16( const CHSV& c1, const CHSV& c2, const CHSV& c3) + { + fill_gradient( &(entries[0]), 16, c1, c2, c3); + } + CRGBPalette16( const CHSV& c1, const CHSV& c2, const CHSV& c3, const CHSV& c4) + { + fill_gradient( &(entries[0]), 16, c1, c2, c3, c4); + } + + CRGBPalette16( const CRGB& c1) + { + fill_solid( &(entries[0]), 16, c1); + } + CRGBPalette16( const CRGB& c1, const CRGB& c2) + { + fill_gradient_RGB( &(entries[0]), 16, c1, c2); + } + CRGBPalette16( const CRGB& c1, const CRGB& c2, const CRGB& c3) + { + fill_gradient_RGB( &(entries[0]), 16, c1, c2, c3); + } + CRGBPalette16( const CRGB& c1, const CRGB& c2, const CRGB& c3, const CRGB& c4) + { + fill_gradient_RGB( &(entries[0]), 16, c1, c2, c3, c4); + } + + }; class CRGBPalette256 { @@ -270,6 +358,41 @@ public: { return &(entries[0]); } + + CRGBPalette256( const CHSV& c1) + { + fill_solid( &(entries[0]), 256, c1); + } + CRGBPalette256( const CHSV& c1, const CHSV& c2) + { + fill_gradient( &(entries[0]), 256, c1, c2); + } + CRGBPalette256( const CHSV& c1, const CHSV& c2, const CHSV& c3) + { + fill_gradient( &(entries[0]), 256, c1, c2, c3); + } + CRGBPalette256( const CHSV& c1, const CHSV& c2, const CHSV& c3, const CHSV& c4) + { + fill_gradient( &(entries[0]), 256, c1, c2, c3, c4); + } + + CRGBPalette256( const CRGB& c1) + { + fill_solid( &(entries[0]), 256, c1); + } + CRGBPalette256( const CRGB& c1, const CRGB& c2) + { + fill_gradient_RGB( &(entries[0]), 256, c1, c2); + } + CRGBPalette256( const CRGB& c1, const CRGB& c2, const CRGB& c3) + { + fill_gradient_RGB( &(entries[0]), 256, c1, c2, c3); + } + CRGBPalette256( const CRGB& c1, const CRGB& c2, const CRGB& c3, const CRGB& c4) + { + fill_gradient_RGB( &(entries[0]), 256, c1, c2, c3, c4); + } + }; typedef enum { NOBLEND=0, BLEND=1 } TBlendType; @@ -299,159 +422,5 @@ void fill_palette(CRGB* L, uint16_t N, TBlendType blendType=NOBLEND); -// Preset color schemes, such as they are. -const TProgmemPalette16 CloudColors_p PROGMEM = -{ - CRGB::Blue, - CRGB::DarkBlue, - CRGB::DarkBlue, - CRGB::DarkBlue, - - CRGB::DarkBlue, - CRGB::DarkBlue, - CRGB::DarkBlue, - CRGB::DarkBlue, - - CRGB::Blue, - CRGB::DarkBlue, - CRGB::SkyBlue, - CRGB::SkyBlue, - - CRGB::LightBlue, - CRGB::White, - CRGB::LightBlue, - CRGB::SkyBlue -}; - -const TProgmemPalette16 LavaColors_p PROGMEM = -{ - CRGB::Black, - CRGB::Maroon, - CRGB::Black, - CRGB::Maroon, - - CRGB::DarkRed, - CRGB::Maroon, - CRGB::DarkRed, - - CRGB::DarkRed, - CRGB::DarkRed, - CRGB::Red, - CRGB::Orange, - - CRGB::White, - CRGB::Orange, - CRGB::Red, - CRGB::DarkRed -}; - - -const TProgmemPalette16 OceanColors_p PROGMEM = -{ - CRGB::MidnightBlue, - CRGB::DarkBlue, - CRGB::MidnightBlue, - CRGB::Navy, - - CRGB::DarkBlue, - CRGB::MediumBlue, - CRGB::SeaGreen, - CRGB::Teal, - - CRGB::CadetBlue, - CRGB::Blue, - CRGB::DarkCyan, - CRGB::CornflowerBlue, - - CRGB::Aquamarine, - CRGB::SeaGreen, - CRGB::Aqua, - CRGB::LightSkyBlue -}; - -const TProgmemPalette16 ForestColors_p PROGMEM = -{ - CRGB::DarkGreen, - CRGB::DarkGreen, - CRGB::DarkOliveGreen, - CRGB::DarkGreen, - - CRGB::Green, - CRGB::ForestGreen, - CRGB::OliveDrab, - CRGB::Green, - - CRGB::SeaGreen, - CRGB::MediumAquamarine, - CRGB::LimeGreen, - CRGB::YellowGreen, - - CRGB::LightGreen, - CRGB::LawnGreen, - CRGB::MediumAquamarine, - CRGB::ForestGreen -}; - -const TProgmemPalette16 RainbowColors_p PROGMEM = -{ - 0xFF0000, - 0xD52A00, - 0xAB5500, - 0xAB7F00, - 0xABAB00, - 0x56D500, - 0x00FF00, - 0x00D52A, - 0x00AB55, - 0x0056AA, - 0x0000FF, - 0x2A00D5, - 0x5500AB, - 0x7F0081, - 0xAB0055, - 0xD5002B -}; - -#define RainbowStripesColors_p RainbowStripeColors_p -const TProgmemPalette16 RainbowStripeColors_p PROGMEM = -{ - 0xFF0000, - 0x000000, - 0xAB5500, - 0x000000, - 0xABAB00, - 0x000000, - 0x00FF00, - 0x000000, - 0x00AB55, - 0x000000, - 0x0000FF, - 0x000000, - 0x5500AB, - 0x000000, - 0xAB0055, - 0x000000 -}; - -const TProgmemPalette16 PartyColors_p PROGMEM = -{ - 0x5500AB, - 0x84007C, - 0xB5004B, - 0xE5001B, - 0xE81700, - 0xB84700, - 0xAB7700, - 0xABAB00, - 0xAB5500, - 0xDD2200, - 0xF2000E, - 0xC2003E, - 0x8F0071, - 0x5F00A1, - 0x2F00D0, - 0x0007F9, -}; - #endif -- cgit v1.2.3 From a4510921459622600253bd488aa6e25bff64c712 Mon Sep 17 00:00:00 2001 From: Mark Kriegsman Date: Fri, 27 Jun 2014 20:06:15 -0400 Subject: Adding Fire2012WithPalette example --- .../Fire2012WithPalette/Fire2012WithPalette.ino | 155 +++++++++++++++++++++ 1 file changed, 155 insertions(+) create mode 100644 examples/Fire2012WithPalette/Fire2012WithPalette.ino diff --git a/examples/Fire2012WithPalette/Fire2012WithPalette.ino b/examples/Fire2012WithPalette/Fire2012WithPalette.ino new file mode 100644 index 00000000..1208a589 --- /dev/null +++ b/examples/Fire2012WithPalette/Fire2012WithPalette.ino @@ -0,0 +1,155 @@ +#include + +#define LED_PIN 5 +#define COLOR_ORDER GRB +#define CHIPSET WS2811 +#define NUM_LEDS 30 + +#define BRIGHTNESS 200 +#define FRAMES_PER_SECOND 60 + +CRGB leds[NUM_LEDS]; + +// Fire2012 with programmable Color Palette +// +// This code is the same fire simulation as the original "Fire2012", +// but each heat cell's temperature is translated to color through a FastLED +// programmable color palette, instead of through the "HeatColor(...)" function. +// +// Four different static color palettes are provided here, plus one dynamic one. +// +// The three static ones are: +// 1. the FastLED built-in HeatColors_p -- this is the default, and it looks +// pretty much exactly like the original Fire2012. +// +// To use any of the other palettes below, just "uncomment" the corresponding code. +// +// 2. a gradient from black to red to yellow to white, which is +// visually similar to the HeatColors_p, and helps to illustrate +// what the 'heat colors' palette is actually doing, +// 3. a similar gradient, but in blue colors rather than red ones, +// i.e. from black to blue to aqua to white, which results in +// an "icy blue" fire effect, +// 4. a simplified three-step gradient, from black to red to white, just to show +// that these gradients need not have four components; two or +// three are possible, too, even if they don't look quite as nice for fire. +// +// The dynamic palette shows how you can change the basic 'hue' of the +// color palette every time through the loop, producing "rainbow fire". + +CRGBPalette16 gPal; + +void setup() { + delay(3000); // sanity delay + FastLED.addLeds(leds, NUM_LEDS).setCorrection( TypicalLEDStrip ); + FastLED.setBrightness( BRIGHTNESS ); + + // This first palette is the basic 'black body radiation' colors, + // which run from black to red to bright yellow to white. + gPal = HeatColors_p; + + // These are other ways to set up the color palette for the 'fire'. + // First, a gradient from black to red to yellow to white -- similar to HeatColors_p + // gPal = CRGBPalette16( CRGB::Black, CRGB::Red, CRGB::Yellow, CRGB::White); + + // Second, this palette is like the heat colors, but blue/aqua instead of red/yellow + // gPal = CRGBPalette16( CRGB::Black, CRGB::Blue, CRGB::Aqua, CRGB::White); + + // Third, here's a simpler, three-step gradient, from black to red to white + // gPal = CRGBPalette16( CRGB::Black, CRGB::Red, CRGB::White); + +} + +void loop() +{ + // Add entropy to random number generator; we use a lot of it. + random16_add_entropy( random()); + + // Fourth, the most sophisticated: this one sets up a new palette every + // time through the loop, based on a hue that changes every time. + // The palette is a gradient from black, to a dark color based on the hue, + // to a light color based on the hue, to white. + // + // static uint8_t hue = 0; + // hue++; + // CRGB darkcolor = CHSV(hue,255,192); // pure hue, three-quarters brightness + // CRGB lightcolor = CHSV(hue,128,255); // half 'whitened', full brightness + // gPal = CRGBPalette16( CRGB::Black, darkcolor, lightcolor, CRGB::White); + + + Fire2012WithPalette(); // run simulation frame, using palette colors + + FastLED.show(); // display this frame + FastLED.delay(1000 / FRAMES_PER_SECOND); +} + + +// Fire2012 by Mark Kriegsman, July 2012 +// as part of "Five Elements" shown here: http://youtu.be/knWiGsmgycY +//// +// This basic one-dimensional 'fire' simulation works roughly as follows: +// There's a underlying array of 'heat' cells, that model the temperature +// at each point along the line. Every cycle through the simulation, +// four steps are performed: +// 1) All cells cool down a little bit, losing heat to the air +// 2) The heat from each cell drifts 'up' and diffuses a little +// 3) Sometimes randomly new 'sparks' of heat are added at the bottom +// 4) The heat from each cell is rendered as a color into the leds array +// The heat-to-color mapping uses a black-body radiation approximation. +// +// Temperature is in arbitrary units from 0 (cold black) to 255 (white hot). +// +// This simulation scales it self a bit depending on NUM_LEDS; it should look +// "OK" on anywhere from 20 to 100 LEDs without too much tweaking. +// +// I recommend running this simulation at anywhere from 30-100 frames per second, +// meaning an interframe delay of about 10-35 milliseconds. +// +// Looks best on a high-density LED setup (60+ pixels/meter). +// +// +// There are two main parameters you can play with to control the look and +// feel of your fire: COOLING (used in step 1 above), and SPARKING (used +// in step 3 above). +// +// COOLING: How much does the air cool as it rises? +// Less cooling = taller flames. More cooling = shorter flames. +// Default 55, suggested range 20-100 +#define COOLING 55 + +// SPARKING: What chance (out of 255) is there that a new spark will be lit? +// Higher chance = more roaring fire. Lower chance = more flickery fire. +// Default 120, suggested range 50-200. +#define SPARKING 120 + + +void Fire2012WithPalette() +{ +// Array of temperature readings at each simulation cell + static byte heat[NUM_LEDS]; + + // Step 1. Cool down every cell a little + for( int i = 0; i < NUM_LEDS; i++) { + heat[i] = qsub8( heat[i], random8(0, ((COOLING * 10) / NUM_LEDS) + 2)); + } + + // Step 2. Heat from each cell drifts 'up' and diffuses a little + for( int k= NUM_LEDS - 3; k > 0; k--) { + heat[k] = (heat[k - 1] + heat[k - 2] + heat[k - 2] ) / 3; + } + + // Step 3. Randomly ignite new 'sparks' of heat near the bottom + if( random8() < SPARKING ) { + int y = random8(7); + heat[y] = qadd8( heat[y], random8(160,255) ); + } + + // Step 4. Map from heat cells to LED colors + for( int j = 0; j < NUM_LEDS; j++) { + // Scale the heat value from 0-255 down to 0-240 + // for best results with color palettes. + byte colorindex = scale8( heat[j], 240); + leds[j] = ColorFromPalette( gPal, colorindex); + } +} + -- cgit v1.2.3 From 0dca886b6465a257ac698659875ecb565a9425c1 Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Sun, 29 Jun 2014 11:59:41 -0700 Subject: Add APA102 support --- FastLED.h | 10 +++++--- chipsets.h | 81 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 88 insertions(+), 3 deletions(-) diff --git a/FastLED.h b/FastLED.h index a305762b..a3e8e047 100644 --- a/FastLED.h +++ b/FastLED.h @@ -24,7 +24,8 @@ enum ESPIChipsets { WS2801, WS2803, SM16716, - P9813 + P9813, + APA102 }; enum EClocklessChipsets { @@ -90,6 +91,7 @@ public: case WS2803: { static WS2803Controller c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); } case SM16716: { static SM16716Controller c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); } case P9813: { static P9813Controller c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); } + case APA102: { static APA102Controller c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); } } } @@ -100,6 +102,7 @@ public: case WS2803: { static WS2803Controller c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); } case SM16716: { static SM16716Controller c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); } case P9813: { static P9813Controller c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); } + case APA102: { static APA102Controller c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); } } } @@ -110,6 +113,7 @@ public: case WS2803: { static WS2803Controller c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); } case SM16716: { static SM16716Controller c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); } case P9813: { static P9813Controller c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); } + case APA102: { static APA102Controller c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); } } } @@ -208,10 +212,10 @@ public: CLEDController & operator[](int x); // Convenience functions for single-strip setups: - + // returns the number of LEDs in the first strip int size() { return (*this)[0].size(); } - + // returns pointer to the CRGB buffer for the first strip CRGB *leds() { return (*this)[0].leds(); } }; diff --git a/chipsets.h b/chipsets.h index 6409bcc2..8510d10c 100644 --- a/chipsets.h +++ b/chipsets.h @@ -119,6 +119,86 @@ public: template class WS2803Controller : public WS2801Controller {}; +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// +// APA102 definition - takes data/clock/select pin values (N.B. should take an SPI definition?) +// +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +template +class APA102Controller : public CLEDController { + typedef SPIOutput SPI; + SPI mSPI; + + void writeBoundary() { mSPI.writeWord(0); mSPI.writeWord(0); } + + inline void writeLed(uint8_t r, uint8_t g, uint8_t b) __attribute__((always_inline)) { + mSPI.writeByte(0xFF); mSPI.writeByte(r); mSPI.writeByte(g); mSPI.writeByte(b); + } + +public: + APA102Controller() {} + + virtual void init() { + mSPI.init(); + } + + virtual void clearLeds(int nLeds) { + showColor(CRGB(0,0,0), nLeds, CRGB(0,0,0)); + } + + virtual void showColor(const struct CRGB & data, int nLeds, CRGB scale) { + PixelController pixels(data, nLeds, scale, getDither()); + + mSPI.select(); + + writeBoundary(); + while(nLeds--) { + writeLed(pixels.loadAndScale0(), pixels.loadAndScale1(), pixels.loadAndScale2()); + pixels.stepDithering(); + } + writeBoundary(); + + mSPI.waitFully(); + mSPI.release(); + } + + virtual void show(const struct CRGB *data, int nLeds, CRGB scale) { + PixelController pixels(data, nLeds, scale, getDither()); + + mSPI.select(); + + writeBoundary(); + for(int i = 0; i < nLeds; i++) { + writeLed(pixels.loadAndScale0(), pixels.loadAndScale1(), pixels.loadAndScale2()); + pixels.advanceData(); + pixels.stepDithering(); + } + writeBoundary(); + + mSPI.release(); + } + +#ifdef SUPPORT_ARGB + virtual void show(const struct CRGB *data, int nLeds, CRGB scale) { + PixelController pixels(data, nLeds,, scale, getDither()); + + mSPI.select(); + + writeBoundary(); + for(int i = 0; i < nLeds; i++) { + writeLed(pixels.loadAndScale0(), pixels.loadAndScale1(), pixels.loadAndScale2()); + pixels.advanceData(); + pixels.stepDithering(); + } + writeBoundary(); + + mSPI.release(); + } +#endif +}; + + ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // P9813 definition - takes data/clock/select pin values (N.B. should take an SPI definition?) @@ -199,6 +279,7 @@ public: #endif }; + ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // SM16716 definition - takes data/clock/select pin values (N.B. should take an SPI definition?) -- cgit v1.2.3 From 8faf072f4f9d28c919aece88315e9dbfe8eb5d86 Mon Sep 17 00:00:00 2001 From: PaulStoffregen Date: Fri, 4 Jul 2014 00:45:10 -0700 Subject: Fix for renamed KINETISK_SPI_t typedef in Teensyduino 1.20 --- fastspi_arm_k20.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/fastspi_arm_k20.h b/fastspi_arm_k20.h index 593ed76a..7e938d54 100644 --- a/fastspi_arm_k20.h +++ b/fastspi_arm_k20.h @@ -4,6 +4,11 @@ #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 SPI_PUSHR_CONT #define SPI_PUSHR_CONT SPIX.PUSHR_CONT #define SPI_PUSHR_CTAS(X) SPIX.PUSHR_CTAS(X) -- cgit v1.2.3 From 7563f35a427ef17153bfbfcbb1d90ef549e46a78 Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Tue, 8 Jul 2014 17:35:19 -0700 Subject: Adding frame end packet to APA102 support. --- chipsets.h | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/chipsets.h b/chipsets.h index 8510d10c..19d37d09 100644 --- a/chipsets.h +++ b/chipsets.h @@ -130,7 +130,8 @@ class APA102Controller : public CLEDController { typedef SPIOutput SPI; SPI mSPI; - void writeBoundary() { mSPI.writeWord(0); mSPI.writeWord(0); } + void startBoundary() { mSPI.writeWord(0); mSPI.writeWord(0); } + void endBoundary() { mSPI.writeWord(0xFFFF); mSPI.writeWord(0xFFFF); } inline void writeLed(uint8_t r, uint8_t g, uint8_t b) __attribute__((always_inline)) { mSPI.writeByte(0xFF); mSPI.writeByte(r); mSPI.writeByte(g); mSPI.writeByte(b); @@ -152,12 +153,12 @@ public: mSPI.select(); - writeBoundary(); + startBoundary(); while(nLeds--) { writeLed(pixels.loadAndScale0(), pixels.loadAndScale1(), pixels.loadAndScale2()); pixels.stepDithering(); } - writeBoundary(); + endBoundary(); mSPI.waitFully(); mSPI.release(); @@ -168,13 +169,13 @@ public: mSPI.select(); - writeBoundary(); + startBoundary(); for(int i = 0; i < nLeds; i++) { writeLed(pixels.loadAndScale0(), pixels.loadAndScale1(), pixels.loadAndScale2()); pixels.advanceData(); pixels.stepDithering(); } - writeBoundary(); + endBoundary(); mSPI.release(); } @@ -185,13 +186,13 @@ public: mSPI.select(); - writeBoundary(); + startBoundary(); for(int i = 0; i < nLeds; i++) { writeLed(pixels.loadAndScale0(), pixels.loadAndScale1(), pixels.loadAndScale2()); pixels.advanceData(); pixels.stepDithering(); } - writeBoundary(); + endBoundary(); mSPI.release(); } -- cgit v1.2.3 From 76840c0dfb92a8ce783abb87fbfe565f9dda26c5 Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Thu, 10 Jul 2014 11:53:58 -0700 Subject: Fix compile errors for arduino 1.5.7 - no testing done yet. Issue #67 --- FastLED.h | 2 ++ colorutils.cpp | 2 ++ noise.cpp | 2 +- 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/FastLED.h b/FastLED.h index b3e7b2dc..749ea9f2 100644 --- a/FastLED.h +++ b/FastLED.h @@ -7,6 +7,8 @@ #define xstr(s) str(s) #define str(s) #s #define FASTLED_VERSION 2001000 +#define __PROG_TYPES_COMPAT__ + #include "controller.h" #include "fastpin.h" diff --git a/colorutils.cpp b/colorutils.cpp index a967aa17..ccaa646f 100644 --- a/colorutils.cpp +++ b/colorutils.cpp @@ -1,3 +1,5 @@ +#define __PROG_TYPES_COMPAT__ + #include #include "hsv2rgb.h" diff --git a/noise.cpp b/noise.cpp index 3b0dc599..f0551c2e 100644 --- a/noise.cpp +++ b/noise.cpp @@ -13,7 +13,7 @@ #define P(x) p[(x)] #endif -FL_PROGMEM static uint8_t p[] = { 151,160,137,91,90,15, +FL_PROGMEM static uint8_t const p[] = { 151,160,137,91,90,15, 131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,99,37,240,21,10,23, 190, 6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,11,32,57,177,33, 88,237,149,56,87,174,20,125,136,171,168, 68,175,74,165,71,134,139,48,27,166, -- cgit v1.2.3 From 7d8fae07e35fac4d5fd4f5497f0e49c2587fd3a2 Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Tue, 5 Aug 2014 02:46:33 -0700 Subject: Adding support for the smart matrix panel/library. --- FastLED.cpp | 12 ++++++---- FastLED.h | 17 ++++++++++++- pixeltypes.h | 10 ++++++++ smartmatrix_t3.h | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 107 insertions(+), 5 deletions(-) create mode 100644 smartmatrix_t3.h diff --git a/FastLED.cpp b/FastLED.cpp index ab182d06..990085a6 100644 --- a/FastLED.cpp +++ b/FastLED.cpp @@ -4,6 +4,8 @@ volatile uint32_t fuckit; #endif +void *pSmartMatrix = NULL; + CFastLED LEDS; CFastLED & FastSPI_LED = LEDS; CFastLED & FastSPI_LED2 = LEDS; @@ -122,13 +124,15 @@ extern int noise_max; void CFastLED::countFPS(int nFrames) { if(Serial) { - static uint32_t br = 0; - static uint32_t lastframe = millis(); + static int br = 0; + static uint32_t lastframe = 0; // millis(); br++; if(br == nFrames) { - uint32_t now = millis() - lastframe; - uint32_t fps = (br * 1000) / now; + uint32_t now = millis(); + Serial.print(lastframe); Serial.print("ms and now it is "); Serial.print(now); Serial.println("ms"); + now -= lastframe; + uint32_t fps = (br * 1000) / now; /*Serial.print('('); Serial.print(noise_min); Serial.print(','); Serial.print(noise_max); Serial.print(") "); */ Serial.print(now); Serial.print("ms for "); Serial.print(br); Serial.print(" frames, aka "); Serial.print(fps); Serial.println(" fps. "); diff --git a/FastLED.h b/FastLED.h index 749ea9f2..24918e66 100644 --- a/FastLED.h +++ b/FastLED.h @@ -9,6 +9,9 @@ #define FASTLED_VERSION 2001000 #define __PROG_TYPES_COMPAT__ +#ifdef SmartMatrix_h +#include +#endif #include "controller.h" #include "fastpin.h" @@ -20,6 +23,7 @@ #include "colorpalettes.h" #include "chipsets.h" #include "dmx.h" +#include "smartmatrix_t3.h" #include "noise.h" enum ESPIChipsets { @@ -31,6 +35,8 @@ enum ESPIChipsets { APA102 }; +enum ESM { SmartMatrix }; + enum EClocklessChipsets { DMX // TM1809, @@ -87,7 +93,7 @@ public: static CLEDController &addLeds(CLEDController *pLed, struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0); - template static CLEDController &addLeds(const struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) { + template static CLEDController &addLeds(struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) { switch(CHIPSET) { case LPD8806: { static LPD8806Controller c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); } case WS2801: { static WS2801Controller c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); } @@ -153,6 +159,15 @@ public: return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); } +#ifdef SmartMatrix_h + template + static CLEDController &addLeds(struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) + { + switch(CHIPSET) { + case SmartMatrix: { static CSmartMatrixController controller; return addLeds(&controller, data, nLedsOrOffset, nLedsIfOffset); } + } + } +#endif #ifdef FASTSPI_USE_DMX_SIMPLE template diff --git a/pixeltypes.h b/pixeltypes.h index ae56c159..e112636b 100644 --- a/pixeltypes.h +++ b/pixeltypes.h @@ -398,6 +398,15 @@ struct CRGB { return retval; } +#ifdef SmartMatrix_h + operator rgb24() const { + rgb24 ret; + ret.red = r; + ret.green = g; + ret.blue = b; + return ret; + } +#endif inline uint8_t getLuma ( ) { //Y' = 0.2126 R' + 0.7152 G' + 0.0722 B' @@ -450,6 +459,7 @@ struct CRGB { return ret; } + typedef enum { AliceBlue=0xF0F8FF, Amethyst=0x9966CC, diff --git a/smartmatrix_t3.h b/smartmatrix_t3.h new file mode 100644 index 00000000..1af910c0 --- /dev/null +++ b/smartmatrix_t3.h @@ -0,0 +1,73 @@ +#ifndef __INC_SMARTMATRIX_T3_H +#define __INC_SMARTMATRIX_T3_H + +#ifdef SmartMatrix_h +#include + +extern SmartMatrix *pSmartMatrix; + +// note - dmx simple must be included before FastSPI for this code to be enabled +class CSmartMatrixController : public CLEDController { + 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; + } + + // clear out/zero out the given number of leds. + virtual void clearLeds(int nLeds) { + const rgb24 black = {0,0,0}; + matrix.fillScreen(black); + matrix.swapBuffers(); + } + + // set all the leds on the controller to a given color + virtual void showColor(const struct CRGB & data, int nLeds,CRGB scale) { + PixelController pixels(data, nLeds, scale, getDither()); + rgb24 *md = matrix.backBuffer(); + while(nLeds--) { + md->red = pixels.loadAndScale0(); + md->green = pixels.loadAndScale1(); + md->blue = pixels.loadAndScale2(); + md++; + pixels.stepDithering(); + } + matrix.swapBuffers(); + } + + // note that the uint8_ts will be in the order that you want them sent out to the device. + // nLeds is the number of RGB leds being written to + virtual void show(const struct CRGB *data, int nLeds, CRGB scale) { + PixelController pixels(data, nLeds, scale, getDither()); + rgb24 *md = matrix.getRealBackBuffer(); + while(nLeds--) { + md->red = pixels.loadAndScale0(); + md->green = pixels.loadAndScale1(); + md->blue = pixels.loadAndScale2(); + md++; + pixels.advanceData(); + pixels.stepDithering(); + } + matrix.swapBuffers(); + matrix.setBackBuffer((rgb24*)data); + } + +#ifdef SUPPORT_ARGB + // as above, but every 4th uint8_t is assumed to be alpha channel data, and will be skipped + virtual void show(const struct CARGB *data, int nLeds, CRGB scale) = 0; +#endif +}; + +#endif + +#endif -- cgit v1.2.3 From 4a21223dc36253f7e798bd6ed9036e46edd1ad6f Mon Sep 17 00:00:00 2001 From: Mark Kriegsman Date: Tue, 5 Aug 2014 14:16:00 -0400 Subject: Adding power management code, with global interfaces ONLY at this point. --- FastLED.h | 1 + power_mgt.cpp | 144 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ power_mgt.h | 48 ++++++++++++++++++++ 3 files changed, 193 insertions(+) create mode 100644 power_mgt.cpp create mode 100644 power_mgt.h diff --git a/FastLED.h b/FastLED.h index 749ea9f2..8e59c792 100644 --- a/FastLED.h +++ b/FastLED.h @@ -21,6 +21,7 @@ #include "chipsets.h" #include "dmx.h" #include "noise.h" +#include "power_mgt.h" enum ESPIChipsets { LPD8806, diff --git a/power_mgt.cpp b/power_mgt.cpp new file mode 100644 index 00000000..edfb568d --- /dev/null +++ b/power_mgt.cpp @@ -0,0 +1,144 @@ +#include "FastLED.h" +#include "power_mgt.h" + +//// POWER MANAGEMENT + +// These power usage values were arrived at by actually measuing the power +// draw of a number of different LED strips, and a bunch of closed-loop-feedback +// testing to make sure that if we USE these values, we stay at or under +// the target power consumption. +// Actual power consumption is much, much more complicated and has +// to include things like voltage drop, etc., etc. +// However, this is good enough for most cases, and almost certainly better +// than no power management at all. +// You're welcome to adjust these values as needed; there may eventually be an API +// for changing these on the fly, but it saves codespace and RAM to have them +// be compile-time constants. +static const uint8_t gRed_mW = 16 * 5; // 16mA @ 5v +static const uint8_t gGreen_mW = 14 * 5; // 14mA @ 5v +static const uint8_t gBlue_mW = 14 * 5; // 14mA @ 5v +static const uint8_t gDark_mW = 1 * 5; // 1mA @ 5v + +// Power consumed by the MCU +static const uint8_t gMCU_mW = 25 * 5; // 25mA @ 5v + + +uint32_t gMaxPowerInMilliwatts = (uint32_t)(400) * (uint32_t)(5); // 400mA @ 5v default to avoid USB bricking +uint8_t gMaxPowerIndicatorLEDPinNumber = 13; // default = Arduino onboard LED pin. set to zero to skip this. + + + +uint32_t calculate_unscaled_power_mW( const CRGB* ledbuffer, uint16_t numLeds ) +{ + uint32_t red32 = 0, green32 = 0, blue32 = 0; + const CRGB* firstled = &(ledbuffer[0]); + uint8_t* p = (uint8_t*)(firstled); + + uint16_t count = numLeds; + + for( byte loop256 = (count >> 8) + 1; loop256; loop256--) { + uint16_t red16 = 0, green16 = 0, blue16 = 0; + while( count) { + red16 += *p++; + green16 += *p++; + blue16 += *p++; + count--; + } + red32 += red16; + green32 += green16; + blue32 += blue16; + } + + red32 *= gRed_mW; + green32 *= gGreen_mW; + blue32 *= gBlue_mW; + + red32 >>= 8; + green32 >>= 8; + blue32 >>= 8; + + uint32_t total = red32 + green32 + blue32 + (gDark_mW * numLeds); + + return total; +} + + + +#define POWER_LED 1 + +// sets brightness to +// - no more than target_brightness +// - no more than max_mW milliwatts +uint8_t calculate_max_brightness_for_power_mW( uint8_t target_brightness, uint32_t max_power_mW) +{ + uint32_t total_mW = gMCU_mW; + + CLEDController *pCur = CLEDController::head(); + while(pCur) { + total_mW += calculate_unscaled_power_mW( pCur->leds(), pCur->size()); + pCur = pCur->next(); + } + + uint32_t requested_power_mW = ((uint32_t)total_mW * target_brightness) / 256; + //Serial.print("requested scaled power mW = "); + //Serial.println( requested_power_mW); + //Serial.print("max power mW = "); + //Serial.println( max_power_mW); + + if( requested_power_mW < max_power_mW) { +#if POWER_LED > 0 + if( gMaxPowerIndicatorLEDPinNumber ) { + digitalWrite(gMaxPowerIndicatorLEDPinNumber, LOW); // turn the LED off + } +#endif + return target_brightness; + } + + uint8_t recommended_brightness = (uint32_t)((uint8_t)(target_brightness) * (uint32_t)(max_power_mW)) / ((uint32_t)(requested_power_mW)); + //Serial.print("recommended brightness = "); + //Serial.println( recommended_brightness); +#if POWER_LED > 0 + if( gMaxPowerIndicatorLEDPinNumber ) { + digitalWrite( gMaxPowerIndicatorLEDPinNumber, HIGH); // turn the LED on + } +#endif + + return recommended_brightness; +} + + +void set_max_power_indicator_LED( uint8_t pinNumber) +{ + gMaxPowerIndicatorLEDPinNumber = pinNumber; +} + +void set_max_power_in_volts_and_milliamps( uint8_t volts, uint32_t milliamps) +{ + gMaxPowerInMilliwatts = (uint32_t)((uint32_t)(volts) * milliamps); +} + +void set_max_power_in_milliwatts( uint32_t powerInmW) +{ + gMaxPowerInMilliwatts = powerInmW; +} + +void show_at_max_brightness_for_power() +{ + uint8_t targetBrightness = FastLED.getBrightness(); + uint8_t max = calculate_max_brightness_for_power_mW( targetBrightness, gMaxPowerInMilliwatts); + + FastLED.setBrightness( max ); + FastLED.show(); + FastLED.setBrightness( targetBrightness ); +} + +void delay_at_max_brightness_for_power( uint16_t ms) +{ + uint8_t targetBrightness = FastLED.getBrightness(); + uint8_t max = calculate_max_brightness_for_power_mW( targetBrightness, gMaxPowerInMilliwatts); + + FastLED.setBrightness( max ); + FastLED.delay( ms); + FastLED.setBrightness( targetBrightness ); +} + diff --git a/power_mgt.h b/power_mgt.h new file mode 100644 index 00000000..60b92e95 --- /dev/null +++ b/power_mgt.h @@ -0,0 +1,48 @@ +#ifndef POWER_MGT_H +#define POWER_MGT_H + +#include "pixeltypes.h" + +// Power Control setup functions +// +// Example: +// set_max_power_in_volts_and_milliamps( 5, 400); +// +void set_max_power_in_volts_and_milliamps( uint8_t volts, uint32_t milliamps); +void set_max_power_in_milliwatts( uint32_t powerInmW); + +void set_max_power_indicator_LED( uint8_t pinNumber); // zero = no indicator LED + + +// Power Control 'show' and 'delay' functions +// +// These are drop-in replacements for FastLED.show() and FastLED.delay() +// In order to use these, you have to actually replace your calls to +// FastLED.show() and FastLED.delay() with these two functions. +// +// Example: +// // was: FastLED.show(); +// // now is: +// show_at_max_brightness_for_power(); +// +void show_at_max_brightness_for_power(); +void delay_at_max_brightness_for_power( uint16_t ms); + + +// Power Control internal helper functions +// +// calculate_unscaled_power_mW tells you how many milliwatts the current +// LED data would draw at brightness = 255. +// +// calculate_max_brightness_for_power_mW tells you the highest brightness +// level you can use and still stay under the specified power budget. It +// takes a 'target brightness' which is the brightness you'd ideally like +// to use. The result from this function will be no higher than the +// target_brightess you supply, but may be lower. +uint32_t calculate_unscaled_power_mW( const CRGB* ledbuffer, uint16_t numLeds); + +uint8_t calculate_max_brightness_for_power_mW( uint8_t target_brightness, uint32_t max_power_mW); + + +// POWER_MGT_H +#endif -- cgit v1.2.3 From 882b928222a246882893530f830eb758664b1119 Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Wed, 6 Aug 2014 10:58:27 -0700 Subject: tweak arm timing adjustment --- clockless_arm_k20.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/clockless_arm_k20.h b/clockless_arm_k20.h index 83080db9..73dcd699 100644 --- a/clockless_arm_k20.h +++ b/clockless_arm_k20.h @@ -34,7 +34,7 @@ public: // Adjust the timer long microsTaken = CLKS_TO_MICROS(clocks); - MS_COUNTER += (microsTaken / 1000); + MS_COUNTER += (1 + (microsTaken / 1000)); sei(); mWait.mark(); } @@ -49,7 +49,7 @@ public: // Adjust the timer long microsTaken = CLKS_TO_MICROS(clocks); - MS_COUNTER += (microsTaken / 1000); + MS_COUNTER += (1 + (microsTaken / 1000)); sei(); mWait.mark(); } @@ -65,7 +65,7 @@ public: // Adjust the timer long microsTaken = CLKS_TO_MICROS(clocks); - MS_COUNTER += (microsTaken / 1000); + MS_COUNTER += (1 + (microsTaken / 1000)); sei(); mWait.mark(); } -- cgit v1.2.3 From 50c5d106ae7a8c2e610e9aa7544ed1946c02ba58 Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Wed, 6 Aug 2014 10:59:34 -0700 Subject: Make smart matrix code work with either original library or modified fork --- smartmatrix_t3.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/smartmatrix_t3.h b/smartmatrix_t3.h index 1af910c0..ba77d149 100644 --- a/smartmatrix_t3.h +++ b/smartmatrix_t3.h @@ -49,7 +49,11 @@ public: // nLeds is the number of RGB leds being written to virtual void show(const struct CRGB *data, int nLeds, CRGB scale) { PixelController pixels(data, nLeds, scale, getDither()); +#ifdef SMART_MATRIX_CAN_TRIPLE_BUFFER rgb24 *md = matrix.getRealBackBuffer(); +#else + rgb24 *md = matrix.backBuffer(); +#endif while(nLeds--) { md->red = pixels.loadAndScale0(); md->green = pixels.loadAndScale1(); @@ -59,7 +63,9 @@ public: pixels.stepDithering(); } matrix.swapBuffers(); +#ifdef SMART_MATRIX_CAN_TRIPLE_BUFFER matrix.setBackBuffer((rgb24*)data); +#endif } #ifdef SUPPORT_ARGB -- cgit v1.2.3 From ec4b5232f29732834580230d2162ac90e793c106 Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Wed, 6 Aug 2014 11:06:53 -0700 Subject: Fix type casting in CLKS_TO_MICROS. --- delay.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/delay.h b/delay.h index 0eeda245..05313127 100644 --- a/delay.h +++ b/delay.h @@ -103,7 +103,7 @@ template<> __attribute__((always_inline)) inline void delaycycles<5>() {NOP2;NOP // #define NS(_NS) (_NS / (1000 / (F_CPU / 1000000L))) #if 1 || (F_CPU < 96000000) #define NS(_NS) ( (_NS * (F_CPU / 1000000L))) / 1000 -#define CLKS_TO_MICROS(_CLKS) ((_CLKS)) / (F_CPU / 1000000L) +#define CLKS_TO_MICROS(_CLKS) ((long)(_CLKS)) / (F_CPU / 1000000L) #else #define NS(_NS) ( (_NS * (F_CPU / 2000000L))) / 1000 #define CLKS_TO_MICROS(_CLKS) ((long)(_CLKS)) / (F_CPU / 2000000L) -- cgit v1.2.3 From 124e63aeed6a3d8c60c769562bc51c51830f106a Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Wed, 6 Aug 2014 11:09:07 -0700 Subject: Update README to alert about arduino 1.5.7 bug. --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 2648b3cf..1c4f7c14 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,9 @@ FastLED ======= +IMPORTANT NOTE: If you are building for AVR based systems, please do not use any version of the arduino +IDE after 1.5.7 yet. It messes with some of the asm output which will cause you problems. + This is a library for easily & efficiently controlling a wide variety of LED chipsets, like the ones sold by adafruit (Neopixel, LPD8806), Sparkfun (WS2801), and aliexpress. In addition to writing to the leds, this library also includes a number of functions for high-performing 8bit math for manipulating -- cgit v1.2.3 From 90c0ce95605647e755de23b3079a16c11e610bd5 Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Wed, 6 Aug 2014 11:24:39 -0700 Subject: Adding SmartMatrix example --- examples/SmartMatrix/SmartMatrix.ino | 122 +++++++++++++++++++++++++++++++++++ 1 file changed, 122 insertions(+) create mode 100644 examples/SmartMatrix/SmartMatrix.ino diff --git a/examples/SmartMatrix/SmartMatrix.ino b/examples/SmartMatrix/SmartMatrix.ino new file mode 100644 index 00000000..56f1c32e --- /dev/null +++ b/examples/SmartMatrix/SmartMatrix.ino @@ -0,0 +1,122 @@ +#include +#include + +#define kMatrixWidth 32 +#define kMatrixHeight 32 +const bool kMatrixSerpentineLayout = false; + +#define NUM_LEDS (kMatrixWidth * kMatrixHeight) + +CRGB leds[kMatrixWidth * kMatrixHeight]; + + +uint16_t XY( uint8_t x, uint8_t y) +{ + uint16_t i; + + if( kMatrixSerpentineLayout == false) { + i = (y * kMatrixWidth) + x; + } + + if( kMatrixSerpentineLayout == true) { + if( y & 0x01) { + // Odd rows run backwards + uint8_t reverseX = (kMatrixWidth - 1) - x; + i = (y * kMatrixWidth) + reverseX; + } else { + // Even rows run forwards + i = (y * kMatrixWidth) + x; + } + } + + return i; +} + +// The 32bit version of our coordinates +static uint16_t x; +static uint16_t y; +static uint16_t z; + +// We're using the x/y dimensions to map to the x/y pixels on the matrix. We'll +// use the z-axis for "time". speed determines how fast time moves forward. Try +// 1 for a very slow moving effect, or 60 for something that ends up looking like +// water. +// uint16_t speed = 1; // almost looks like a painting, moves very slowly +uint16_t speed = 20; // a nice starting speed, mixes well with a scale of 100 +// uint16_t speed = 33; +// uint16_t speed = 100; // wicked fast! + +// Scale determines how far apart the pixels in our noise matrix are. Try +// changing these values around to see how it affects the motion of the display. The +// higher the value of scale, the more "zoomed out" the noise iwll be. A value +// of 1 will be so zoomed in, you'll mostly see solid colors. + +// uint16_t scale = 1; // mostly just solid colors +// uint16_t scale = 4011; // very zoomed out and shimmery +uint16_t scale = 31; + +// This is the array that we keep our computed noise values in +uint8_t noise[kMatrixWidth][kMatrixHeight]; + +void setup() { + // uncomment the following lines if you want to see FPS count information + // Serial.begin(38400); + // Serial.println("resetting!"); + delay(3000); + LEDS.addLeds(leds,NUM_LEDS); + LEDS.setBrightness(96); + + // Initialize our coordinates to some random values + x = random16(); + y = random16(); + z = random16(); + + // Show off smart matrix scrolling text + pSmartMatrix->setScrollMode(wrapForward); + pSmartMatrix->setScrollColor({0xff, 0xff, 0xff}); + pSmartMatrix->setScrollSpeed(15); + pSmartMatrix->setScrollFont(font6x10); + pSmartMatrix->scrollText("Smart Matrix & FastLED", -1); + pSmartMatrix->setScrollOffsetFromEdge(10); +} + +// Fill the x/y array of 8-bit noise values using the inoise8 function. +void fillnoise8() { + for(int i = 0; i < kMatrixWidth; i++) { + int ioffset = scale * i; + for(int j = 0; j < kMatrixHeight; j++) { + int joffset = scale * j; + noise[i][j] = inoise8(x + ioffset,y + joffset,z); + } + } + z += speed; +} + + +void loop() { + static uint8_t circlex = 0; + static uint8_t circley = 0; + + static uint8_t ihue=0; + fillnoise8(); + for(int i = 0; i < kMatrixWidth; i++) { + for(int j = 0; j < kMatrixHeight; j++) { + // We use the value at the (i,j) coordinate in the noise + // array for our brightness, and the flipped value from (j,i) + // for our pixel's hue. + leds[XY(i,j)] = CHSV(noise[j][i],255,noise[i][j]); + + // You can also explore other ways to constrain the hue used, like below + // leds[XY(i,j)] = CHSV(ihue + (noise[j][i]>>2),255,noise[i][j]); + } + } + ihue+=1; + + // N.B. this requires SmartMatrix modified w/triple buffering support + pSmartMatrix->fillCircle(circlex % 32,circley % 32,6,CRGB(CHSV(ihue+128,255,255))); + circlex += random16(2); + circley += random16(2); + LEDS.show(); + LEDS.countFPS(); + // delay(10); +} -- cgit v1.2.3 From e3b42e174be2d65cc303a967c256a336f4f50110 Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Wed, 6 Aug 2014 11:30:51 -0700 Subject: Updating readme --- README.md | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 1c4f7c14..0cd2eeb3 100644 --- a/README.md +++ b/README.md @@ -43,10 +43,15 @@ Here's a list of all the LED chipsets are supported. More details on the led ch * TM1809/4 - 3 wire chipset, cheaply available on aliexpress.com * TM1803 - 3 wire chipset, sold by radio shack * UCS1903 - another 3 wire led chipset, cheap +* GW6205 - another 3 wire led chipset * LPD8806 - SPI based chpiset, very high speed * WS2801 - SPI based chipset, cheap and widely available * SM16716 - SPI based chipset +* APA102 - SPI based chipset +* P9813 - aka Cool Neon's Total Control Lighting * DMX - send rgb data out over DMX using arduino DMX libraries +* SmartMatrix panels - needs the SmartMatrix library - https://github.com/pixelmatix/SmartMatrix + LPD6803, HL1606, and "595"-style shift registers are no longer supported by the library. The older Version 1 of the library ("FastSPI_LED") has support for these, but is missing many of the advanced features of current versions and is no longer being maintained. @@ -56,9 +61,10 @@ LPD6803, HL1606, and "595"-style shift registers are no longer supported by the Right now the library is supported on a variety of arduino compatable platforms. If it's ARM or AVR and uses the arduino software (or a modified version of it to build) then it is likely supported. Note that we have a long list of upcoming platforms to support, so if you don't see what you're looking for here, ask, it may be on the roadmap (or may already be supported). N.B. at the moment we are only supporting the stock compilers that ship with the arduino software. Support for upgraded compilers, as well as using AVR studio and skipping the arduino entirely, should be coming in a near future release. * Arduino & compatibles - straight up arduino devices, uno, duo, leonardo, mega, nano, etc... -* Teensy 2, Teensy++ 2, Teensy 3 - arduino compataible from pjrc.com with some extra goodies (note the teensy 3 is ARM, not AVR!) +* Teensy 2, Teensy++ 2, Teensy 3.1 - arduino compataible from pjrc.com with some extra goodies (note the teensy 3 is ARM, not AVR!) +* Arduino Due and the digistump DigiX -What types of platforms are we thinking about supporting in the future? Here's a short list: Arduino Due, MSP430, ChipKit32, Maple, Beagleboard +What types of platforms are we thinking about supporting in the future? Here's a short list: , MSP430, ChipKit32, Maple, Beagleboard ## What about that name? -- cgit v1.2.3 From 608f9b62d115ed4f1f28a8704d756f6b5337e48d Mon Sep 17 00:00:00 2001 From: Mark Kriegsman Date: Thu, 7 Aug 2014 18:03:21 -0400 Subject: Fixed overflow, added debug option, adjusted constants a bit. --- power_mgt.cpp | 94 +++++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 63 insertions(+), 31 deletions(-) diff --git a/power_mgt.cpp b/power_mgt.cpp index edfb568d..336430fd 100644 --- a/power_mgt.cpp +++ b/power_mgt.cpp @@ -3,32 +3,50 @@ //// POWER MANAGEMENT -// These power usage values were arrived at by actually measuing the power -// draw of a number of different LED strips, and a bunch of closed-loop-feedback -// testing to make sure that if we USE these values, we stay at or under +// These power usage values are approximate, and your exact readings +// will be slightly (10%?) different from these. +// +// They were arrived at by actually measuing the power draw of a number +// of different LED strips, and a bunch of closed-loop-feedback testing +// to make sure that if we USE these values, we stay at or under // the target power consumption. // Actual power consumption is much, much more complicated and has // to include things like voltage drop, etc., etc. // However, this is good enough for most cases, and almost certainly better // than no power management at all. +// // You're welcome to adjust these values as needed; there may eventually be an API // for changing these on the fly, but it saves codespace and RAM to have them // be compile-time constants. -static const uint8_t gRed_mW = 16 * 5; // 16mA @ 5v -static const uint8_t gGreen_mW = 14 * 5; // 14mA @ 5v -static const uint8_t gBlue_mW = 14 * 5; // 14mA @ 5v -static const uint8_t gDark_mW = 1 * 5; // 1mA @ 5v -// Power consumed by the MCU -static const uint8_t gMCU_mW = 25 * 5; // 25mA @ 5v +static const uint8_t gRed_mW = 16 * 5; // 16mA @ 5v = 80mW +static const uint8_t gGreen_mW = 11 * 5; // 11mA @ 5v = 55mW +static const uint8_t gBlue_mW = 15 * 5; // 15mA @ 5v = 75mW +static const uint8_t gDark_mW = 1 * 5; // 1mA @ 5v = 5mW + +// Alternate calibration by RAtkins via pre-PSU wattage measurments; +// these are all probably about 20%-25% too high due to PSU heat losses, +// but if you're measuring wattage on the PSU input side, this may +// be a better set of calibrations. (WS2812B) +// static const uint8_t gRed_mW = 100; +// static const uint8_t gGreen_mW = 48; +// static const uint8_t gBlue_mW = 100; +// static const uint8_t gDark_mW = 12; + + +#define POWER_LED 1 +#define POWER_DEBUG_PRINT 0 -uint32_t gMaxPowerInMilliwatts = (uint32_t)(400) * (uint32_t)(5); // 400mA @ 5v default to avoid USB bricking -uint8_t gMaxPowerIndicatorLEDPinNumber = 13; // default = Arduino onboard LED pin. set to zero to skip this. +// Power consumed by the MCU +static const uint8_t gMCU_mW = 25 * 5; // 25mA @ 5v = 125 mW + +static uint32_t gMaxPowerInMilliwatts = (uint32_t)(400) * (uint32_t)(5); // 400mA @ 5v default to avoid USB bricking +static uint8_t gMaxPowerIndicatorLEDPinNumber = 13; // default = Arduino onboard LED pin. set to zero to skip this. -uint32_t calculate_unscaled_power_mW( const CRGB* ledbuffer, uint16_t numLeds ) +uint32_t calculate_unscaled_power_mW( const CRGB* ledbuffer, uint16_t numLeds ) //25354 { uint32_t red32 = 0, green32 = 0, blue32 = 0; const CRGB* firstled = &(ledbuffer[0]); @@ -36,17 +54,12 @@ uint32_t calculate_unscaled_power_mW( const CRGB* ledbuffer, uint16_t numLeds ) uint16_t count = numLeds; - for( byte loop256 = (count >> 8) + 1; loop256; loop256--) { - uint16_t red16 = 0, green16 = 0, blue16 = 0; - while( count) { - red16 += *p++; - green16 += *p++; - blue16 += *p++; - count--; - } - red32 += red16; - green32 += green16; - blue32 += blue16; + // This loop might benefit from an AVR assembly version -MEK + while( count) { + red32 += *p++; + green32 += *p++; + blue32 += *p++; + count--; } red32 *= gRed_mW; @@ -64,8 +77,6 @@ uint32_t calculate_unscaled_power_mW( const CRGB* ledbuffer, uint16_t numLeds ) -#define POWER_LED 1 - // sets brightness to // - no more than target_brightness // - no more than max_mW milliwatts @@ -79,24 +90,45 @@ uint8_t calculate_max_brightness_for_power_mW( uint8_t target_brightness, uint32 pCur = pCur->next(); } +#if POWER_DEBUG_PRINT == 1 + Serial.print("power demand at full brightness mW = "); + Serial.println( total_mW); +#endif + uint32_t requested_power_mW = ((uint32_t)total_mW * target_brightness) / 256; - //Serial.print("requested scaled power mW = "); - //Serial.println( requested_power_mW); - //Serial.print("max power mW = "); - //Serial.println( max_power_mW); +#if POWER_DEBUG_PRINT == 1 + if( target_brightness != 255 ) { + Serial.print("power demand at scaled brightness mW = "); + Serial.println( requested_power_mW); + } + Serial.print("power limit mW = "); + Serial.println( max_power_mW); +#endif if( requested_power_mW < max_power_mW) { #if POWER_LED > 0 if( gMaxPowerIndicatorLEDPinNumber ) { digitalWrite(gMaxPowerIndicatorLEDPinNumber, LOW); // turn the LED off } +#endif +#if POWER_DEBUG_PRINT == 1 + Serial.print("demand is under the limit"); #endif return target_brightness; } uint8_t recommended_brightness = (uint32_t)((uint8_t)(target_brightness) * (uint32_t)(max_power_mW)) / ((uint32_t)(requested_power_mW)); - //Serial.print("recommended brightness = "); - //Serial.println( recommended_brightness); +#if POWER_DEBUG_PRINT == 1 + Serial.print("recommended brightness # = "); + Serial.println( recommended_brightness); + + uint32_t resultant_power_mW = (total_mW * recommended_brightness) / 256; + Serial.print("resultant power demand mW = "); + Serial.println( resultant_power_mW); + + Serial.println(); +#endif + #if POWER_LED > 0 if( gMaxPowerIndicatorLEDPinNumber ) { digitalWrite( gMaxPowerIndicatorLEDPinNumber, HIGH); // turn the LED on -- cgit v1.2.3 From 7c1cb6f70f0b23d017f23da68bb291093f9154ad Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Sun, 17 Aug 2014 11:56:22 -0400 Subject: Make sure delay does the right thing, even when show is short enough to not cause millis to change - #71 --- FastLED.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FastLED.cpp b/FastLED.cpp index 990085a6..53a64898 100644 --- a/FastLED.cpp +++ b/FastLED.cpp @@ -90,7 +90,7 @@ void CFastLED::delay(unsigned long ms) { unsigned long start = millis(); while((millis()-start) < ms) { show(); - + delay(1); } } -- cgit v1.2.3 From 7e0503c8c4ae141d10a0f5c1fa0d16f7a2e084f0 Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Thu, 11 Sep 2014 09:17:52 -0700 Subject: Change enum to SMART_MATRIX --- FastLED.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/FastLED.h b/FastLED.h index aa2512ab..ff8300f8 100644 --- a/FastLED.h +++ b/FastLED.h @@ -36,7 +36,7 @@ enum ESPIChipsets { APA102 }; -enum ESM { SmartMatrix }; +enum ESM { SMART_MATRIX }; enum EClocklessChipsets { DMX @@ -165,7 +165,7 @@ public: static CLEDController &addLeds(struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) { switch(CHIPSET) { - case SmartMatrix: { static CSmartMatrixController controller; return addLeds(&controller, data, nLedsOrOffset, nLedsIfOffset); } + case SMART_MATRIX: { static CSmartMatrixController controller; return addLeds(&controller, data, nLedsOrOffset, nLedsIfOffset); } } } #endif -- cgit v1.2.3 From ac72ba9e91fcd65b8f8316fe55bd6177dbf1d768 Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Thu, 11 Sep 2014 09:43:56 -0700 Subject: fix smart matrix example --- examples/SmartMatrix/SmartMatrix.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/SmartMatrix/SmartMatrix.ino b/examples/SmartMatrix/SmartMatrix.ino index 56f1c32e..99d75a42 100644 --- a/examples/SmartMatrix/SmartMatrix.ino +++ b/examples/SmartMatrix/SmartMatrix.ino @@ -63,7 +63,7 @@ void setup() { // Serial.begin(38400); // Serial.println("resetting!"); delay(3000); - LEDS.addLeds(leds,NUM_LEDS); + LEDS.addLeds(leds,NUM_LEDS); LEDS.setBrightness(96); // Initialize our coordinates to some random values -- cgit v1.2.3 From 9b1388bbffc3d4ee5f644e2b139b1d177cb04250 Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Sun, 14 Sep 2014 12:21:43 -0700 Subject: Add ATmega1284 support --- fastpin_avr.h | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/fastpin_avr.h b/fastpin_avr.h index 2c6103a1..103498c2 100644 --- a/fastpin_avr.h +++ b/fastpin_avr.h @@ -81,6 +81,25 @@ _DEFPIN_AVR(16, 0x04, C); _DEFPIN_AVR(17, 0x08, C); _DEFPIN_AVR(18, 0x10, C); _D #define AVR_HARDWARE_SPI 1 #define HAS_HARDWARE_PIN_SUPPORT 1 +#elif defined(__AVR_ATmega1284P__) + +_IO(A); _IO(B); _IO(C); _IO(D); + +_DEFPIN_AVR(0, 1<<0, D); _DEFPIN_AVR(1, 1<<1, D); _DEFPIN_AVR(2, 1<<2, B); _DEFPIN_AVR(3, 1<<3, B); +_DEFPIN_AVR(4, 1<<0, B); _DEFPIN_AVR(5, 1<<1, B); _DEFPIN_AVR(6, 1<<2, D); _DEFPIN_AVR(7, 1<<3, D); +_DEFPIN_AVR(8, 1<<5, D); _DEFPIN_AVR(9, 1<<6, D); _DEFPIN_AVR(10, 1<<4, B); _DEFPIN_AVR(11, 1<<5, B); +_DEFPIN_AVR(12, 1<<6, B); _DEFPIN_AVR(13, 1<<7, B); _DEFPIN_AVR(14, 1<<7, A); _DEFPIN_AVR(15, 1<<6, A); +_DEFPIN_AVR(16, 1<<5, A); _DEFPIN_AVR(17, 1<<4, A); _DEFPIN_AVR(18, 1<<3, A); _DEFPIN_AVR(19, 1<<2, A); +_DEFPIN_AVR(20, 1<<1, A); _DEFPIN_AVR(21, 1<<0, A); _DEFPIN_AVR(22, 1<<0, C); _DEFPIN_AVR(23, 1<<1, C); +_DEFPIN_AVR(24, 1<<2, C); _DEFPIN_AVR(25, 1<<3, C); _DEFPIN_AVR(26, 1<<4, C); _DEFPIN_AVR(27, 1<<5, C); +_DEFPIN_AVR(28, 1<<6, C); _DEFPIN_AVR(29, 1<<7, C); _DEFPIN_AVR(30, 1<<4, D); _DEFPIN_AVR(31, 1<<7, D); + +#define SPI_DATA 11 +#define SPI_CLOCK 13 +#define SPI_SELECT 10 +#define AVR_HARDWARE_SPI 1 +#define HAS_HARDWARE_PIN_SUPPORT 1 + #elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) // megas -- cgit v1.2.3 From 0b27df9a2b844da20fcd67073a013e4bb2f4353e Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Sun, 14 Sep 2014 20:18:19 -0700 Subject: Shut up warnings about progmem and color palettes. Also, move the palette definitions out of a .h file and into a .cpp file (minimize duplicate constant creation that I don't always trust gcc to collapse down) --- colorpalettes.cpp | 164 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ colorpalettes.h | 127 +++--------------------------------------- 2 files changed, 172 insertions(+), 119 deletions(-) create mode 100644 colorpalettes.cpp diff --git a/colorpalettes.cpp b/colorpalettes.cpp new file mode 100644 index 00000000..9591279a --- /dev/null +++ b/colorpalettes.cpp @@ -0,0 +1,164 @@ +#ifndef __INC_COLORPALETTES_H +#define __INC_COLORPALETTES_H + +#include "FastLED.h" +#include "colorutils.h" +#include "colorpalettes.h" + +// Workaround for http://gcc.gnu.org/bugzilla/show_bug.cgi?id=34734 +#ifdef FASTLED_AVR +#ifdef PROGMEM +#undef PROGMEM +#define PROGMEM __attribute__((section(".progmem.data"))) +#endif +#endif + + + +// Preset color schemes, such as they are. + +// These schemes are all declared as "PROGMEM", meaning +// that they won't take up SRAM on AVR chips until used. +// Furthermore, the compiler won't even include these +// in your PROGMEM (flash) storage unless you specifically +// use each one, so you only 'pay for' those you actually use. + + +extern const TProgmemPalette16 CloudColors_p PROGMEM = +{ + CRGB::Blue, + CRGB::DarkBlue, + CRGB::DarkBlue, + CRGB::DarkBlue, + + CRGB::DarkBlue, + CRGB::DarkBlue, + CRGB::DarkBlue, + CRGB::DarkBlue, + + CRGB::Blue, + CRGB::DarkBlue, + CRGB::SkyBlue, + CRGB::SkyBlue, + + CRGB::LightBlue, + CRGB::White, + CRGB::LightBlue, + CRGB::SkyBlue +}; + +extern const TProgmemPalette16 LavaColors_p PROGMEM = +{ + CRGB::Black, + CRGB::Maroon, + CRGB::Black, + CRGB::Maroon, + + CRGB::DarkRed, + CRGB::Maroon, + CRGB::DarkRed, + + CRGB::DarkRed, + CRGB::DarkRed, + CRGB::Red, + CRGB::Orange, + + CRGB::White, + CRGB::Orange, + CRGB::Red, + CRGB::DarkRed +}; + + +extern const TProgmemPalette16 OceanColors_p PROGMEM = +{ + CRGB::MidnightBlue, + CRGB::DarkBlue, + CRGB::MidnightBlue, + CRGB::Navy, + + CRGB::DarkBlue, + CRGB::MediumBlue, + CRGB::SeaGreen, + CRGB::Teal, + + CRGB::CadetBlue, + CRGB::Blue, + CRGB::DarkCyan, + CRGB::CornflowerBlue, + + CRGB::Aquamarine, + CRGB::SeaGreen, + CRGB::Aqua, + CRGB::LightSkyBlue +}; + +extern const TProgmemPalette16 ForestColors_p PROGMEM = +{ + CRGB::DarkGreen, + CRGB::DarkGreen, + CRGB::DarkOliveGreen, + CRGB::DarkGreen, + + CRGB::Green, + CRGB::ForestGreen, + CRGB::OliveDrab, + CRGB::Green, + + CRGB::SeaGreen, + CRGB::MediumAquamarine, + CRGB::LimeGreen, + CRGB::YellowGreen, + + CRGB::LightGreen, + CRGB::LawnGreen, + CRGB::MediumAquamarine, + CRGB::ForestGreen +}; + +// HSV Rainbow +extern const TProgmemPalette16 RainbowColors_p PROGMEM = +{ + 0xFF0000, 0xD52A00, 0xAB5500, 0xAB7F00, + 0xABAB00, 0x56D500, 0x00FF00, 0x00D52A, + 0x00AB55, 0x0056AA, 0x0000FF, 0x2A00D5, + 0x5500AB, 0x7F0081, 0xAB0055, 0xD5002B +}; + +// HSV Rainbow colors with alternatating stripes of black +#define RainbowStripesColors_p RainbowStripeColors_p +extern const TProgmemPalette16 RainbowStripeColors_p PROGMEM = +{ + 0xFF0000, 0x000000, 0xAB5500, 0x000000, + 0xABAB00, 0x000000, 0x00FF00, 0x000000, + 0x00AB55, 0x000000, 0x0000FF, 0x000000, + 0x5500AB, 0x000000, 0xAB0055, 0x000000 +}; + +// HSV color ramp: blue purple ping red orange yellow (and back) +// Basically, everything but the greens, which tend to make +// people's skin look unhealthy. This palette is good for +// lighting at a club or party, where it'll be shining on people. +extern const TProgmemPalette16 PartyColors_p PROGMEM = +{ + 0x5500AB, 0x84007C, 0xB5004B, 0xE5001B, + 0xE81700, 0xB84700, 0xAB7700, 0xABAB00, + 0xAB5500, 0xDD2200, 0xF2000E, 0xC2003E, + 0x8F0071, 0x5F00A1, 0x2F00D0, 0x0007F9 +}; + +// Approximate "black body radiation" palette, akin to +// the FastLED 'HeatColor' function. +// Recommend that you use values 0-240 rather than +// the usual 0-255, as the last 15 colors will be +// 'wrapping around' from the hot end to the cold end, +// which looks wrong. +extern const TProgmemPalette16 HeatColors_p PROGMEM = +{ + 0x000000, + 0x330000, 0x660000, 0x990000, 0xCC0000, 0xFF0000, + 0xFF3300, 0xFF6600, 0xFF9900, 0xFFCC00, 0xFFFF00, + 0xFFFF33, 0xFFFF66, 0xFFFF99, 0xFFFFCC, 0xFFFFFF +}; + +#endif diff --git a/colorpalettes.h b/colorpalettes.h index 0a127ef4..b9622694 100644 --- a/colorpalettes.h +++ b/colorpalettes.h @@ -13,128 +13,23 @@ // use each one, so you only 'pay for' those you actually use. -const TProgmemPalette16 CloudColors_p PROGMEM = -{ - CRGB::Blue, - CRGB::DarkBlue, - CRGB::DarkBlue, - CRGB::DarkBlue, - - CRGB::DarkBlue, - CRGB::DarkBlue, - CRGB::DarkBlue, - CRGB::DarkBlue, - - CRGB::Blue, - CRGB::DarkBlue, - CRGB::SkyBlue, - CRGB::SkyBlue, - - CRGB::LightBlue, - CRGB::White, - CRGB::LightBlue, - CRGB::SkyBlue -}; - -const TProgmemPalette16 LavaColors_p PROGMEM = -{ - CRGB::Black, - CRGB::Maroon, - CRGB::Black, - CRGB::Maroon, - - CRGB::DarkRed, - CRGB::Maroon, - CRGB::DarkRed, - - CRGB::DarkRed, - CRGB::DarkRed, - CRGB::Red, - CRGB::Orange, - - CRGB::White, - CRGB::Orange, - CRGB::Red, - CRGB::DarkRed -}; - - -const TProgmemPalette16 OceanColors_p PROGMEM = -{ - CRGB::MidnightBlue, - CRGB::DarkBlue, - CRGB::MidnightBlue, - CRGB::Navy, - - CRGB::DarkBlue, - CRGB::MediumBlue, - CRGB::SeaGreen, - CRGB::Teal, - - CRGB::CadetBlue, - CRGB::Blue, - CRGB::DarkCyan, - CRGB::CornflowerBlue, - - CRGB::Aquamarine, - CRGB::SeaGreen, - CRGB::Aqua, - CRGB::LightSkyBlue -}; - -const TProgmemPalette16 ForestColors_p PROGMEM = -{ - CRGB::DarkGreen, - CRGB::DarkGreen, - CRGB::DarkOliveGreen, - CRGB::DarkGreen, - - CRGB::Green, - CRGB::ForestGreen, - CRGB::OliveDrab, - CRGB::Green, - - CRGB::SeaGreen, - CRGB::MediumAquamarine, - CRGB::LimeGreen, - CRGB::YellowGreen, - - CRGB::LightGreen, - CRGB::LawnGreen, - CRGB::MediumAquamarine, - CRGB::ForestGreen -}; +extern const TProgmemPalette16 CloudColors_p PROGMEM; +extern const TProgmemPalette16 LavaColors_p PROGMEM; +extern const TProgmemPalette16 OceanColors_p PROGMEM; +extern const TProgmemPalette16 ForestColors_p PROGMEM; // HSV Rainbow -const TProgmemPalette16 RainbowColors_p PROGMEM = -{ - 0xFF0000, 0xD52A00, 0xAB5500, 0xAB7F00, - 0xABAB00, 0x56D500, 0x00FF00, 0x00D52A, - 0x00AB55, 0x0056AA, 0x0000FF, 0x2A00D5, - 0x5500AB, 0x7F0081, 0xAB0055, 0xD5002B -}; +extern const TProgmemPalette16 RainbowColors_p PROGMEM; // HSV Rainbow colors with alternatating stripes of black #define RainbowStripesColors_p RainbowStripeColors_p -const TProgmemPalette16 RainbowStripeColors_p PROGMEM = -{ - 0xFF0000, 0x000000, 0xAB5500, 0x000000, - 0xABAB00, 0x000000, 0x00FF00, 0x000000, - 0x00AB55, 0x000000, 0x0000FF, 0x000000, - 0x5500AB, 0x000000, 0xAB0055, 0x000000 -}; +extern const TProgmemPalette16 RainbowStripeColors_p PROGMEM; // HSV color ramp: blue purple ping red orange yellow (and back) // Basically, everything but the greens, which tend to make // people's skin look unhealthy. This palette is good for // lighting at a club or party, where it'll be shining on people. -const TProgmemPalette16 PartyColors_p PROGMEM = -{ - 0x5500AB, 0x84007C, 0xB5004B, 0xE5001B, - 0xE81700, 0xB84700, 0xAB7700, 0xABAB00, - 0xAB5500, 0xDD2200, 0xF2000E, 0xC2003E, - 0x8F0071, 0x5F00A1, 0x2F00D0, 0x0007F9 -}; +extern const TProgmemPalette16 PartyColors_p PROGMEM; // Approximate "black body radiation" palette, akin to // the FastLED 'HeatColor' function. @@ -142,12 +37,6 @@ const TProgmemPalette16 PartyColors_p PROGMEM = // the usual 0-255, as the last 15 colors will be // 'wrapping around' from the hot end to the cold end, // which looks wrong. -const TProgmemPalette16 HeatColors_p PROGMEM = -{ - 0x000000, - 0x330000, 0x660000, 0x990000, 0xCC0000, 0xFF0000, - 0xFF3300, 0xFF6600, 0xFF9900, 0xFFCC00, 0xFFFF00, - 0xFFFF33, 0xFFFF66, 0xFFFF99, 0xFFFFCC, 0xFFFFFF -}; +extern const TProgmemPalette16 HeatColors_p PROGMEM; #endif -- cgit v1.2.3 From bd17f26fbe937d1de61415ad51cd6e32c94fcca2 Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Sun, 14 Sep 2014 23:45:11 -0700 Subject: Fix hanging that occurrs w/FastLED.delay --- FastLED.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/FastLED.cpp b/FastLED.cpp index 53a64898..b5a28ae9 100644 --- a/FastLED.cpp +++ b/FastLED.cpp @@ -89,10 +89,9 @@ void CFastLED::clearData() { void CFastLED::delay(unsigned long ms) { unsigned long start = millis(); while((millis()-start) < ms) { + ::delay(1); show(); - delay(1); } - } void CFastLED::setTemperature(const struct CRGB & temp) { -- cgit v1.2.3 From d2d658022136b9abcc31f106cea43b8974188b7e Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Sun, 14 Sep 2014 23:50:22 -0700 Subject: enforcing protections on internal methods in controllers --- chipsets.h | 10 ++++ clockless_arm_k20.h | 2 + clockless_arm_sam.h | 2 + clockless_trinket.h | 138 +++++++++++++++++++++++++++------------------------- 4 files changed, 86 insertions(+), 66 deletions(-) diff --git a/chipsets.h b/chipsets.h index 19d37d09..42720b5e 100644 --- a/chipsets.h +++ b/chipsets.h @@ -52,6 +52,8 @@ public: mSPI.release(); } +protected: + virtual void showColor(const struct CRGB & data, int nLeds, CRGB scale) { mSPI.template writePixels<0, LPD8806_ADJUST, RGB_ORDER>(PixelController(data, nLeds, scale, getDither())); } @@ -95,6 +97,8 @@ public: mWaitDelay.mark(); } +protected: + virtual void showColor(const struct CRGB & data, int nLeds, CRGB scale) { mWaitDelay.wait(); mSPI.template writePixels<0, DATA_NOP, RGB_ORDER>(PixelController(data, nLeds, scale, getDither())); @@ -148,6 +152,8 @@ public: showColor(CRGB(0,0,0), nLeds, CRGB(0,0,0)); } +protected: + virtual void showColor(const struct CRGB & data, int nLeds, CRGB scale) { PixelController pixels(data, nLeds, scale, getDither()); @@ -229,6 +235,8 @@ public: showColor(CRGB(0,0,0), nLeds, CRGB(0,0,0)); } +protected: + virtual void showColor(const struct CRGB & data, int nLeds, CRGB scale) { PixelController pixels(data, nLeds, scale, getDither()); @@ -322,6 +330,8 @@ public: writeHeader(); } +protected: + virtual void showColor(const struct CRGB & data, int nLeds, CRGB scale) { mSPI.template writePixels(PixelController(data, nLeds, scale, getDither())); writeHeader(); diff --git a/clockless_arm_k20.h b/clockless_arm_k20.h index 73dcd699..366c46f1 100644 --- a/clockless_arm_k20.h +++ b/clockless_arm_k20.h @@ -23,6 +23,8 @@ public: showColor(CRGB(0, 0, 0), nLeds, 0); } +protected: + // set all the leds on the controller to a given color virtual void showColor(const struct CRGB & rgbdata, int nLeds, CRGB scale) { PixelController pixels(rgbdata, nLeds, scale, getDither()); diff --git a/clockless_arm_sam.h b/clockless_arm_sam.h index d4c3d36f..74a0f602 100644 --- a/clockless_arm_sam.h +++ b/clockless_arm_sam.h @@ -34,6 +34,8 @@ public: showColor(CRGB(0, 0, 0), nLeds, 0); } +protected: + // set all the leds on the controller to a given color virtual void showColor(const struct CRGB & rgbdata, int nLeds, CRGB scale) { PixelController pixels(rgbdata, nLeds, scale, getDither()); diff --git a/clockless_trinket.h b/clockless_trinket.h index 55cd3f2b..4d93d091 100644 --- a/clockless_trinket.h +++ b/clockless_trinket.h @@ -18,18 +18,18 @@ // Variations on the functions in delay.h - w/a loop var passed in to preserve registers across calls by the optimizer/compiler template inline void _dc(register uint8_t & loopvar); -template inline void _dc_AVR(register uint8_t & loopvar) { +template inline void _dc_AVR(register uint8_t & loopvar) { _dc(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" + " 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 __attribute__((always_inline)) inline void _dc(register uint8_t & loopvar) { +template __attribute__((always_inline)) inline void _dc(register uint8_t & loopvar) { _dc_AVR(loopvar); } template<> __attribute__((always_inline)) inline void _dc<0>(register uint8_t & loopvar) {} @@ -51,7 +51,7 @@ template<> __attribute__((always_inline)) inline void _dc<10>(register uint8_t & ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // 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 +// 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. // ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -63,31 +63,33 @@ class ClocklessController : public CLEDController { CMinWait mWait; public: - virtual void init() { + virtual void init() { FastPin::setOutput(); } virtual void clearLeds(int nLeds) { - CRGB zeros(0,0,0); + CRGB zeros(0,0,0); showAdjTime((uint8_t*)&zeros, nLeds, zeros, false, 0); } +protected: + // set all the leds on the controller to a given color virtual void showColor(const struct CRGB & rgbdata, int nLeds, CRGB scale) { showAdjTime((uint8_t*)&rgbdata, nLeds, scale, false, 0); } - virtual void show(const struct CRGB *rgbdata, int nLeds, CRGB scale) { + virtual void show(const struct CRGB *rgbdata, int nLeds, CRGB scale) { showAdjTime((uint8_t*)rgbdata, nLeds, scale, true, 0); } #ifdef SUPPORT_ARGB - virtual void show(const struct CARGB *rgbdata, int nLeds, CRGB scale) { + virtual void show(const struct CARGB *rgbdata, int nLeds, CRGB scale) { showAdjTime((uint8_t*)rgbdata, nLeds, scale, true, 1); } #endif - void showAdjTime(const uint8_t *data, int nLeds, CRGB & scale, bool advance, int skip) { + void showAdjTime(const uint8_t *data, int nLeds, CRGB & scale, bool advance, int skip) { PixelController pixels(data, nLeds, scale, getDither(), advance, skip); mWait.wait(); @@ -97,16 +99,20 @@ public: // Adjust the timer #if !defined(NO_CORRECTION) || (NO_CORRECTION == 0) - uint16_t microsTaken = nLeds * CLKS_TO_MICROS(24 * (T1 + T2 + T3)); - MS_COUNTER += (microsTaken >> 10); + uint32_t microsTaken = (uint32_t)nLeds * (uint32_t)CLKS_TO_MICROS(24 * (T1 + T2 + T3)); + if(microsTaken > 1024) { + MS_COUNTER += (microsTaken >> 10); + } else { + MS_COUNTER++; + } #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 +// 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), \ @@ -129,7 +135,7 @@ public: [O0] "M" (RGB_BYTE0(RGB_ORDER)), \ [O1] "M" (RGB_BYTE1(RGB_ORDER)), \ [O2] "M" (RGB_BYTE2(RGB_ORDER)) \ - : /* clobber registers */ + : /* clobber registers */ // 1 cycle, write hi to the port @@ -201,7 +207,7 @@ public: #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 + // 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__ ((always_inline)) showRGBInternal(PixelController & pixels) { uint8_t *data = (uint8_t*)pixels.mData; @@ -209,7 +215,7 @@ public: data_t mask = FastPin::mask(); uint8_t scale_base = 0; - // register uint8_t *end = data + nLeds; + // register uint8_t *end = data + nLeds; data_t hi = *port | mask; data_t lo = *port & ~mask; *port = lo; @@ -218,10 +224,10 @@ public: uint8_t b1 = 0; uint8_t b2 = 0; - // Setup the pixel controller and load/scale the first byte + // Setup the pixel controller and load/scale the first byte pixels.preStepFirstByteDithering(); b0 = pixels.loadAndScale0(); - + // pull the dithering/adjustment values out of the pixels object for direct asm access uint8_t advanceBy = pixels.advanceBy(); @@ -236,7 +242,7 @@ public: 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; { @@ -254,31 +260,31 @@ public: // 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, + // 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. #if TRINKET_SCALE // Inline scaling - RGB ordering - HI1 D1(1) QLO2(b0, 7) LDSCL4(b1,O1) D2(4) LO1 PRESCALEA2(d1) D3(2) - HI1 D1(1) QLO2(b0, 6) PRESCALEB3(d1) D2(3) LO1 SCALE12(b1,0) D3(2) + HI1 D1(1) QLO2(b0, 7) LDSCL4(b1,O1) D2(4) LO1 PRESCALEA2(d1) D3(2) + HI1 D1(1) QLO2(b0, 6) PRESCALEB3(d1) D2(3) LO1 SCALE12(b1,0) D3(2) HI1 D1(1) QLO2(b0, 5) RORSC14(b1,1) D2(4) LO1 ROR1(b1) CLC1 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 ROR1(b1) CLC1 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 ROR1(b1) CLC1 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 ROR1(b1) CLC1 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 ROR1(b1) CLC1 D3(2) HI1 D1(1) QLO2(b0, 0) D2(0) LO1 D3(0) switch(XTRA0) { case 4: HI1 D1(1) QLO2(b0,0) D2(0) LO1 D3(0); case 3: HI1 D1(1) QLO2(b0,0) D2(0) LO1 D3(0); case 2: HI1 D1(1) QLO2(b0,0) D2(0) LO1 D3(0); case 1: HI1 D1(1) QLO2(b0,0) D2(0) LO1 D3(0); - } - HI1 D1(1) QLO2(b1, 7) LDSCL4(b2,O2) D2(4) LO1 PRESCALEA2(d2) D3(2) - HI1 D1(1) QLO2(b1, 6) PRESCALEB3(d2) D2(3) LO1 SCALE22(b2,0) D3(2) + } + HI1 D1(1) QLO2(b1, 7) LDSCL4(b2,O2) D2(4) LO1 PRESCALEA2(d2) D3(2) + HI1 D1(1) QLO2(b1, 6) PRESCALEB3(d2) D2(3) LO1 SCALE22(b2,0) D3(2) HI1 D1(1) QLO2(b1, 5) RORSC24(b2,1) D2(4) LO1 ROR1(b2) CLC1 D3(2) - HI1 D1(1) QLO2(b1, 4) SCROR24(b2,2) D2(4) LO1 SCALE22(b2,3) D3(2) - HI1 D1(1) QLO2(b1, 3) RORSC24(b2,4) D2(4) LO1 ROR1(b2) CLC1 D3(2) - HI1 D1(1) QLO2(b1, 2) SCROR24(b2,5) D2(4) LO1 SCALE22(b2,6) D3(2) + HI1 D1(1) QLO2(b1, 4) SCROR24(b2,2) D2(4) LO1 SCALE22(b2,3) D3(2) + HI1 D1(1) QLO2(b1, 3) RORSC24(b2,4) D2(4) LO1 ROR1(b2) CLC1 D3(2) + HI1 D1(1) QLO2(b1, 2) SCROR24(b2,5) D2(4) LO1 SCALE22(b2,6) D3(2) HI1 D1(1) QLO2(b1, 1) RORSC24(b2,7) D2(4) LO1 ROR1(b2) CLC1 D3(2) HI1 D1(1) QLO2(b1, 0) IDATA2 CLC1 D2(3) LO1 D3(0) switch(XTRA0) { @@ -286,49 +292,49 @@ public: case 3: HI1 D1(1) QLO2(b1,0) D2(0) LO1 D3(0); case 2: HI1 D1(1) QLO2(b1,0) D2(0) LO1 D3(0); case 1: HI1 D1(1) QLO2(b1,0) D2(0) LO1 D3(0); - } - HI1 D1(1) QLO2(b2, 7) LDSCL4(b0,O0) D2(4) LO1 PRESCALEA2(d0) D3(2) - HI1 D1(1) QLO2(b2, 6) PRESCALEB3(d0) D2(3) LO1 SCALE02(b0,0) D3(2) + } + HI1 D1(1) QLO2(b2, 7) LDSCL4(b0,O0) D2(4) LO1 PRESCALEA2(d0) D3(2) + HI1 D1(1) QLO2(b2, 6) PRESCALEB3(d0) D2(3) LO1 SCALE02(b0,0) D3(2) HI1 D1(1) QLO2(b2, 5) RORSC04(b0,1) D2(4) LO1 ROR1(b0) CLC1 D3(2) - HI1 D1(1) QLO2(b2, 4) SCROR04(b0,2) D2(4) LO1 SCALE02(b0,3) D3(2) - HI1 D1(1) QLO2(b2, 3) RORSC04(b0,4) D2(4) LO1 ROR1(b0) CLC1 D3(2) - HI1 D1(1) QLO2(b2, 2) SCROR04(b0,5) D2(4) LO1 SCALE02(b0,6) D3(2) + HI1 D1(1) QLO2(b2, 4) SCROR04(b0,2) D2(4) LO1 SCALE02(b0,3) D3(2) + HI1 D1(1) QLO2(b2, 3) RORSC04(b0,4) D2(4) LO1 ROR1(b0) CLC1 D3(2) + HI1 D1(1) QLO2(b2, 2) SCROR04(b0,5) D2(4) LO1 SCALE02(b0,6) D3(2) HI1 D1(1) QLO2(b2, 1) RORSC04(b0,7) D2(4) LO1 ROR1(b0) CLC1 D3(2) - // HI1 D1(1) QLO2(b2, 0) DCOUNT2 BRLOOP1 D2(3) LO1 D3(2) JMPLOOP2 - HI1 D1(1) QLO2(b2, 0) D2(0) LO1 D3(0) + // HI1 D1(1) QLO2(b2, 0) DCOUNT2 BRLOOP1 D2(3) LO1 D3(2) JMPLOOP2 + HI1 D1(1) QLO2(b2, 0) D2(0) LO1 D3(0) switch(XTRA0) { case 4: HI1 D1(1) QLO2(b1,0) D2(0) LO1 D3(0); case 3: HI1 D1(1) QLO2(b1,0) D2(0) LO1 D3(0); case 2: HI1 D1(1) QLO2(b1,0) D2(0) LO1 D3(0); case 1: HI1 D1(1) QLO2(b1,0) D2(0) LO1 D3(0); - } + } #else // no inline scaling - non-straight RGB ordering HI1 D1(1) QLO2(b0, 7) LD2(b1,O1) D2(2) LO1 D3(0) HI1 D1(1) QLO2(b0, 6) D2(0) LO1 D3(0) HI1 D1(1) QLO2(b0, 5) D2(0) LO1 D3(0) - HI1 D1(1) QLO2(b0, 4) D2(0) LO1 D3(0) - HI1 D1(1) QLO2(b0, 3) D2(0) LO1 D3(0) - HI1 D1(1) QLO2(b0, 2) D2(0) LO1 D3(0) - HI1 D1(1) QLO2(b0, 1) D2(0) LO1 D3(0) - HI1 D1(1) QLO2(b0, 0) D2(0) LO1 D3(0) - HI1 D1(1) QLO2(b1, 7) LD2(b2,O2) D2(2) LO1 D3(0) - HI1 D1(1) QLO2(b1, 6) D2(0) LO1 D3(0) - HI1 D1(1) QLO2(b1, 5) D2(0) LO1 D3(0) - HI1 D1(1) QLO2(b1, 4) D2(0) LO1 D3(0) - HI1 D1(1) QLO2(b1, 3) D2(0) LO1 D3(0) - HI1 D1(1) QLO2(b1, 2) D2(0) LO1 D3(0) - HI1 D1(1) QLO2(b1, 1) D2(0) LO1 D3(0) - HI1 D1(1) QLO2(b1, 0) IDATA2 D2(2) LO1 D3(0) - HI1 D1(1) QLO2(b2, 7) LD2(b0,O0) D2(2) LO1 D3(0) - HI1 D1(1) QLO2(b2, 6) D2(0) LO1 D3(0) - HI1 D1(1) QLO2(b2, 5) D2(0) LO1 D3(0) - HI1 D1(1) QLO2(b2, 4) D2(0) LO1 D3(0) - HI1 D1(1) QLO2(b2, 3) D2(0) LO1 D3(0) - HI1 D1(1) QLO2(b2, 2) D2(0) LO1 D3(0) + HI1 D1(1) QLO2(b0, 4) D2(0) LO1 D3(0) + HI1 D1(1) QLO2(b0, 3) D2(0) LO1 D3(0) + HI1 D1(1) QLO2(b0, 2) D2(0) LO1 D3(0) + HI1 D1(1) QLO2(b0, 1) D2(0) LO1 D3(0) + HI1 D1(1) QLO2(b0, 0) D2(0) LO1 D3(0) + HI1 D1(1) QLO2(b1, 7) LD2(b2,O2) D2(2) LO1 D3(0) + HI1 D1(1) QLO2(b1, 6) D2(0) LO1 D3(0) + HI1 D1(1) QLO2(b1, 5) D2(0) LO1 D3(0) + HI1 D1(1) QLO2(b1, 4) D2(0) LO1 D3(0) + HI1 D1(1) QLO2(b1, 3) D2(0) LO1 D3(0) + HI1 D1(1) QLO2(b1, 2) D2(0) LO1 D3(0) + HI1 D1(1) QLO2(b1, 1) D2(0) LO1 D3(0) + HI1 D1(1) QLO2(b1, 0) IDATA2 D2(2) LO1 D3(0) + HI1 D1(1) QLO2(b2, 7) LD2(b0,O0) D2(2) LO1 D3(0) + HI1 D1(1) QLO2(b2, 6) D2(0) LO1 D3(0) + HI1 D1(1) QLO2(b2, 5) D2(0) LO1 D3(0) + HI1 D1(1) QLO2(b2, 4) D2(0) LO1 D3(0) + HI1 D1(1) QLO2(b2, 3) D2(0) LO1 D3(0) + HI1 D1(1) QLO2(b2, 2) D2(0) LO1 D3(0) HI1 D1(1) QLO2(b2, 1) D2(0) LO1 D3(0) - HI1 D1(1) QLO2(b2, 0) D2(0) LO1 D3(0) -#endif + HI1 D1(1) QLO2(b2, 0) D2(0) LO1 D3(0) +#endif // DONE // D2(4) LO1 D3(0) } @@ -340,7 +346,7 @@ public: } #ifdef SUPPORT_ARGB - virtual void showARGB(struct CARGB *data, int nLeds) { + virtual void showARGB(struct CARGB *data, int nLeds) { // TODO: IMPLEMENTME } #endif -- cgit v1.2.3 From d975f96a875650a3b7850a0bcf3a51ef336af48c Mon Sep 17 00:00:00 2001 From: Mark Kriegsman Date: Tue, 23 Sep 2014 21:09:26 -0400 Subject: Fix boundary conditions in Fire examples --- examples/Fire2012/Fire2012.ino | 2 +- examples/Fire2012WithPalette/Fire2012WithPalette.ino | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/Fire2012/Fire2012.ino b/examples/Fire2012/Fire2012.ino index 73703426..0929e2f2 100644 --- a/examples/Fire2012/Fire2012.ino +++ b/examples/Fire2012/Fire2012.ino @@ -78,7 +78,7 @@ void Fire2012() } // Step 2. Heat from each cell drifts 'up' and diffuses a little - for( int k= NUM_LEDS - 3; k > 0; k--) { + for( int k= NUM_LEDS - 1; k >= 2; k--) { heat[k] = (heat[k - 1] + heat[k - 2] + heat[k - 2] ) / 3; } diff --git a/examples/Fire2012WithPalette/Fire2012WithPalette.ino b/examples/Fire2012WithPalette/Fire2012WithPalette.ino index 1208a589..41b9a247 100644 --- a/examples/Fire2012WithPalette/Fire2012WithPalette.ino +++ b/examples/Fire2012WithPalette/Fire2012WithPalette.ino @@ -134,7 +134,7 @@ void Fire2012WithPalette() } // Step 2. Heat from each cell drifts 'up' and diffuses a little - for( int k= NUM_LEDS - 3; k > 0; k--) { + for( int k= NUM_LEDS - 1; k >= 2; k--) { heat[k] = (heat[k - 1] + heat[k - 2] + heat[k - 2] ) / 3; } -- cgit v1.2.3 From 3103724f81abeb3d1f000960ad642e2d859b9b25 Mon Sep 17 00:00:00 2001 From: Mark Kriegsman Date: Tue, 23 Sep 2014 21:43:03 -0400 Subject: Added HSV blend functions --- colorutils.cpp | 75 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ colorutils.h | 25 +++++++++++++++----- 2 files changed, 94 insertions(+), 6 deletions(-) diff --git a/colorutils.cpp b/colorutils.cpp index ccaa646f..0f8d3832 100644 --- a/colorutils.cpp +++ b/colorutils.cpp @@ -319,6 +319,81 @@ CRGB* blend( const CRGB* src1, const CRGB* src2, CRGB* dest, uint16_t count, fra +CHSV& nblend( CHSV& existing, const CHSV& overlay, fract8 amountOfOverlay, TGradientDirectionCode directionCode) +{ + if( amountOfOverlay == 0) { + return existing; + } + + if( amountOfOverlay == 255) { + existing = overlay; + return existing; + } + + fract8 amountOfKeep = 256 - amountOfOverlay; + + uint8_t huedelta8 = overlay.hue - existing.hue; + + if( directionCode == SHORTEST_HUES ) { + directionCode = FORWARD_HUES; + if( huedelta8 > 127) { + directionCode = BACKWARD_HUES; + } + } + + if( directionCode == LONGEST_HUES ) { + directionCode = FORWARD_HUES; + if( huedelta8 < 128) { + directionCode = BACKWARD_HUES; + } + } + + if( directionCode == FORWARD_HUES) { + existing.hue = existing.hue + scale8( huedelta8, amountOfOverlay); + } + else /* directionCode == BACKWARD_HUES */ + { + huedelta8 = -huedelta8; + existing.hue = existing.hue - scale8( huedelta8, amountOfOverlay); + } + + existing.sat = scale8_LEAVING_R1_DIRTY( existing.sat, amountOfKeep) + + scale8_LEAVING_R1_DIRTY( overlay.sat, amountOfOverlay); + existing.val = scale8_LEAVING_R1_DIRTY( existing.val, amountOfKeep) + + scale8_LEAVING_R1_DIRTY( overlay.val, amountOfOverlay); + + cleanup_R1(); + + return existing; +} + + + +void nblend( CHSV* existing, CHSV* overlay, uint16_t count, fract8 amountOfOverlay, TGradientDirectionCode directionCode ) +{ + for( uint16_t i = count; i; i--) { + nblend( *existing, *overlay, amountOfOverlay, directionCode); + existing++; + overlay++; + } +} + +CHSV blend( const CHSV& p1, const CHSV& p2, fract8 amountOfP2, TGradientDirectionCode directionCode ) +{ + CHSV nu(p1); + nblend( nu, p2, amountOfP2, directionCode); + return nu; +} + +CHSV* blend( const CHSV* src1, const CHSV* src2, CHSV* dest, uint16_t count, fract8 amountOfsrc2, TGradientDirectionCode directionCode ) +{ + for( uint16_t i = count; i; i--) { + dest[i] = blend(src1[i], src2[i], amountOfsrc2, directionCode); + } + return dest; +} + + // CRGB HeatColor( uint8_t temperature) // diff --git a/colorutils.h b/colorutils.h index c986838b..181970e7 100644 --- a/colorutils.h +++ b/colorutils.h @@ -96,25 +96,38 @@ void nscale8( CRGB* leds, uint16_t num_leds, uint8_t scale); // Pixel blending // -// blend - computes an RGB-blended some fraction of the way -// between two other RGB colors. +// blend - computes a new color blended some fraction of the way +// between two other colors. CRGB blend( const CRGB& p1, const CRGB& p2, fract8 amountOfP2 ); -// blend - computes an RGB-blended array of colors, each +CHSV blend( const CHSV& p1, const CHSV& p2, fract8 amountOfP2, + TGradientDirectionCode directionCode = SHORTEST_HUES ); + +// blend - computes a new color blended array of colors, each // a given fraction of the way between corresponding // elements of two source arrays of colors. // Useful for blending palettes. CRGB* blend( const CRGB* src1, const CRGB* src2, CRGB* dest, uint16_t count, fract8 amountOfsrc2 ); -// nblend - destructively modifies one RGB color, blending -// in a given fraction of an overlay RGB color +CHSV* blend( const CHSV* src1, const CHSV* src2, CHSV* dest, + uint16_t count, fract8 amountOfsrc2, + TGradientDirectionCode directionCode = SHORTEST_HUES ); + +// nblend - destructively modifies one color, blending +// in a given fraction of an overlay color CRGB& nblend( CRGB& existing, const CRGB& overlay, fract8 amountOfOverlay ); +CHSV& nblend( CHSV& existing, const CHSV& overlay, fract8 amountOfOverlay, + TGradientDirectionCode directionCode = SHORTEST_HUES ); + // nblend - destructively blends a given fraction of -// a new RGB array into an existing RGB array +// a new color array into an existing color array void nblend( CRGB* existing, CRGB* overlay, uint16_t count, fract8 amountOfOverlay); +void nblend( CHSV* existing, CHSV* overlay, uint16_t count, fract8 amountOfOverlay, + TGradientDirectionCode directionCode = SHORTEST_HUES); + // CRGB HeatColor( uint8_t temperature) -- cgit v1.2.3 From 912d3c38bab3a69d42de487b8bde92ca0cd3ab12 Mon Sep 17 00:00:00 2001 From: Mark Kriegsman Date: Thu, 25 Sep 2014 18:25:46 -0400 Subject: Added dim8_lin, brighten8_lin, and sqrt16 --- lib8tion.h | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 64 insertions(+), 1 deletion(-) diff --git a/lib8tion.h b/lib8tion.h index 0c8b32ac..2de3f36f 100644 --- a/lib8tion.h +++ b/lib8tion.h @@ -105,13 +105,19 @@ quadwave8( x) triwave8( x) - + - Square root for 16-bit integers. About three times + faster and five times smaller than Arduino's built-in + generic 32-bit sqrt routine. + sqrt16( uint16_t x ) == sqrt( x) + - Dimming and brightening functions for 8-bit light values. dim8_video( x) == scale8_video( x, x) dim8_raw( x) == scale8( x, x) + dim8_lin( x) == (x<128) ? ((x+1)/2) : scale8(x,x) brighten8_video( x) == 255 - dim8_video( 255 - x) brighten8_raw( x) == 255 - dim8_raw( 255 - x) + brighten8_lin( x) == 255 - dim8_lin( 255 - x) The dimming functions in particular are suitable for making LED light output appear more 'linear'. @@ -996,6 +1002,17 @@ LIB8STATIC uint8_t dim8_video( uint8_t x) return scale8_video( x, x); } +LIB8STATIC uint8_t dim8_lin( uint8_t x ) +{ + if( x & 0x80 ) { + x = scale8( x, x); + } else { + x += 1; + x /= 2; + } + return x; +} + LIB8STATIC uint8_t brighten8_raw( uint8_t x) { uint8_t ix = 255 - x; @@ -1008,6 +1025,18 @@ LIB8STATIC uint8_t brighten8_video( uint8_t x) return 255 - scale8_video( ix, ix); } +LIB8STATIC uint8_t brighten8_lin( uint8_t x ) +{ + uint8_t ix = 255 - x; + if( ix & 0x80 ) { + ix = scale8( ix, ix); + } else { + ix += 1; + ix /= 2; + } + return 255 - ix; +} + /////////////////////////////////////////////////////////////////////// // A 16-bit PNRG good enough for LED animations @@ -1578,6 +1607,40 @@ LIB8STATIC uint8_t cubicwave8(uint8_t in) +// sqrt16: square root for 16-bit integers +// About three times faster and five times smaller +// than Arduino's general sqrt on AVR. +LIB8STATIC uint8_t sqrt16(uint16_t x) +{ + if( x <= 1) { + return x; + } + + uint8_t low = 1; // lower bound + uint8_t hi, mid; + + if( x > 7904) { + hi = 255; + } else { + hi = (x >> 5) + 8; // initial estimate for upper bound + } + + do { + mid = (low + hi) >> 1; + if ((mid * mid) > x) { + hi = mid - 1; + } else { + if( mid == 255) { + return 255; + } + low = mid + 1; + } + } while (hi >= low); + + return low - 1; +} + + template class q { T i:I; T f:F; -- cgit v1.2.3 From cbd2b2e56a10f4d897f89015521f6eda351d85f1 Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Mon, 29 Sep 2014 17:27:28 -0700 Subject: Radio shack's supplier tweaked the TM1803 timing numbers again --- chipsets.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/chipsets.h b/chipsets.h index 42720b5e..f0770409 100644 --- a/chipsets.h +++ b/chipsets.h @@ -389,7 +389,7 @@ template class TM1809Controller800Khz : public ClocklessController {}; template -class TM1803Controller400Khz : public ClocklessController {}; +class TM1803Controller400Khz : public ClocklessController {}; template class TM1829Controller800Khz : public ClocklessController {}; @@ -452,7 +452,7 @@ class WS2811Controller400Khz : public ClocklessController -class TM1803Controller400Khz : public ClocklessController {}; +class TM1803Controller400Khz : public ClocklessController {}; #if NO_TIME(750, 750, 750) #warning "Not enough clock cycles available for the TM1803" #endif -- cgit v1.2.3 From c4f3db5deb09e20702b0d16460efebc6f3a31119 Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Wed, 1 Oct 2014 16:21:40 -0700 Subject: Fix indexing error in one of the noise functions --- noise.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/noise.cpp b/noise.cpp index f0551c2e..36925c26 100644 --- a/noise.cpp +++ b/noise.cpp @@ -670,7 +670,7 @@ void fill_2dnoise16(CRGB *leds, int width, int height, bool serpentine, for(int i = 0; i < height; i++) { int wb = i*width; for(int j = 0; j < width; j++) { - CRGB led(CHSV(H[h1-i][h1-j],255,V[i][j])); + CRGB led(CHSV(H[h1-i][w1-j],255,V[i][j])); int pos = j; if(serpentine && (i & 0x1)) { -- cgit v1.2.3 From f3191249c73eae66975bfb3a3ba7c4921bc375d3 Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Wed, 1 Oct 2014 18:34:24 -0700 Subject: Tweaking WS2811 timings --- chipsets.h | 2 +- clockless_trinket.h | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/chipsets.h b/chipsets.h index f0770409..679dd0f2 100644 --- a/chipsets.h +++ b/chipsets.h @@ -374,7 +374,7 @@ class LPD1886Controller1250Khz : public ClocklessController -class WS2811Controller800Khz : public ClocklessController {}; +class WS2811Controller800Khz : public ClocklessController {}; template class WS2811Controller400Khz : public ClocklessController {}; diff --git a/clockless_trinket.h b/clockless_trinket.h index 4d93d091..4f7b7db3 100644 --- a/clockless_trinket.h +++ b/clockless_trinket.h @@ -32,6 +32,12 @@ template inline void _dc_AVR(register uint8_t & loopvar) { template __attribute__((always_inline)) inline void _dc(register uint8_t & loopvar) { _dc_AVR(loopvar); } +template<> __attribute__((always_inline)) inline void _dc<-6>(register uint8_t & loopvar) {} +template<> __attribute__((always_inline)) inline void _dc<-5>(register uint8_t & loopvar) {} +template<> __attribute__((always_inline)) inline void _dc<-4>(register uint8_t & loopvar) {} +template<> __attribute__((always_inline)) inline void _dc<-3>(register uint8_t & loopvar) {} +template<> __attribute__((always_inline)) inline void _dc<-2>(register uint8_t & loopvar) {} +template<> __attribute__((always_inline)) inline void _dc<-1>(register uint8_t & loopvar) {} template<> __attribute__((always_inline)) inline void _dc<0>(register uint8_t & loopvar) {} template<> __attribute__((always_inline)) inline void _dc<1>(register uint8_t & loopvar) {asm __volatile__("mov r0,r0":::);} template<> __attribute__((always_inline)) inline void _dc<2>(register uint8_t & loopvar) {asm __volatile__("rjmp .+0":::);} -- cgit v1.2.3 From 3153d74dad88b3684a26a9cba411dddfd6b12eaf Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Wed, 1 Oct 2014 18:42:53 -0700 Subject: Not ready to adjust the timing yet, actually --- chipsets.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/chipsets.h b/chipsets.h index 679dd0f2..e9a91132 100644 --- a/chipsets.h +++ b/chipsets.h @@ -374,7 +374,8 @@ class LPD1886Controller1250Khz : public ClocklessController -class WS2811Controller800Khz : public ClocklessController {}; +class WS2811Controller800Khz : public ClocklessController {}; +//class WS2811Controller800Khz : public ClocklessController {}; template class WS2811Controller400Khz : public ClocklessController {}; -- cgit v1.2.3 From 75e312d39e5c505231f14adb525c97d2b5f78447 Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Wed, 1 Oct 2014 19:10:20 -0700 Subject: Fix FirstLight default pin --- examples/FirstLight/FirstLight.ino | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/FirstLight/FirstLight.ino b/examples/FirstLight/FirstLight.ino index e4b4dd7c..928c7bbd 100644 --- a/examples/FirstLight/FirstLight.ino +++ b/examples/FirstLight/FirstLight.ino @@ -15,7 +15,7 @@ #define NUM_LEDS 60 // Data pin that led data will be written out over -#define DATA_PIN 23 +#define DATA_PIN 3 // Clock pin only needed for SPI based chipsets when not using hardware SPI //#define CLOCK_PIN 8 @@ -32,7 +32,7 @@ void setup() { // FastLED.addLeds(leds, NUM_LEDS); // FastLED.addLeds(leds, NUM_LEDS); // FastLED.addLeds(leds, NUM_LEDS); - // FastLED.addLeds(leds, NUM_LEDS); + FastLED.addLeds(leds, NUM_LEDS); // FastLED.addLeds(leds, NUM_LEDS); // FastLED.addLeds(leds, NUM_LEDS); // FastLED.addLeds(leds, NUM_LEDS); @@ -40,7 +40,7 @@ void setup() { // FastLED.addLeds(leds, NUM_LEDS); // FastLED.addLeds(leds, NUM_LEDS); // FastLED.addLeds(leds, NUM_LEDS); - FastLED.addLeds(leds, NUM_LEDS); + // FastLED.addLeds(leds, NUM_LEDS); // FastLED.addLeds(leds, NUM_LEDS); // FastLED.addLeds(leds, NUM_LEDS); -- cgit v1.2.3 From 1f0a65b39e9b0ad528fe74373ec871bb160f075a Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Wed, 1 Oct 2014 19:12:00 -0700 Subject: Tweak countFPS to only count (adding a getFPS method for getting the current FPS rate). Also, now that it only counts, modify Show method to always count. --- FastLED.cpp | 30 +++++++++++++----------------- FastLED.h | 9 +++++---- 2 files changed, 18 insertions(+), 21 deletions(-) diff --git a/FastLED.cpp b/FastLED.cpp index b5a28ae9..814cfbf5 100644 --- a/FastLED.cpp +++ b/FastLED.cpp @@ -20,6 +20,7 @@ CFastLED::CFastLED() { // clear out the array of led controllers // m_nControllers = 0; m_Scale = 255; + m_nFPS = 0; } CLEDController &CFastLED::addLeds(CLEDController *pLed, @@ -39,6 +40,7 @@ void CFastLED::show(uint8_t scale) { pCur->showLeds(scale); pCur = pCur->next(); } + countFPS(); } int CFastLED::count() { @@ -69,6 +71,7 @@ void CFastLED::showColor(const struct CRGB & color, uint8_t scale) { pCur->showColor(color, scale); pCur = pCur->next(); } + countFPS(); } void CFastLED::clear(boolean writeData) { @@ -122,21 +125,14 @@ extern int noise_min; extern int noise_max; void CFastLED::countFPS(int nFrames) { - if(Serial) { - static int br = 0; - static uint32_t lastframe = 0; // millis(); - - br++; - if(br == nFrames) { - uint32_t now = millis(); - Serial.print(lastframe); Serial.print("ms and now it is "); Serial.print(now); Serial.println("ms"); - now -= lastframe; - uint32_t fps = (br * 1000) / now; - /*Serial.print('('); Serial.print(noise_min); Serial.print(','); Serial.print(noise_max); Serial.print(") "); */ - Serial.print(now); Serial.print("ms for "); Serial.print(br); Serial.print(" frames, aka "); - Serial.print(fps); Serial.println(" fps. "); - br = 0; - lastframe = millis(); - } - } + static int br = 0; + static uint32_t lastframe = 0; // millis(); + + if(br++ >= nFrames) { + uint32_t now = millis(); + now -= lastframe; + m_nFPS = (br * 1000) / now; + br = 0; + lastframe = millis(); + } } diff --git a/FastLED.h b/FastLED.h index ff8300f8..c1990197 100644 --- a/FastLED.h +++ b/FastLED.h @@ -87,8 +87,8 @@ enum EBlockChipsets { class CFastLED { // int m_nControllers; - uint8_t m_Scale; - + uint8_t m_Scale; + uint16_t m_nFPS; public: CFastLED(); @@ -220,9 +220,10 @@ public: void setDither(uint8_t ditherMode = BINARY_DITHER); // for debugging, will keep track of time between calls to countFPS, and every - // nFrames calls, it will print a summary of FPS info out to the serial port. - // If the serial port isn't opened, this function does nothing. + // nFrames calls, it will update an internal counter for the current FPS. void countFPS(int nFrames=25); + // Get the number of frames/second being written out + uint16_t getFPS(); // returns the number of controllers (strips) that have been added with addLeds int count(); -- cgit v1.2.3 From 20c7d9455794e901301feaa2a2e9d978384853ff Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Wed, 1 Oct 2014 19:13:34 -0700 Subject: Clean up warnings --- lib8tion.h | 2 +- noise.cpp | 9 ++++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/lib8tion.h b/lib8tion.h index 2de3f36f..272d33cc 100644 --- a/lib8tion.h +++ b/lib8tion.h @@ -1627,7 +1627,7 @@ LIB8STATIC uint8_t sqrt16(uint16_t x) do { mid = (low + hi) >> 1; - if ((mid * mid) > x) { + if ((uint16_t)(mid * mid) > x) { hi = mid - 1; } else { if( mid == 255) { diff --git a/noise.cpp b/noise.cpp index 36925c26..163d4663 100644 --- a/noise.cpp +++ b/noise.cpp @@ -5,6 +5,14 @@ #define USE_PROGMEM #endif +// Workaround for http://gcc.gnu.org/bugzilla/show_bug.cgi?id=34734 +#ifdef FASTLED_AVR +#ifdef PROGMEM +#undef PROGMEM +#define PROGMEM __attribute__((section(".progmem.data"))) +#endif +#endif + #ifdef USE_PROGMEM #define FL_PROGMEM PROGMEM #define P(x) pgm_read_byte_near(p + x) @@ -519,7 +527,6 @@ void fill_raw_2dnoise16(uint16_t *pData, int width, int height, uint8_t octaves, scalex *= skip; scaley *= skip; - uint32_t xx = x; fract16 invamp = 65535-amplitude; for(int i = 0; i < height; i+=skip, y+=scaley) { uint16_t *pRow = pData + (i*width); -- cgit v1.2.3 From d4cfd0be38bf7fe9ae565061f643bc5105a71d85 Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Wed, 1 Oct 2014 21:16:14 -0700 Subject: Turns out everything we were doing with the SPI clock doubling stuff on the teensy 3/3.1 was correct. 12Mhz is a more realistic driving speed for the teensy 3/3.1 for LPD8806 than 20Mhz. --- chipsets.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/chipsets.h b/chipsets.h index e9a91132..d60dbe72 100644 --- a/chipsets.h +++ b/chipsets.h @@ -10,7 +10,7 @@ // ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -template +template class LPD8806Controller : public CLEDController { typedef SPIOutput SPI; @@ -331,7 +331,7 @@ public: } protected: - + virtual void showColor(const struct CRGB & data, int nLeds, CRGB scale) { mSPI.template writePixels(PixelController(data, nLeds, scale, getDither())); writeHeader(); -- cgit v1.2.3 From 483ecfd225c34be1df277bdd6a591ed6857f591a Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Wed, 1 Oct 2014 21:22:01 -0700 Subject: Issue #70 - turns out the clock doubling behavior is right - we just can't drive these chipsets as fast as we would like. --- chipsets.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chipsets.h b/chipsets.h index d60dbe72..dbfec665 100644 --- a/chipsets.h +++ b/chipsets.h @@ -212,7 +212,7 @@ protected: // ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -template +template class P9813Controller : public CLEDController { typedef SPIOutput SPI; SPI mSPI; -- cgit v1.2.3 From fec8a89aa8e6930e77ae735cc33ad3a9bf5d2098 Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Wed, 1 Oct 2014 21:40:59 -0700 Subject: Getting rid of redundant countFPS calls --- examples/Noise/Noise.ino | 1 - examples/NoisePlayground/NoisePlayground.ino | 1 - examples/SmartMatrix/SmartMatrix.ino | 1 - 3 files changed, 3 deletions(-) diff --git a/examples/Noise/Noise.ino b/examples/Noise/Noise.ino index dab26e7e..c2a64752 100644 --- a/examples/Noise/Noise.ino +++ b/examples/Noise/Noise.ino @@ -108,6 +108,5 @@ void loop() { ihue+=1; LEDS.show(); - LEDS.countFPS(); // delay(10); } diff --git a/examples/NoisePlayground/NoisePlayground.ino b/examples/NoisePlayground/NoisePlayground.ino index 35890146..e2c7cb31 100644 --- a/examples/NoisePlayground/NoisePlayground.ino +++ b/examples/NoisePlayground/NoisePlayground.ino @@ -42,7 +42,6 @@ void loop() { hue_octaves,hxy,hue_scale,hxy,hue_scale,hue_time, false); LEDS.show(); - LEDS.countFPS(); // adjust the intra-frame time values x += x_speed; diff --git a/examples/SmartMatrix/SmartMatrix.ino b/examples/SmartMatrix/SmartMatrix.ino index 99d75a42..997b6d24 100644 --- a/examples/SmartMatrix/SmartMatrix.ino +++ b/examples/SmartMatrix/SmartMatrix.ino @@ -117,6 +117,5 @@ void loop() { circlex += random16(2); circley += random16(2); LEDS.show(); - LEDS.countFPS(); // delay(10); } -- cgit v1.2.3 From f08fb6679f0c8b6c659713eb087275925be6a4b4 Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Wed, 1 Oct 2014 21:55:19 -0700 Subject: Tweak k20 timing for clockless chipsets, adjust for T3/3.1 clock speed --- clockless_arm_k20.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/clockless_arm_k20.h b/clockless_arm_k20.h index 366c46f1..b7f45ad6 100644 --- a/clockless_arm_k20.h +++ b/clockless_arm_k20.h @@ -24,7 +24,7 @@ public: } protected: - + // set all the leds on the controller to a given color virtual void showColor(const struct CRGB & rgbdata, int nLeds, CRGB scale) { PixelController pixels(rgbdata, nLeds, scale, getDither()); @@ -79,10 +79,10 @@ protected: next_mark = ARM_DWT_CYCCNT + (T1+T2+T3); FastPin::fastset(port, hi); if(b&0x80) { - while((next_mark - ARM_DWT_CYCCNT) > T3); + while((next_mark - ARM_DWT_CYCCNT) > (T3+(3*(F_CPU/24000000)))); FastPin::fastset(port, lo); } else { - while((next_mark - ARM_DWT_CYCCNT) > (T2+T3+1)); + while((next_mark - ARM_DWT_CYCCNT) > (T2+T3+(2*(F_CPU/24000000)))); FastPin::fastset(port, lo); } b <<= 1; @@ -93,10 +93,10 @@ protected: FastPin::fastset(port, hi); if(b&0x80) { - while((next_mark - ARM_DWT_CYCCNT) > T3); + while((next_mark - ARM_DWT_CYCCNT) > (T3+(3*(F_CPU/24000000)))); FastPin::fastset(port, lo); } else { - while((next_mark - ARM_DWT_CYCCNT) > (T2+T3+1)); + while((next_mark - ARM_DWT_CYCCNT) > (T2+T3+(2*(F_CPU/24000000)))); FastPin::fastset(port, lo); } } -- cgit v1.2.3 From d31046118e55f67656e8cfefb0bb1a86cceb4b54 Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Thu, 2 Oct 2014 00:18:12 -0700 Subject: make sure getFPS has a body --- FastLED.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FastLED.h b/FastLED.h index c1990197..af3d77de 100644 --- a/FastLED.h +++ b/FastLED.h @@ -223,7 +223,7 @@ public: // nFrames calls, it will update an internal counter for the current FPS. void countFPS(int nFrames=25); // Get the number of frames/second being written out - uint16_t getFPS(); + uint16_t getFPS() { return m_nFPS; } // returns the number of controllers (strips) that have been added with addLeds int count(); -- cgit v1.2.3 From 91c36a8737bc807e26c61c21155504b08e6b5741 Mon Sep 17 00:00:00 2001 From: Mark Kriegsman Date: Sun, 5 Oct 2014 14:37:34 -0400 Subject: Adding noise+palette example --- examples/NoisePlusPalette/NoisePlusPalette.ino | 273 +++++++++++++++++++++++++ 1 file changed, 273 insertions(+) create mode 100644 examples/NoisePlusPalette/NoisePlusPalette.ino diff --git a/examples/NoisePlusPalette/NoisePlusPalette.ino b/examples/NoisePlusPalette/NoisePlusPalette.ino new file mode 100644 index 00000000..2d4349e4 --- /dev/null +++ b/examples/NoisePlusPalette/NoisePlusPalette.ino @@ -0,0 +1,273 @@ +#include + +#define LED_PIN 3 +#define BRIGHTNESS 96 +#define LED_TYPE WS2811 +#define COLOR_ORDER GRB + +const uint8_t kMatrixWidth = 16; +const uint8_t kMatrixHeight = 16; +const bool kMatrixSerpentineLayout = true; + + +// This example combines two features of FastLED to produce a remarkable range of +// effects from a relatively small amount of code. This example combines FastLED's +// color palette lookup functions with FastLED's Perlin/simplex noise generator, and +// the combination is extremely powerful. +// +// You might want to look at the "ColorPalette" and "Noise" examples separately +// if this example code seems daunting. +// +// +// The basic setup here is that for each frame, we generate a new array of +// 'noise' data, and then map it onto the LED matrix through a color palette. +// +// Periodically, the color palette is changed, and new noise-generation parameters +// are chosen at the same time. In this example, specific noise-generation +// values have been selected to match the given color palettes; some are faster, +// or slower, or larger, or smaller than others, but there's no reason these +// parameters can't be freely mixed-and-matched. +// +// In addition, this example includes some fast automatic 'data smoothing' at +// lower noise speeds to help produce smoother animations in those cases. +// +// The FastLED built-in color palettes (Forest, Clouds, Lava, Ocean, Party) are +// used, as well as some 'hand-defined' ones, and some proceedurally generated +// palettes. + + +#define NUM_LEDS (kMatrixWidth * kMatrixHeight) +#define MAX_DIMENSION ((kMatrixWidth>kMatrixHeight) ? kMatrixWidth : kMatrixHeight) + +// The leds +CRGB leds[kMatrixWidth * kMatrixHeight]; + +// The 16 bit version of our coordinates +static uint16_t x; +static uint16_t y; +static uint16_t z; + +// We're using the x/y dimensions to map to the x/y pixels on the matrix. We'll +// use the z-axis for "time". speed determines how fast time moves forward. Try +// 1 for a very slow moving effect, or 60 for something that ends up looking like +// water. +uint16_t speed = 20; // speed is set dynamically once we've started up + +// Scale determines how far apart the pixels in our noise matrix are. Try +// changing these values around to see how it affects the motion of the display. The +// higher the value of scale, the more "zoomed out" the noise iwll be. A value +// of 1 will be so zoomed in, you'll mostly see solid colors. +uint16_t scale = 30; // scale is set dynamically once we've started up + +// This is the array that we keep our computed noise values in +uint8_t noise[MAX_DIMENSION][MAX_DIMENSION]; + +CRGBPalette16 currentPalette( PartyColors_p ); +uint8_t colorLoop = 1; + +void setup() { + delay(3000); + LEDS.addLeds(leds,NUM_LEDS); + LEDS.setBrightness(BRIGHTNESS); + + // Initialize our coordinates to some random values + x = random16(); + y = random16(); + z = random16(); +} + + + +// Fill the x/y array of 8-bit noise values using the inoise8 function. +void fillnoise8() { + // If we're runing at a low "speed", some 8-bit artifacts become visible + // from frame-to-frame. In order to reduce this, we can do some fast data-smoothing. + // The amount of data smoothing we're doing depends on "speed". + uint8_t dataSmoothing = 0; + if( speed < 50) { + dataSmoothing = 200 - (speed * 4); + } + + for(int i = 0; i < MAX_DIMENSION; i++) { + int ioffset = scale * i; + for(int j = 0; j < MAX_DIMENSION; j++) { + int joffset = scale * j; + + byte data = inoise8(x + ioffset,y + joffset,z); + + // The range of the inoise8 function is roughly 16-240. + // These two operations expand those values out to roughly 0..255 + // You can comment them out if you want the raw noise data. + data = qsub8(data,16); + data = qadd8(data,scale8(data,39)); + + if( dataSmoothing ) { + uint8_t olddata = noise[i][j]; + uint8_t newdata = scale8( olddata, dataSmoothing) + scale8( data, 256 - dataSmoothing); + data = newdata; + } + + noise[i][j] = data; + } + } + + z += speed; + + // apply slow drift to X and Y, just for visual variation. + x += speed / 8; + y -= speed / 16; +} + +void mapNoiseToLEDsUsingPalette() +{ + static uint8_t ihue=0; + + for(int i = 0; i < kMatrixWidth; i++) { + for(int j = 0; j < kMatrixHeight; j++) { + // We use the value at the (i,j) coordinate in the noise + // array for our brightness, and the flipped value from (j,i) + // for our pixel's index into the color palette. + + uint8_t index = noise[j][i]; + uint8_t bri = noise[i][j]; + + // if this palette is a 'loop', add a slowly-changing base value + if( colorLoop) { + index += ihue; + } + + // brighten up, as the color palette itself often contains the + // light/dark dynamic range desired + if( bri > 127 ) { + bri = 255; + } else { + bri = dim8_raw( bri * 2); + } + + CRGB color = ColorFromPalette( currentPalette, index, bri); + leds[XY(i,j)] = color; + } + } + + ihue+=1; +} + +void loop() { + // Periodically choose a new palette, speed, and scale + ChangePaletteAndSettingsPeriodically(); + + // generate noise data + fillnoise8(); + + // convert the noise data to colors in the LED array + // using the current palette + mapNoiseToLEDsUsingPalette(); + + LEDS.show(); + // delay(10); +} + + + +// There are several different palettes of colors demonstrated here. +// +// FastLED provides several 'preset' palettes: RainbowColors_p, RainbowStripeColors_p, +// OceanColors_p, CloudColors_p, LavaColors_p, ForestColors_p, and PartyColors_p. +// +// Additionally, you can manually define your own color palettes, or you can write +// code that creates color palettes on the fly. + +// 1 = 5 sec per palette +// 2 = 10 sec per palette +// etc +#define HOLD_PALETTES_X_TIMES_AS_LONG 1 + +void ChangePaletteAndSettingsPeriodically() +{ + uint8_t secondHand = ((millis() / 1000) / HOLD_PALETTES_X_TIMES_AS_LONG) % 60; + static uint8_t lastSecond = 99; + + if( lastSecond != secondHand) { + lastSecond = secondHand; + if( secondHand == 0) { currentPalette = RainbowColors_p; speed = 20; scale = 30; colorLoop = 1; } + if( secondHand == 5) { SetupPurpleAndGreenPalette(); speed = 10; scale = 50; colorLoop = 1; } + if( secondHand == 10) { SetupBlackAndWhiteStripedPalette(); speed = 20; scale = 30; colorLoop = 1; } + if( secondHand == 15) { currentPalette = ForestColors_p; speed = 8; scale =120; colorLoop = 0; } + if( secondHand == 20) { currentPalette = CloudColors_p; speed = 4; scale = 30; colorLoop = 0; } + if( secondHand == 25) { currentPalette = LavaColors_p; speed = 8; scale = 50; colorLoop = 0; } + if( secondHand == 30) { currentPalette = OceanColors_p; speed = 20; scale = 90; colorLoop = 0; } + if( secondHand == 35) { currentPalette = PartyColors_p; speed = 20; scale = 30; colorLoop = 1; } + if( secondHand == 40) { SetupRandomPalette(); speed = 20; scale = 20; colorLoop = 1; } + if( secondHand == 45) { SetupRandomPalette(); speed = 50; scale = 50; colorLoop = 1; } + if( secondHand == 50) { SetupRandomPalette(); speed = 90; scale = 90; colorLoop = 1; } + if( secondHand == 55) { currentPalette = RainbowStripeColors_p; speed = 30; scale = 20; colorLoop = 1; } + } +} + +// This function generates a random palette that's a gradient +// between four different colors. The first is a dim hue, the second is +// a bright hue, the third is a bright pastel, and the last is +// another bright hue. This gives some visual bright/dark variation +// which is more interesting than just a gradient of different hues. +void SetupRandomPalette() +{ + currentPalette = CRGBPalette16( + CHSV( random8(), 255, 32), + CHSV( random8(), 255, 255), + CHSV( random8(), 128, 255), + CHSV( random8(), 255, 255)); +} + +// This function sets up a palette of black and white stripes, +// using code. Since the palette is effectively an array of +// sixteen CRGB colors, the various fill_* functions can be used +// to set them up. +void SetupBlackAndWhiteStripedPalette() +{ + // 'black out' all 16 palette entries... + fill_solid( currentPalette, 16, CRGB::Black); + // and set every fourth one to white. + currentPalette[0] = CRGB::White; + currentPalette[4] = CRGB::White; + currentPalette[8] = CRGB::White; + currentPalette[12] = CRGB::White; + +} + +// This function sets up a palette of purple and green stripes. +void SetupPurpleAndGreenPalette() +{ + CRGB purple = CHSV( HUE_PURPLE, 255, 255); + CRGB green = CHSV( HUE_GREEN, 255, 255); + CRGB black = CRGB::Black; + + currentPalette = CRGBPalette16( + green, green, black, black, + purple, purple, black, black, + green, green, black, black, + purple, purple, black, black ); +} + + +// +// Mark's xy coordinate mapping code. See the XYMatrix for more information on it. +// +uint16_t XY( uint8_t x, uint8_t y) +{ + uint16_t i; + if( kMatrixSerpentineLayout == false) { + i = (y * kMatrixWidth) + x; + } + if( kMatrixSerpentineLayout == true) { + if( y & 0x01) { + // Odd rows run backwards + uint8_t reverseX = (kMatrixWidth - 1) - x; + i = (y * kMatrixWidth) + reverseX; + } else { + // Even rows run forwards + i = (y * kMatrixWidth) + x; + } + } + return i; +} + -- cgit v1.2.3 From 73989e3f0bd417fd5746292ca73fe27aa6fc7cc9 Mon Sep 17 00:00:00 2001 From: Mark Kriegsman Date: Sun, 5 Oct 2014 14:42:40 -0400 Subject: Fix for fill_gradient, switch to templates for a few functions to allow use on CHSV arrays as well as CRGB arrays, e.g., if there ever were such a thing as CHSVPalette. --- colorutils.cpp | 124 +++++++++++++------------------------------------- colorutils.h | 139 +++++++++++++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 156 insertions(+), 107 deletions(-) diff --git a/colorutils.cpp b/colorutils.cpp index 0f8d3832..6a12fb11 100644 --- a/colorutils.cpp +++ b/colorutils.cpp @@ -6,14 +6,31 @@ #include "colorutils.h" -void fill_solid( struct CRGB * pFirstLED, int numToFill, - const struct CRGB& color) + + +void fill_solid( struct CRGB * leds, int numToFill, + const struct CRGB& color) +{ + for( int i = 0; i < numToFill; i++) { + leds[i] = color; + } +} + +void fill_solid( struct CHSV * targetArray, int numToFill, + const struct CHSV& hsvColor) { for( int i = 0; i < numToFill; i++) { - pFirstLED[i] = color; + targetArray[i] = hsvColor; } } + +// void fill_solid( struct CRGB* targetArray, int numToFill, +// const struct CHSV& hsvColor) +// { +// fill_solid( targetArray, numToFill, (CRGB) hsvColor); +// } + void fill_rainbow( struct CRGB * pFirstLED, int numToFill, uint8_t initialhue, uint8_t deltahue ) @@ -28,74 +45,21 @@ void fill_rainbow( struct CRGB * pFirstLED, int numToFill, } } - -#define saccum87 int16_t - -void fill_gradient( CRGB* leds, - uint16_t startpos, CHSV startcolor, - uint16_t endpos, CHSV endcolor, - TGradientDirectionCode directionCode ) +void fill_rainbow( struct CHSV * targetArray, int numToFill, + uint8_t initialhue, + uint8_t deltahue ) { - // if the points are in the wrong order, straighten them - if( endpos < startpos ) { - uint16_t t = endpos; - CHSV tc = endcolor; - startpos = t; - startcolor = tc; - endcolor = startcolor; - endpos = startpos; - } - - saccum87 huedistance87; - saccum87 satdistance87; - saccum87 valdistance87; - - satdistance87 = (endcolor.sat - startcolor.sat) << 7; - valdistance87 = (endcolor.val - startcolor.val) << 7; - - uint8_t huedelta8 = endcolor.hue - startcolor.hue; - - if( directionCode == SHORTEST_HUES ) { - directionCode = FORWARD_HUES; - if( huedelta8 > 127) { - directionCode = BACKWARD_HUES; - } - } - - if( directionCode == LONGEST_HUES ) { - directionCode = FORWARD_HUES; - if( huedelta8 < 128) { - directionCode = BACKWARD_HUES; - } - } - - if( directionCode == FORWARD_HUES) { - huedistance87 = huedelta8 << 7; - } - else /* directionCode == BACKWARD_HUES */ - { - huedistance87 = (uint8_t)(256 - huedelta8) << 7; - huedistance87 = -huedistance87; - } - - uint16_t pixeldistance = endpos - startpos; - uint16_t p2 = pixeldistance / 2; - int16_t divisor = p2 ? p2 : 1; - saccum87 huedelta87 = huedistance87 / divisor; - saccum87 satdelta87 = satdistance87 / divisor; - saccum87 valdelta87 = valdistance87 / divisor; - - accum88 hue88 = startcolor.hue << 8; - accum88 sat88 = startcolor.sat << 8; - accum88 val88 = startcolor.val << 8; - for( uint16_t i = startpos; i <= endpos; i++) { - leds[i] = CHSV( hue88 >> 8, sat88 >> 8, val88 >> 8); - hue88 += huedelta87; - sat88 += satdelta87; - val88 += valdelta87; + CHSV hsv; + hsv.hue = initialhue; + hsv.val = 255; + hsv.sat = 255; + for( int i = 0; i < numToFill; i++) { + targetArray[i] = hsv; + hsv.hue += deltahue; } } + void fill_gradient_RGB( CRGB* leds, uint16_t startpos, CRGB startcolor, uint16_t endpos, CRGB endcolor ) @@ -136,32 +100,6 @@ void fill_gradient_RGB( CRGB* leds, } } - -void fill_gradient( CRGB* leds, uint16_t numLeds, const CHSV& c1, const CHSV& c2, TGradientDirectionCode directionCode ) -{ - uint16_t last = numLeds - 1; - fill_gradient( leds, 0, c1, last, c2, directionCode); -} - - -void fill_gradient( CRGB* leds, uint16_t numLeds, const CHSV& c1, const CHSV& c2, const CHSV& c3, TGradientDirectionCode directionCode ) -{ - uint16_t half = (numLeds / 2); - uint16_t last = numLeds - 1; - fill_gradient( leds, 0, c1, half, c2, directionCode); - fill_gradient( leds, half, c2, last, c3, directionCode); -} - -void fill_gradient( CRGB* leds, uint16_t numLeds, const CHSV& c1, const CHSV& c2, const CHSV& c3, const CHSV& c4, TGradientDirectionCode directionCode ) -{ - uint16_t onethird = (numLeds / 3); - uint16_t twothirds = ((numLeds * 2) / 3); - uint16_t last = numLeds - 1; - fill_gradient( leds, 0, c1, onethird, c2, directionCode); - fill_gradient( leds, onethird, c2, twothirds, c3, directionCode); - fill_gradient( leds, twothirds, c3, last, c4, directionCode); -} - #if 0 void fill_gradient( const CHSV& c1, const CHSV& c2) { diff --git a/colorutils.h b/colorutils.h index 181970e7..c2e1ec65 100644 --- a/colorutils.h +++ b/colorutils.h @@ -7,17 +7,27 @@ // fill_solid - fill a range of LEDs with a solid color -void fill_solid( struct CRGB * pFirstLED, int numToFill, +// Example: fill_solid( leds, NUM_LEDS, CRGB(50,0,200)); + +void fill_solid( struct CRGB * leds, int numToFill, const struct CRGB& color); +void fill_solid( struct CHSV* targetArray, int numToFill, + const struct CHSV& hsvColor); + + // fill_rainbow - fill a range of LEDs with a rainbow of colors, at // full saturation and full value (brightness) void fill_rainbow( struct CRGB * pFirstLED, int numToFill, uint8_t initialhue, uint8_t deltahue = 5); + +void fill_rainbow( struct CHSV * targetArray, int numToFill, + uint8_t initialhue, + uint8_t deltahue = 5); -// fill_gradient - fill a range of LEDs with a smooth HSV gradient +// fill_gradient - fill an array of colors with a smooth HSV gradient // between two specified HSV colors. // Since 'hue' is a value around a color wheel, // there are always two ways to sweep from one hue @@ -31,24 +41,125 @@ void fill_rainbow( struct CRGB * pFirstLED, int numToFill, // The default is SHORTEST_HUES, as this is nearly // always what is wanted. // +// fill_gradient can write the gradient colors EITHER +// (1) into an array of CRGBs (e.g., into leds[] array, or an RGB Palette) +// OR +// (2) into an array of CHSVs (e.g. an HSV Palette). +// +// In the case of writing into a CRGB array, the gradient is +// computed in HSV space, and then HSV values are converted to RGB +// as they're written into the RGB array. + typedef enum { FORWARD_HUES, BACKWARD_HUES, SHORTEST_HUES, LONGEST_HUES } TGradientDirectionCode; -void fill_gradient( struct CRGB* leds, + + +#define saccum87 int16_t + +template +void fill_gradient( T* targetArray, uint16_t startpos, CHSV startcolor, uint16_t endpos, CHSV endcolor, - TGradientDirectionCode directionCode = SHORTEST_HUES ); + TGradientDirectionCode directionCode = SHORTEST_HUES ) +{ + // if the points are in the wrong order, straighten them + if( endpos < startpos ) { + uint16_t t = endpos; + CHSV tc = endcolor; + startpos = t; + startcolor = tc; + endcolor = startcolor; + endpos = startpos; + } + + saccum87 huedistance87; + saccum87 satdistance87; + saccum87 valdistance87; + + satdistance87 = (endcolor.sat - startcolor.sat) << 7; + valdistance87 = (endcolor.val - startcolor.val) << 7; + + uint8_t huedelta8 = endcolor.hue - startcolor.hue; + + if( directionCode == SHORTEST_HUES ) { + directionCode = FORWARD_HUES; + if( huedelta8 > 127) { + directionCode = BACKWARD_HUES; + } + } + + if( directionCode == LONGEST_HUES ) { + directionCode = FORWARD_HUES; + if( huedelta8 < 128) { + directionCode = BACKWARD_HUES; + } + } + + if( directionCode == FORWARD_HUES) { + huedistance87 = huedelta8 << 7; + } + else /* directionCode == BACKWARD_HUES */ + { + huedistance87 = (uint8_t)(256 - huedelta8) << 7; + huedistance87 = -huedistance87; + } + + uint16_t pixeldistance = endpos - startpos; + int16_t divisor = pixeldistance ? pixeldistance : 1; + + saccum87 huedelta87 = huedistance87 / divisor; + saccum87 satdelta87 = satdistance87 / divisor; + saccum87 valdelta87 = valdistance87 / divisor; + + huedelta87 *= 2; + satdelta87 *= 2; + valdelta87 *= 2; + + accum88 hue88 = startcolor.hue << 8; + accum88 sat88 = startcolor.sat << 8; + accum88 val88 = startcolor.val << 8; + for( uint16_t i = startpos; i <= endpos; i++) { + targetArray[i] = CHSV( hue88 >> 8, sat88 >> 8, val88 >> 8); + hue88 += huedelta87; + sat88 += satdelta87; + val88 += valdelta87; + } +} + -// Convenience functions to fill a range of leds[] with a +// Convenience functions to fill an array of colors with a // two-color, three-color, or four-color gradient -void fill_gradient( struct CRGB* leds, uint16_t numLeds, - const CHSV& c1, const CHSV& c2, - TGradientDirectionCode directionCode = SHORTEST_HUES ); -void fill_gradient( struct CRGB* leds, uint16_t numLeds, - const CHSV& c1, const CHSV& c2, const CHSV& c3, - TGradientDirectionCode directionCode = SHORTEST_HUES ); -void fill_gradient( struct CRGB* leds, uint16_t numLeds, - const CHSV& c1, const CHSV& c2, const CHSV& c3, const CHSV& c4, - TGradientDirectionCode directionCode = SHORTEST_HUES ); +template +void fill_gradient( T* targetArray, uint16_t numLeds, const CHSV& c1, const CHSV& c2, + TGradientDirectionCode directionCode = SHORTEST_HUES ) +{ + uint16_t last = numLeds - 1; + fill_gradient( targetArray, 0, c1, last, c2, directionCode); +} + +template +void fill_gradient( T* targetArray, uint16_t numLeds, + const CHSV& c1, const CHSV& c2, const CHSV& c3, + TGradientDirectionCode directionCode = SHORTEST_HUES ) +{ + uint16_t half = (numLeds / 2); + uint16_t last = numLeds - 1; + fill_gradient( targetArray, 0, c1, half, c2, directionCode); + fill_gradient( targetArray, half, c2, last, c3, directionCode); +} + +template +void fill_gradient( T* targetArray, uint16_t numLeds, + const CHSV& c1, const CHSV& c2, const CHSV& c3, const CHSV& c4, + TGradientDirectionCode directionCode = SHORTEST_HUES ) +{ + uint16_t onethird = (numLeds / 3); + uint16_t twothirds = ((numLeds * 2) / 3); + uint16_t last = numLeds - 1; + fill_gradient( targetArray, 0, c1, onethird, c2, directionCode); + fill_gradient( targetArray, onethird, c2, twothirds, c3, directionCode); + fill_gradient( targetArray, twothirds, c3, last, c4, directionCode); +} // convenience synonym #define fill_gradient_HSV fill_gradient -- cgit v1.2.3 From 8aa1405052a2716f65f5bd524cc6c52912d2371e Mon Sep 17 00:00:00 2001 From: Mark Kriegsman Date: Mon, 6 Oct 2014 14:48:59 -0400 Subject: change 'byte' to 'uint8_t' --- examples/NoisePlusPalette/NoisePlusPalette.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/NoisePlusPalette/NoisePlusPalette.ino b/examples/NoisePlusPalette/NoisePlusPalette.ino index 2d4349e4..bca6698c 100644 --- a/examples/NoisePlusPalette/NoisePlusPalette.ino +++ b/examples/NoisePlusPalette/NoisePlusPalette.ino @@ -93,7 +93,7 @@ void fillnoise8() { for(int j = 0; j < MAX_DIMENSION; j++) { int joffset = scale * j; - byte data = inoise8(x + ioffset,y + joffset,z); + uint8_t data = inoise8(x + ioffset,y + joffset,z); // The range of the inoise8 function is roughly 16-240. // These two operations expand those values out to roughly 0..255 -- cgit v1.2.3 From ffd143e305e4454b4dd3f1ca5037be7d6094f9f8 Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Tue, 7 Oct 2014 17:10:05 -0700 Subject: Some port/pin flag tweaks for the K20 hardware SPI support --- fastspi_arm_k20.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/fastspi_arm_k20.h b/fastspi_arm_k20.h index 7e938d54..ad9598ae 100644 --- a/fastspi_arm_k20.h +++ b/fastspi_arm_k20.h @@ -93,9 +93,9 @@ class ARMHardwareSPIOutput { CORE_PIN12_CONFIG = PORT_PCR_MUX(2); CORE_PIN13_CONFIG = PORT_PCR_DSE | PORT_PCR_MUX(2); } else if(_DATA_PIN == 7) { - CORE_PIN7_CONFIG = PORT_PCR_MUX(2); - CORE_PIN8_CONFIG = PORT_PCR_MUX(2); - CORE_PIN14_CONFIG = PORT_PCR_MUX(2); + CORE_PIN7_CONFIG = PORT_PCR_DSE | PORT_PCR_MUX(2); + CORE_PIN8_CONFIG = PORT_PCR_DSE | PORT_PCR_MUX(2); + CORE_PIN14_CONFIG = PORT_PCR_DSE | PORT_PCR_MUX(2); } } @@ -107,9 +107,9 @@ class ARMHardwareSPIOutput { CORE_PIN12_CONFIG = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1); CORE_PIN13_CONFIG = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1); } else if(_DATA_PIN == 7) { - // CORE_PIN7_CONFIG = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1); - // CORE_PIN8_CONFIG = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1); - // CORE_PIN14_CONFIG = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1); + CORE_PIN7_CONFIG = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1); + CORE_PIN8_CONFIG = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1); + CORE_PIN14_CONFIG = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1); } } public: -- cgit v1.2.3 From 68f469ca23b4168f54cef07b1629e8c18dd9585b Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Tue, 7 Oct 2014 17:10:20 -0700 Subject: Trying to clean up software SPI timings --- fastspi_bitbang.h | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/fastspi_bitbang.h b/fastspi_bitbang.h index fc2403bd..a779ddd3 100644 --- a/fastspi_bitbang.h +++ b/fastspi_bitbang.h @@ -105,7 +105,8 @@ private: } public: - #define SPI_DELAY delaycycles< (SPI_SPEED-2) / 2>(); + #define SPI_DELAY delaycycles< ((SPI_SPEED-2) / 2)>(); + #define SPI_DELAY_HALF delaycycles< ((SPI_SPEED-4) / 4)>(); // write the BIT'th bit out via spi, setting the data pin then strobing the clcok template __attribute__((always_inline, hot)) inline static void writeBit(uint8_t b) { @@ -169,14 +170,14 @@ private: writeBit(b); #else if(b & (1 << BIT)) { - FastPin::fastset(clockdatapin, datahiclocklo); SPI_DELAY; + FastPin::fastset(clockdatapin, datahiclocklo); SPI_DELAY_HALF; FastPin::fastset(clockdatapin, datahiclockhi); SPI_DELAY; - FastPin::fastset(clockdatapin, datahiclocklo); SPI_DELAY; + FastPin::fastset(clockdatapin, datahiclocklo); SPI_DELAY_HALF; } else { // NOP; - FastPin::fastset(clockdatapin, dataloclocklo); SPI_DELAY; + FastPin::fastset(clockdatapin, dataloclocklo); SPI_DELAY_HALF; FastPin::fastset(clockdatapin, dataloclockhi); SPI_DELAY; - FastPin::fastset(clockdatapin, dataloclocklo); SPI_DELAY; + FastPin::fastset(clockdatapin, dataloclocklo); SPI_DELAY_HALF; } #endif } -- cgit v1.2.3 From 97f45ca07c3e66ec9f84509b53ec12d0d6fa5dbf Mon Sep 17 00:00:00 2001 From: Mark Kriegsman Date: Wed, 8 Oct 2014 11:36:41 -0400 Subject: Made the comments match the code. Also reality. --- examples/NoisePlusPalette/NoisePlusPalette.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/NoisePlusPalette/NoisePlusPalette.ino b/examples/NoisePlusPalette/NoisePlusPalette.ino index bca6698c..4e06bdd8 100644 --- a/examples/NoisePlusPalette/NoisePlusPalette.ino +++ b/examples/NoisePlusPalette/NoisePlusPalette.ino @@ -95,7 +95,7 @@ void fillnoise8() { uint8_t data = inoise8(x + ioffset,y + joffset,z); - // The range of the inoise8 function is roughly 16-240. + // The range of the inoise8 function is roughly 16-238. // These two operations expand those values out to roughly 0..255 // You can comment them out if you want the raw noise data. data = qsub8(data,16); -- cgit v1.2.3 From b0225bb185b5d3350fde4f7c668de70610773add Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Thu, 9 Oct 2014 22:01:42 -0700 Subject: Adjusting timings for k20 based clockless chips --- chipsets.h | 8 ++++---- clockless_arm_k20.h | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/chipsets.h b/chipsets.h index dbfec665..e2929990 100644 --- a/chipsets.h +++ b/chipsets.h @@ -366,7 +366,7 @@ protected: // We want to force all avr's to use the Trinket controller when running at 8Mhz, because even the 328's at 8Mhz // need the more tightly defined timeframes. -#if (F_CPU == 8000000 || F_CPU == 16000000 || F_CPU == 24000000 || F_CPU == 48000000 || F_CPU == 96000000) // 125ns/clock +#if (F_CPU == 8000000 || F_CPU == 16000000 || F_CPU == 24000000) // || F_CPU == 48000000 || F_CPU == 96000000) // 125ns/clock #define FMUL (F_CPU/8000000) // LPD1886 template @@ -437,10 +437,10 @@ class TM1809Controller800Khz : public ClocklessController -class WS2811Controller800Khz : public ClocklessController {}; -#if NO_TIME(400, 400, 450) +class WS2811Controller800Khz : public ClocklessController {}; +#if NO_TIME(320, 320, 640) #warning "Not enough clock cycles available for the WS2811 (800khz)" #endif diff --git a/clockless_arm_k20.h b/clockless_arm_k20.h index b7f45ad6..126955b1 100644 --- a/clockless_arm_k20.h +++ b/clockless_arm_k20.h @@ -79,7 +79,7 @@ protected: next_mark = ARM_DWT_CYCCNT + (T1+T2+T3); FastPin::fastset(port, hi); if(b&0x80) { - while((next_mark - ARM_DWT_CYCCNT) > (T3+(3*(F_CPU/24000000)))); + while((next_mark - ARM_DWT_CYCCNT) > (T3+(2*(F_CPU/24000000)))); FastPin::fastset(port, lo); } else { while((next_mark - ARM_DWT_CYCCNT) > (T2+T3+(2*(F_CPU/24000000)))); @@ -93,7 +93,7 @@ protected: FastPin::fastset(port, hi); if(b&0x80) { - while((next_mark - ARM_DWT_CYCCNT) > (T3+(3*(F_CPU/24000000)))); + while((next_mark - ARM_DWT_CYCCNT) > (T3+(2*(F_CPU/24000000)))); FastPin::fastset(port, lo); } else { while((next_mark - ARM_DWT_CYCCNT) > (T2+T3+(2*(F_CPU/24000000)))); -- cgit v1.2.3 From 36c48066c20863716e24adfa2f9282c7e0429107 Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Thu, 9 Oct 2014 22:02:09 -0700 Subject: Bring DMX kicking and screaming into the FastLED2.1 world --- FastLED.h | 62 ++++++++++++++++++++++++++---------------------------------- dmx.h | 65 ++++++++++++++++++++++++++++++++++----------------------------- 2 files changed, 62 insertions(+), 65 deletions(-) diff --git a/FastLED.h b/FastLED.h index af3d77de..60684718 100644 --- a/FastLED.h +++ b/FastLED.h @@ -13,6 +13,14 @@ #include #endif +#ifdef DmxSimple_h +#include +#endif + +#ifdef DmxSerial_h +#include +#endif + #include "controller.h" #include "fastpin.h" #include "fastspi.h" @@ -22,7 +30,7 @@ #include "colorutils.h" #include "colorpalettes.h" #include "chipsets.h" -#include "dmx.h" +#include "./dmx.h" #include "smartmatrix_t3.h" #include "noise.h" #include "power_mgt.h" @@ -38,23 +46,6 @@ enum ESPIChipsets { enum ESM { SMART_MATRIX }; -enum EClocklessChipsets { - DMX - // TM1809, - // TM1804, - // TM1803, - // WS2811, - // WS2812, - // WS2812B, - // UCS1903, - // UCS1903B, - // WS2811_400, - // // NEOPIXEL, - // GW6205, - // GW6205_400, - // TM1829 -}; - template class NEOPIXEL : public WS2811Controller800Khz {}; template class TM1829 : public TM1829Controller800Khz {}; template class TM1809 : public TM1809Controller800Khz {}; @@ -69,6 +60,12 @@ template class WS2811_400 : public WS2811Con template class GW6205 : public GW6205Controller800Khz {}; template class GW6205_400 : public GW6205Controller400Khz {}; template class LPD1886 : public LPD1886Controller1250Khz {}; +#ifdef DmxSimple_h +template class DMXSIMPLE : public DMXSimpleController {}; +#endif +#ifdef DmxSerial_h +template class DMXSERIAL : public DMXSerialController {}; +#endif // template class LPD8806 : public LPD8806Controller {}; // template class WS2801 : public WS2801Controller {}; @@ -160,6 +157,18 @@ public: return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); } + template class CHIPSET> + static CLEDController &addLeds(struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) { + static CHIPSET c; + return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); + } + + template class CHIPSET, EOrder RGB_ORDER> + static CLEDController &addLeds(struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) { + static CHIPSET c; + return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); + } + #ifdef SmartMatrix_h template static CLEDController &addLeds(struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) @@ -170,23 +179,6 @@ public: } #endif -#ifdef FASTSPI_USE_DMX_SIMPLE - template - static CLEDController &addLeds(struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) - { - switch(CHIPSET) { - case DMX: { static DMXController controller; return addLeds(&controller, data, nLedsOrOffset, nLedsIfOffset); } - } - } - - template - static CLEDController &addLeds(struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) { - switch(CHIPSET) { - case DMX: {static DMXController controller; return addLeds(&controller, data, nLedsOrOffset, nLedsIfOffset); } - } - } -#endif - #ifdef HAS_BLOCKLESS template static CLEDController &addLeds(struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) { diff --git a/dmx.h b/dmx.h index 1556e515..8892302f 100644 --- a/dmx.h +++ b/dmx.h @@ -1,12 +1,13 @@ #ifndef __INC_DMX_H #define __INC_DMX_H -//#ifdef DmxSimple_H -//#if USE_DMX_SIMPLE -#ifdef FASTSPI_USE_DMX_SIMPLE + +#ifdef DmxSimple_h #include +#define HAS_DMX_SIMPLE + // note - dmx simple must be included before FastSPI for this code to be enabled -template class DMXController : public CLEDController { +template class DMXSimpleController : public CLEDController { public: // initialize the LED controller virtual void init() { DmxSimple.usePin(DATA_PIN); } @@ -17,26 +18,27 @@ public: for(int iChannel = 1; iChannel <= count; iChannel++) { DmxSimple.write(iChannel, 0); } } +protected: // set all the leds on the controller to a given color - virtual void showColor(const struct CRGB & data, int nLeds, uint8_t scale = 255) { + virtual void showColor(const struct CRGB & data, int nLeds, CRGB scale) { int count = min(nLeds, DMX_SIZE / 3); int iChannel = 1; for(int i = 0; i < count; i++) { - DmxSimple.write(iChannel++, scale8(data[RGB_BYTE0(RGB_ORDER)], scale)); - DmxSimple.write(iChannel++, scale8(data[RGB_BYTE1(RGB_ORDER)], scale)); - DmxSimple.write(iChannel++, scale8(data[RGB_BYTE2(RGB_ORDER)], scale)); + DmxSimple.write(iChannel++, scale8(data[RGB_BYTE0(RGB_ORDER)], scale.raw[RGB_BYTE0(RGB_ORDER)])); + DmxSimple.write(iChannel++, scale8(data[RGB_BYTE1(RGB_ORDER)], scale.raw[RGB_BYTE1(RGB_ORDER)])); + DmxSimple.write(iChannel++, scale8(data[RGB_BYTE2(RGB_ORDER)], scale.raw[RGB_BYTE2(RGB_ORDER)])); } } - // note that the uint8_ts will be in the order that you want them sent out to the device. + // note that the uint8_ts will be in the order that you want them sent out to the device. // nLeds is the number of RGB leds being written to - virtual void show(const struct CRGB *data, int nLeds, uint8_t scale = 255) { + virtual void show(const struct CRGB *data, int nLeds, CRGB scale) { int count = min(nLeds, DMX_SIZE / 3); int iChannel = 1; for(int i = 0; i < count; i++) { - DmxSimple.write(iChannel++, scale8(data[i][RGB_BYTE0(RGB_ORDER)], scale)); - DmxSimple.write(iChannel++, scale8(data[i][RGB_BYTE1(RGB_ORDER)], scale)); - DmxSimple.write(iChannel++, scale8(data[i][RGB_BYTE2(RGB_ORDER)], scale)); + DmxSimple.write(iChannel++, scale8(data[i][RGB_BYTE0(RGB_ORDER)], scale.raw[RGB_BYTE0(RGB_ORDER)])); + DmxSimple.write(iChannel++, scale8(data[i][RGB_BYTE1(RGB_ORDER)], scale.raw[RGB_BYTE1(RGB_ORDER)])); + DmxSimple.write(iChannel++, scale8(data[i][RGB_BYTE2(RGB_ORDER)], scale.raw[RGB_BYTE2(RGB_ORDER)])); } } @@ -47,39 +49,42 @@ public: #endif }; -#elif defined(FASTSPI_USE_DMX_SERIAL) +#endif -template class DMXController : public CLEDController { +#ifdef DmxSerial_h +#include + +template class DMXSerialController : public CLEDController { public: // initialize the LED controller virtual void init() { DMXSerial.init(DMXController); } // clear out/zero out the given number of leds. virtual void clearLeds(int nLeds) { - int count = min(nLeds * 3, DMX_SIZE); - for(int iChannel = 0; iChannel < count; iChannel++) { DmxSimple.write(iChannel, 0); } + int count = min(nLeds * 3, DMXSERIAL_MAX); + for(int iChannel = 0; iChannel < count; iChannel++) { DMXSerial.write(iChannel, 0); } } // set all the leds on the controller to a given color - virtual void showColor(const struct CRGB & data, int nLeds, uint8_t scale = 255) { - int count = min(nLeds, DMX_SIZE / 3); + virtual void showColor(const struct CRGB & data, int nLeds, CRGB scale) { + int count = min(nLeds, DMXSERIAL_MAX / 3); int iChannel = 0; for(int i = 0; i < count; i++) { - DMXSerial.write(iChannel++, scale8(data[RGB_BYTE0(RGB_ORDER)], scale)); - DMXSerial.write(iChannel++, scale8(data[RGB_BYTE1(RGB_ORDER)], scale)); - DMXSerial.write(iChannel++, scale8(data[RGB_BYTE2(RGB_ORDER)], scale)); + DMXSerial.write(iChannel++, scale8(data[RGB_BYTE0(RGB_ORDER)], scale.raw[RGB_BYTE0(RGB_ORDER)])); + DMXSerial.write(iChannel++, scale8(data[RGB_BYTE1(RGB_ORDER)], scale.raw[RGB_BYTE1(RGB_ORDER)])); + DMXSerial.write(iChannel++, scale8(data[RGB_BYTE2(RGB_ORDER)], scale.raw[RGB_BYTE2(RGB_ORDER)])); } } - // note that the uint8_ts will be in the order that you want them sent out to the device. + // note that the uint8_ts will be in the order that you want them sent out to the device. // nLeds is the number of RGB leds being written to - virtual void show(const struct CRGB *data, int nLeds, uint8_t scale = 255) { - int count = min(nLeds, DMX_SIZE / 3); + virtual void show(const struct CRGB *data, int nLeds, CRGB scale) { + int count = min(nLeds, DMXSERIAL_MAX / 3); int iChannel = 0; for(int i = 0; i < count; i++) { - DMXSerial.write(iChannel++, scale8(data[i][RGB_BYTE0(RGB_ORDER)], scale)); - DMXSerial.write(iChannel++, scale8(data[i][RGB_BYTE1(RGB_ORDER)], scale)); - DMXSerial.write(iChannel++, scale8(data[i][RGB_BYTE2(RGB_ORDER)], scale)); + DMXSerial.write(iChannel++, scale8(data[i][RGB_BYTE0(RGB_ORDER)], scale.raw[RGB_BYTE0(RGB_ORDER)])); + DMXSerial.write(iChannel++, scale8(data[i][RGB_BYTE1(RGB_ORDER)], scale.raw[RGB_BYTE1(RGB_ORDER)])); + DMXSerial.write(iChannel++, scale8(data[i][RGB_BYTE2(RGB_ORDER)], scale.raw[RGB_BYTE2(RGB_ORDER)])); } } @@ -89,7 +94,7 @@ public: virtual void show(const struct CARGB *data, int nLeds, uint8_t scale = 255) = 0; #endif }; - +#define HAS_DMX_SERIAL #endif -#endif \ No newline at end of file +#endif -- cgit v1.2.3 From 3cf1699835f982f0aeb728c18bc2119acd52de7b Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Fri, 10 Oct 2014 11:54:29 -0700 Subject: APA102 bug fixing and speed tweaking --- chipsets.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/chipsets.h b/chipsets.h index e2929990..7faf384e 100644 --- a/chipsets.h +++ b/chipsets.h @@ -129,13 +129,13 @@ class WS2803Controller : public WS2801Controller +template class APA102Controller : public CLEDController { typedef SPIOutput SPI; SPI mSPI; void startBoundary() { mSPI.writeWord(0); mSPI.writeWord(0); } - void endBoundary() { mSPI.writeWord(0xFFFF); mSPI.writeWord(0xFFFF); } + void endBoundary() { /*mSPI.writeWord(0xFFFF); mSPI.writeWord(0xFFFF); */} inline void writeLed(uint8_t r, uint8_t g, uint8_t b) __attribute__((always_inline)) { mSPI.writeByte(0xFF); mSPI.writeByte(r); mSPI.writeByte(g); mSPI.writeByte(b); -- cgit v1.2.3 From baf6dfaf9eb1ea4e57956398f42555d0d0e3d828 Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Fri, 10 Oct 2014 17:23:53 -0700 Subject: Tweak bit-bang'd SPI timing for running high speed chipsets --- fastspi_bitbang.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fastspi_bitbang.h b/fastspi_bitbang.h index a779ddd3..b596f628 100644 --- a/fastspi_bitbang.h +++ b/fastspi_bitbang.h @@ -105,8 +105,8 @@ private: } public: - #define SPI_DELAY delaycycles< ((SPI_SPEED-2) / 2)>(); - #define SPI_DELAY_HALF delaycycles< ((SPI_SPEED-4) / 4)>(); + #define SPI_DELAY delaycycles<1+((SPI_SPEED-2) / 2)>(); + #define SPI_DELAY_HALF delaycycles<1+ ((SPI_SPEED-4) / 4)>(); // write the BIT'th bit out via spi, setting the data pin then strobing the clcok template __attribute__((always_inline, hot)) inline static void writeBit(uint8_t b) { -- cgit v1.2.3 From c18ee923241103a33f2024582bb4785f3ac5ea81 Mon Sep 17 00:00:00 2001 From: Mark Kriegsman Date: Sat, 11 Oct 2014 08:21:14 -0400 Subject: Added CHSVPalette16, CHSVPalette256, and map_data_into_colors_through_palette( data, NUM_LEDS, leds, palette), which saves typing, and lets you focus on 'data' and 'palette' separately. --- colorpalettes.cpp | 16 ++-- colorpalettes.h | 16 ++-- colorutils.cpp | 103 +++++++++++++++----- colorutils.h | 274 ++++++++++++++++++++++++++++++++++++++++++++++++++---- 4 files changed, 352 insertions(+), 57 deletions(-) diff --git a/colorpalettes.cpp b/colorpalettes.cpp index 9591279a..8cec8980 100644 --- a/colorpalettes.cpp +++ b/colorpalettes.cpp @@ -24,7 +24,7 @@ // use each one, so you only 'pay for' those you actually use. -extern const TProgmemPalette16 CloudColors_p PROGMEM = +extern const TProgmemRGBPalette16 CloudColors_p PROGMEM = { CRGB::Blue, CRGB::DarkBlue, @@ -47,7 +47,7 @@ extern const TProgmemPalette16 CloudColors_p PROGMEM = CRGB::SkyBlue }; -extern const TProgmemPalette16 LavaColors_p PROGMEM = +extern const TProgmemRGBPalette16 LavaColors_p PROGMEM = { CRGB::Black, CRGB::Maroon, @@ -70,7 +70,7 @@ extern const TProgmemPalette16 LavaColors_p PROGMEM = }; -extern const TProgmemPalette16 OceanColors_p PROGMEM = +extern const TProgmemRGBPalette16 OceanColors_p PROGMEM = { CRGB::MidnightBlue, CRGB::DarkBlue, @@ -93,7 +93,7 @@ extern const TProgmemPalette16 OceanColors_p PROGMEM = CRGB::LightSkyBlue }; -extern const TProgmemPalette16 ForestColors_p PROGMEM = +extern const TProgmemRGBPalette16 ForestColors_p PROGMEM = { CRGB::DarkGreen, CRGB::DarkGreen, @@ -117,7 +117,7 @@ extern const TProgmemPalette16 ForestColors_p PROGMEM = }; // HSV Rainbow -extern const TProgmemPalette16 RainbowColors_p PROGMEM = +extern const TProgmemRGBPalette16 RainbowColors_p PROGMEM = { 0xFF0000, 0xD52A00, 0xAB5500, 0xAB7F00, 0xABAB00, 0x56D500, 0x00FF00, 0x00D52A, @@ -127,7 +127,7 @@ extern const TProgmemPalette16 RainbowColors_p PROGMEM = // HSV Rainbow colors with alternatating stripes of black #define RainbowStripesColors_p RainbowStripeColors_p -extern const TProgmemPalette16 RainbowStripeColors_p PROGMEM = +extern const TProgmemRGBPalette16 RainbowStripeColors_p PROGMEM = { 0xFF0000, 0x000000, 0xAB5500, 0x000000, 0xABAB00, 0x000000, 0x00FF00, 0x000000, @@ -139,7 +139,7 @@ extern const TProgmemPalette16 RainbowStripeColors_p PROGMEM = // Basically, everything but the greens, which tend to make // people's skin look unhealthy. This palette is good for // lighting at a club or party, where it'll be shining on people. -extern const TProgmemPalette16 PartyColors_p PROGMEM = +extern const TProgmemRGBPalette16 PartyColors_p PROGMEM = { 0x5500AB, 0x84007C, 0xB5004B, 0xE5001B, 0xE81700, 0xB84700, 0xAB7700, 0xABAB00, @@ -153,7 +153,7 @@ extern const TProgmemPalette16 PartyColors_p PROGMEM = // the usual 0-255, as the last 15 colors will be // 'wrapping around' from the hot end to the cold end, // which looks wrong. -extern const TProgmemPalette16 HeatColors_p PROGMEM = +extern const TProgmemRGBPalette16 HeatColors_p PROGMEM = { 0x000000, 0x330000, 0x660000, 0x990000, 0xCC0000, 0xFF0000, diff --git a/colorpalettes.h b/colorpalettes.h index b9622694..340349d4 100644 --- a/colorpalettes.h +++ b/colorpalettes.h @@ -13,23 +13,23 @@ // use each one, so you only 'pay for' those you actually use. -extern const TProgmemPalette16 CloudColors_p PROGMEM; -extern const TProgmemPalette16 LavaColors_p PROGMEM; -extern const TProgmemPalette16 OceanColors_p PROGMEM; -extern const TProgmemPalette16 ForestColors_p PROGMEM; +extern const TProgmemRGBPalette16 CloudColors_p PROGMEM; +extern const TProgmemRGBPalette16 LavaColors_p PROGMEM; +extern const TProgmemRGBPalette16 OceanColors_p PROGMEM; +extern const TProgmemRGBPalette16 ForestColors_p PROGMEM; // HSV Rainbow -extern const TProgmemPalette16 RainbowColors_p PROGMEM; +extern const TProgmemRGBPalette16 RainbowColors_p PROGMEM; // HSV Rainbow colors with alternatating stripes of black #define RainbowStripesColors_p RainbowStripeColors_p -extern const TProgmemPalette16 RainbowStripeColors_p PROGMEM; +extern const TProgmemRGBPalette16 RainbowStripeColors_p PROGMEM; // HSV color ramp: blue purple ping red orange yellow (and back) // Basically, everything but the greens, which tend to make // people's skin look unhealthy. This palette is good for // lighting at a club or party, where it'll be shining on people. -extern const TProgmemPalette16 PartyColors_p PROGMEM; +extern const TProgmemRGBPalette16 PartyColors_p PROGMEM; // Approximate "black body radiation" palette, akin to // the FastLED 'HeatColor' function. @@ -37,6 +37,6 @@ extern const TProgmemPalette16 PartyColors_p PROGMEM; // the usual 0-255, as the last 15 colors will be // 'wrapping around' from the hot end to the cold end, // which looks wrong. -extern const TProgmemPalette16 HeatColors_p PROGMEM; +extern const TProgmemRGBPalette16 HeatColors_p PROGMEM; #endif diff --git a/colorutils.cpp b/colorutils.cpp index 6a12fb11..781651a8 100644 --- a/colorutils.cpp +++ b/colorutils.cpp @@ -456,41 +456,98 @@ CRGB ColorFromPalette( const CRGBPalette256& pal, uint8_t index, uint8_t brightn } -void UpscalePalette(const CRGBPalette16& srcpal16, CRGBPalette256& destpal256) +CHSV ColorFromPalette( const struct CHSVPalette16& pal, uint8_t index, uint8_t brightness, TBlendType blendType) { - for( int i = 0; i < 256; i++) { - destpal256[(uint8_t)(i)] = ColorFromPalette( srcpal16, i); + uint8_t hi4 = index >> 4; + uint8_t lo4 = index & 0x0F; + + // CRGB rgb1 = pal[ hi4]; + const CHSV* entry = &(pal[0]) + hi4; + + uint8_t hue1 = entry->hue; + uint8_t sat1 = entry->sat; + uint8_t val1 = entry->val; + + uint8_t blend = lo4 && (blendType != NOBLEND); + + if( blend ) { + + if( hi4 == 15 ) { + entry = &(pal[0]); + } else { + entry++; + } + + uint8_t f2 = lo4 << 4; + uint8_t f1 = 256 - f2; + + uint8_t hue2 = entry->hue; + uint8_t sat2 = entry->sat; + uint8_t val2 = entry->val; + + sat1 = scale8_LEAVING_R1_DIRTY( sat1, f1); + val1 = scale8_LEAVING_R1_DIRTY( val1, f1); + + sat2 = scale8_LEAVING_R1_DIRTY( sat2, f2); + val2 = scale8_LEAVING_R1_DIRTY( val2, f2); + + // cleanup_R1(); + + // These sums can't overflow, so no qadd8 needed. + sat1 += sat2; + val1 += val2; + + uint8_t deltaHue = (uint8_t)(hue2 - hue1); + if( deltaHue & 0x80 ) { + // go backwards + hue1 -= scale8( 256 - deltaHue, f2); + } else { + // go forwards + hue1 += scale8( deltaHue, f2); + } + + cleanup_R1(); + } + + if( brightness != 255) { + val1 = scale8_video( val1, brightness); } + + return CHSV( hue1, sat1, val1); } -#if 0 -// replaced by PartyColors_p -void SetupPartyColors(CRGBPalette16& pal) -{ - fill_gradient( pal, 0, CHSV( HUE_PURPLE,255,255), 7, CHSV(HUE_YELLOW - 18,255,255), FORWARD_HUES); - fill_gradient( pal, 8, CHSV( HUE_ORANGE,255,255), 15, CHSV(HUE_BLUE + 18,255,255), BACKWARD_HUES); -} -#endif -void fill_palette(CRGB* L, uint16_t N, uint8_t startIndex, uint8_t incIndex, - const CRGBPalette16& pal, uint8_t brightness, TBlendType blendType) +CHSV ColorFromPalette( const struct CHSVPalette256& pal, uint8_t index, uint8_t brightness, TBlendType) { - uint8_t colorIndex = startIndex; - for( uint16_t i = 0; i < N; i++) { - L[i] = ColorFromPalette( pal, colorIndex, brightness, blendType); - colorIndex += incIndex; + CHSV hsv;// = *( &(pal[0]) + index ); + + if( brightness != 255) { + hsv.value = scale8_video( hsv.value, brightness); } + + return hsv; } -void fill_palette(CRGB* L, uint16_t N, uint8_t startIndex, uint8_t incIndex, - const CRGBPalette256& pal, uint8_t brightness, TBlendType blendType) +void UpscalePalette(const struct CRGBPalette16& srcpal16, struct CRGBPalette256& destpal256) { - uint8_t colorIndex = startIndex; - for( uint16_t i = 0; i < N; i++) { - L[i] = ColorFromPalette( pal, colorIndex, brightness, blendType); - colorIndex += incIndex; + for( int i = 0; i < 256; i++) { + destpal256[(uint8_t)(i)] = ColorFromPalette( srcpal16, i); } } +void UpscalePalette(const struct CHSVPalette16& srcpal16, struct CHSVPalette256& destpal256) +{ + for( int i = 0; i < 256; i++) { + destpal256[(uint8_t)(i)] = ColorFromPalette( srcpal16, i); + } +} +#if 0 +// replaced by PartyColors_p +void SetupPartyColors(CRGBPalette16& pal) +{ + fill_gradient( pal, 0, CHSV( HUE_PURPLE,255,255), 7, CHSV(HUE_YELLOW - 18,255,255), FORWARD_HUES); + fill_gradient( pal, 8, CHSV( HUE_ORANGE,255,255), 15, CHSV(HUE_BLUE + 18,255,255), BACKWARD_HUES); +} +#endif diff --git a/colorutils.h b/colorutils.h index c2e1ec65..1a3a8d85 100644 --- a/colorutils.h +++ b/colorutils.h @@ -253,7 +253,7 @@ CRGB HeatColor( uint8_t temperature); // Palettes // -// Palettes map an 8-bit value (0..255) to an RGB color. +// RGB Palettes map an 8-bit value (0..255) to an RGB color. // // You can create any color palette you wish; a couple of starters // are provided: Forest, Clouds, Lava, Ocean, Rainbow, and Rainbow Stripes. @@ -309,11 +309,189 @@ CRGB HeatColor( uint8_t temperature); class CRGBPalette16; class CRGBPalette256; -typedef prog_uint32_t TProgmemPalette16[16]; +class CHSVPalette16; +class CHSVPalette256; +typedef prog_uint32_t TProgmemRGBPalette16[16]; +typedef prog_uint32_t TProgmemHSVPalette16[16]; +#define TProgmemPalette16 TProgmemRGBPalette16 // Convert a 16-entry palette to a 256-entry palette -void UpscalePalette(const CRGBPalette16& srcpal16, CRGBPalette256& destpal256); +void UpscalePalette(const struct CRGBPalette16& srcpal16, struct CRGBPalette256& destpal256); +void UpscalePalette(const struct CHSVPalette16& srcpal16, struct CHSVPalette256& destpal256); +class CHSVPalette16 { +public: + CHSV entries[16]; + CHSVPalette16() {}; + CHSVPalette16( const CHSV& c00,const CHSV& c01,const CHSV& c02,const CHSV& c03, + const CHSV& c04,const CHSV& c05,const CHSV& c06,const CHSV& c07, + const CHSV& c08,const CHSV& c09,const CHSV& c10,const CHSV& c11, + const CHSV& c12,const CHSV& c13,const CHSV& c14,const CHSV& c15 ) + { + entries[0]=c00; entries[1]=c01; entries[2]=c02; entries[3]=c03; + entries[4]=c04; entries[5]=c05; entries[6]=c06; entries[7]=c07; + entries[8]=c08; entries[9]=c09; entries[10]=c10; entries[11]=c11; + entries[12]=c12; entries[13]=c13; entries[14]=c14; entries[15]=c15; + }; + + CHSVPalette16( const CHSVPalette16& rhs) + { + memmove8( &(entries[0]), &(rhs.entries[0]), sizeof( entries)); + } + CHSVPalette16& operator=( const CHSVPalette16& rhs) + { + memmove8( &(entries[0]), &(rhs.entries[0]), sizeof( entries)); + return *this; + } + + CHSVPalette16( const TProgmemHSVPalette16& rhs) + { + for( uint8_t i = 0; i < 16; i++) { + CRGB xyz = pgm_read_dword_near( rhs + i); + entries[i].hue = xyz.red; + entries[i].sat = xyz.green; + entries[i].val = xyz.blue; + } + } + CHSVPalette16& operator=( const TProgmemHSVPalette16& rhs) + { + for( uint8_t i = 0; i < 16; i++) { + CRGB xyz = pgm_read_dword_near( rhs + i); + entries[i].hue = xyz.red; + entries[i].sat = xyz.green; + entries[i].val = xyz.blue; + } + return *this; + } + + inline CHSV& operator[] (uint8_t x) __attribute__((always_inline)) + { + return entries[x]; + } + inline const CHSV& operator[] (uint8_t x) const __attribute__((always_inline)) + { + return entries[x]; + } + + inline CHSV& operator[] (int x) __attribute__((always_inline)) + { + return entries[(uint8_t)x]; + } + inline const CHSV& operator[] (int x) const __attribute__((always_inline)) + { + return entries[(uint8_t)x]; + } + + operator CHSV*() + { + return &(entries[0]); + } + + CHSVPalette16( const CHSV& c1) + { + fill_solid( &(entries[0]), 16, c1); + } + CHSVPalette16( const CHSV& c1, const CHSV& c2) + { + fill_gradient( &(entries[0]), 16, c1, c2); + } + CHSVPalette16( const CHSV& c1, const CHSV& c2, const CHSV& c3) + { + fill_gradient( &(entries[0]), 16, c1, c2, c3); + } + CHSVPalette16( const CHSV& c1, const CHSV& c2, const CHSV& c3, const CHSV& c4) + { + fill_gradient( &(entries[0]), 16, c1, c2, c3, c4); + } + +}; + +class CHSVPalette256 { +public: + CHSV entries[256]; + CHSVPalette256() {}; + CHSVPalette256( const CHSV& c00,const CHSV& c01,const CHSV& c02,const CHSV& c03, + const CHSV& c04,const CHSV& c05,const CHSV& c06,const CHSV& c07, + const CHSV& c08,const CHSV& c09,const CHSV& c10,const CHSV& c11, + const CHSV& c12,const CHSV& c13,const CHSV& c14,const CHSV& c15 ) + { + CHSVPalette16 p16(c00,c01,c02,c03,c04,c05,c06,c07, + c08,c09,c10,c11,c12,c13,c14,c15); + *this = p16; + }; + + CHSVPalette256( const CHSVPalette256& rhs) + { + memmove8( &(entries[0]), &(rhs.entries[0]), sizeof( entries)); + } + CHSVPalette256& operator=( const CHSVPalette256& rhs) + { + memmove8( &(entries[0]), &(rhs.entries[0]), sizeof( entries)); + return *this; + } + + CHSVPalette256( const CHSVPalette16& rhs16) + { + UpscalePalette( rhs16, *this); + } + CHSVPalette256& operator=( const CHSVPalette16& rhs16) + { + UpscalePalette( rhs16, *this); + return *this; + } + + CHSVPalette256( const TProgmemRGBPalette16& rhs) + { + CHSVPalette16 p16(rhs); + *this = p16; + } + CHSVPalette256& operator=( const TProgmemRGBPalette16& rhs) + { + CHSVPalette16 p16(rhs); + *this = p16; + return *this; + } + + inline CHSV& operator[] (uint8_t x) __attribute__((always_inline)) + { + return entries[x]; + } + inline const CHSV& operator[] (uint8_t x) const __attribute__((always_inline)) + { + return entries[x]; + } + + inline CHSV& operator[] (int x) __attribute__((always_inline)) + { + return entries[(uint8_t)x]; + } + inline const CHSV& operator[] (int x) const __attribute__((always_inline)) + { + return entries[(uint8_t)x]; + } + + operator CHSV*() + { + return &(entries[0]); + } + + CHSVPalette256( const CHSV& c1) + { + fill_solid( &(entries[0]), 256, c1); + } + CHSVPalette256( const CHSV& c1, const CHSV& c2) + { + fill_gradient( &(entries[0]), 256, c1, c2); + } + CHSVPalette256( const CHSV& c1, const CHSV& c2, const CHSV& c3) + { + fill_gradient( &(entries[0]), 256, c1, c2, c3); + } + CHSVPalette256( const CHSV& c1, const CHSV& c2, const CHSV& c3, const CHSV& c4) + { + fill_gradient( &(entries[0]), 256, c1, c2, c3, c4); + } +}; class CRGBPalette16 { public: @@ -340,13 +518,27 @@ public: return *this; } - CRGBPalette16( const TProgmemPalette16& rhs) + CRGBPalette16( const CHSVPalette16& rhs) + { + for( uint8_t i = 0; i < 16; i++) { + entries[i] = rhs.entries[i]; // implicit HSV-to-RGB conversion + } + } + CRGBPalette16& operator=( const CHSVPalette16& rhs) + { + for( uint8_t i = 0; i < 16; i++) { + entries[i] = rhs.entries[i]; // implicit HSV-to-RGB conversion + } + return *this; + } + + CRGBPalette16( const TProgmemRGBPalette16& rhs) { for( uint8_t i = 0; i < 16; i++) { entries[i] = pgm_read_dword_near( rhs + i); } } - CRGBPalette16& operator=( const TProgmemPalette16& rhs) + CRGBPalette16& operator=( const TProgmemRGBPalette16& rhs) { for( uint8_t i = 0; i < 16; i++) { entries[i] = pgm_read_dword_near( rhs + i); @@ -438,6 +630,20 @@ public: return *this; } + CRGBPalette256( const CHSVPalette256& rhs) + { + for( int i = 0; i < 256; i++) { + entries[i] = rhs.entries[i]; // implicit HSV-to-RGB conversion + } + } + CRGBPalette256& operator=( const CHSVPalette256& rhs) + { + for( int i = 0; i < 256; i++) { + entries[i] = rhs.entries[i]; // implicit HSV-to-RGB conversion + } + return *this; + } + CRGBPalette256( const CRGBPalette16& rhs16) { UpscalePalette( rhs16, *this); @@ -448,12 +654,12 @@ public: return *this; } - CRGBPalette256( const TProgmemPalette16& rhs) + CRGBPalette256( const TProgmemRGBPalette16& rhs) { CRGBPalette16 p16(rhs); *this = p16; } - CRGBPalette256& operator=( const TProgmemPalette16& rhs) + CRGBPalette256& operator=( const TProgmemRGBPalette16& rhs) { CRGBPalette16 p16(rhs); *this = p16; @@ -519,6 +725,9 @@ public: }; + + + typedef enum { NOBLEND=0, BLEND=1 } TBlendType; CRGB ColorFromPalette( const CRGBPalette16& pal, @@ -531,20 +740,49 @@ CRGB ColorFromPalette( const CRGBPalette256& pal, uint8_t brightness=255, TBlendType blendType=NOBLEND ); +CHSV ColorFromPalette( const CHSVPalette16& pal, + uint8_t index, + uint8_t brightness=255, + TBlendType blendType=BLEND); -// Fill a range of LEDs with a sequece of entryies from a palette -void fill_palette(CRGB* L, uint16_t N, - uint8_t startIndex, uint8_t incIndex, - const CRGBPalette16& pal, - uint8_t brightness=255, - TBlendType blendType=BLEND); +CHSV ColorFromPalette( const CHSVPalette256& pal, + uint8_t index, + uint8_t brightness=255, + TBlendType blendType=NOBLEND ); -void fill_palette(CRGB* L, uint16_t N, - uint8_t startIndex, uint8_t incIndex, - const CRGBPalette256& pal, - uint8_t brightness=255, - TBlendType blendType=NOBLEND); +// Fill a range of LEDs with a sequece of entryies from a palette +template +void fill_palette(CRGB* L, uint16_t N, uint8_t startIndex, uint8_t incIndex, + const PALETTE& pal, uint8_t brightness, TBlendType blendType) +{ + uint8_t colorIndex = startIndex; + for( uint16_t i = 0; i < N; i++) { + L[i] = ColorFromPalette( pal, colorIndex, brightness, blendType); + colorIndex += incIndex; + } +} +template +void map_data_into_colors_through_palette( + uint8_t *dataArray, uint16_t dataCount, + CRGB* targetColorArray, + const PALETTE& pal, + uint8_t brightness=255, + uint8_t opacity=255, + TBlendType blendType=BLEND) +{ + for( uint16_t i = 0; i < dataCount; i++) { + uint8_t d = dataArray[i]; + CRGB rgb = ColorFromPalette( pal, d, brightness, blendType); + if( opacity == 255 ) { + targetColorArray[i] = rgb; + } else { + targetColorArray[i].nscale8( 256 - opacity); + rgb.nscale8_video( opacity); + targetColorArray[i] += rgb; + } + } +} #endif -- cgit v1.2.3 From a860bcdae51ed41ca7399c82bacb7b792ed21aa0 Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Sun, 12 Oct 2014 02:54:25 -0700 Subject: Tweaking platform info --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 0cd2eeb3..cb9cdc3a 100644 --- a/README.md +++ b/README.md @@ -61,10 +61,11 @@ LPD6803, HL1606, and "595"-style shift registers are no longer supported by the Right now the library is supported on a variety of arduino compatable platforms. If it's ARM or AVR and uses the arduino software (or a modified version of it to build) then it is likely supported. Note that we have a long list of upcoming platforms to support, so if you don't see what you're looking for here, ask, it may be on the roadmap (or may already be supported). N.B. at the moment we are only supporting the stock compilers that ship with the arduino software. Support for upgraded compilers, as well as using AVR studio and skipping the arduino entirely, should be coming in a near future release. * Arduino & compatibles - straight up arduino devices, uno, duo, leonardo, mega, nano, etc... +* Adafruit Trinket & Gemma - Trinket Pro may be supported, but haven't tested to confirm yet * Teensy 2, Teensy++ 2, Teensy 3.1 - arduino compataible from pjrc.com with some extra goodies (note the teensy 3 is ARM, not AVR!) * Arduino Due and the digistump DigiX -What types of platforms are we thinking about supporting in the future? Here's a short list: , MSP430, ChipKit32, Maple, Beagleboard +What types of platforms are we thinking about supporting in the future? Here's a short list: RFDuino, SparkCore, MSP430, ChipKit32, Maple, Beagleboard ## What about that name? -- cgit v1.2.3 From 61141426ea3f43f97c2c3695b305ed75f52695aa Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Sun, 12 Oct 2014 02:54:46 -0700 Subject: Add alias for APA104 to WS2811 --- FastLED.h | 1 + 1 file changed, 1 insertion(+) diff --git a/FastLED.h b/FastLED.h index 60684718..afb117c6 100644 --- a/FastLED.h +++ b/FastLED.h @@ -56,6 +56,7 @@ template class UCS1903B : public UCS1903BCon template class WS2812 : public WS2811Controller800Khz {}; template class WS2812B : public WS2811Controller800Khz {}; template class WS2811 : public WS2811Controller800Khz {}; +template class APA104 : public WS2811Controller800Khz {}; template class WS2811_400 : public WS2811Controller400Khz {}; template class GW6205 : public GW6205Controller800Khz {}; template class GW6205_400 : public GW6205Controller400Khz {}; -- cgit v1.2.3 From 0137036552a2c74e4cab7aa4a845871c417970a8 Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Sun, 12 Oct 2014 15:01:12 -0700 Subject: Adding a bunch of keywords in prep for merging back to master --- keywords.txt | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/keywords.txt b/keywords.txt index 40ba2bd2..2591b1ef 100644 --- a/keywords.txt +++ b/keywords.txt @@ -26,6 +26,11 @@ getBrightness KEYWORD2 show KEYWORD2 clear KEYWORD2 showColor KEYWORD2 +setTemperature KEYWORD2 +setCorrection KEYWORD2 +setDither KEYWORD2 +countFPS KEYWORD2 +getFPS KEYWORD2 # Lib8tion methods qadd8 KEYWORD2 @@ -232,17 +237,27 @@ CRGB::YellowGreen KEYWORD2 # Chipsets LPD8806 LITERAL1 WS2801 LITERAL1 +WS2803 LITERAL1 +P9813 LITERAL1 SM16716 LITERAL1 -DMX LITERAL1 +APA102 LITERAL1 +DMXSERIAL LITERAL1 +DMXSIMPLE LITERAL1 +TM1829 LITERAL1 TM1809 LITERAL1 TM1804 LITERAL1 TM1803 LITERAL1 +APA104 LITERAL1 WS2811 LITERAL1 WS2812 LITERAL1 WS2812B LITERAL1 WS2811_400 LITERAL1 NEOPIXEL LITERAL1 UCS1903 LITERAL1 +UCS1903B LITERAL1 +GW6205 LITERAL1 +GW6205B LITERAL1 +LPD1886 LITERAL1 # RGB orderings RGB LITERAL1 @@ -251,4 +266,3 @@ GRB LITERAL1 GBR LITERAL1 BRG LITERAL1 BGR LITERAL1 - -- cgit v1.2.3 From 986bede1d46742d6d93fa2ef9f4afb556208ba6f Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Sun, 12 Oct 2014 15:20:16 -0700 Subject: Update release notes --- release_notes.md | 106 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ release_notes.txt | 65 --------------------------------- 2 files changed, 106 insertions(+), 65 deletions(-) create mode 100644 release_notes.md delete mode 100644 release_notes.txt diff --git a/release_notes.md b/release_notes.md new file mode 100644 index 00000000..a921fe66 --- /dev/null +++ b/release_notes.md @@ -0,0 +1,106 @@ +FastLED2.1 +========== + +* Remove Squant (takes up space!) +* A number of performance/memory improvements +* Added support for the following platforms: + * Arduino due + * Teensy 3.1 +* Added the following LED chipsets: + * USC1903_400 + * GW6205 / GW6205_400 + * APA102 + * APA104 + * LPD1886 + * P9813 + * SmartMatrix +* Added multiple examples: + * ColorPalette - show off the color palette code + * ColorTemperature - show off the color correction code + * Fire2012 + * Fire2012WithPalette + * Multiple led controller examples + * Noise + * NoisePlayground + * NoisePlusPalette + * SmartMatrix - show off SmartMatrix support + * XYMatrix - show how to use a mtrix layout of leds +* Added color correction +* Added dithering +* Added power management support +* Added support for color palettes +* Added easing functions +* Added fast trig functions +* Added simplex noise functions +* Added color utility functions +* Fixed DMXSERIAL/DMXSIMPLE support +* Timing adjustments for existing SPI chipsets +* Cleaned up the code layout to make platform support easier +* Many bug fixes + +FastLED2 +======== + +## Full release of the library + +## Release Candidate 6 +* Rename library, offically, to FastLED, move to github +* Update keywords with all the new stuffs + +## Release Candidate 5 +* Gemma and Trinket: supported except for global "setBrightness" + +## Release Candidate 4 +* Added NEOPIXEL as a synonym for WS2811 +* Fix WS2811/WS2812B timings, bring it in line to exactly 1.25ns/bit. +* Fix handling of constant color definitions (damn you, gcc!) + +## Release Candidate 3 +* Fixed bug when Clock and Data were on the same port +* Added ability to set pixel color directly from HSV +* Added ability to retrieve current random16 seed + +## Release Candidate 2 +* mostly bug fixes +* Fix SPI macro definitions for latest teensy3 software update +* Teensy 2 compilation fix +* hsv2rgb_rainbow performance fix + +## Release Candidate 1 +* New unified/simplified API for adding/using controllers +* fleshout clockless chip support +* add hsv (spectrum and rainbow style colors) +* high speed memory management operations +* library for interpolation/easing functions +* various api changes, addition of clear and showColor functions +* scale value applied to all show methods +* bug fixes for SM16716 +* performance improvements, lpd8806 exceeds 22Mbit now +* hardware def fixes +* allow alternate rgb color orderings +* high speed math methods +* rich CRGB structure + +## Preview 3 +* True hardware SPI support for teensy (up to 20Mbit output!) +* Minor bug fixes/tweaks + +## Preview 2 +* Rename pin class to FastPin +* Replace latch with select, more accurate description of what it does +* Enforce intra-frame timing for ws2801s +* SM16716 support +* Add #define FAST_SPI_INTERRUPTS_WRITE_PINS to make sure world is ok w/interrupts and SPI +* Add #define FORCE_SOFTWARE_SPI for those times when you absolutely don't want to use hardware SPI, ev +en if you're using the hardware SPI pins +* Add pin definitions for the arduino megas - should fix ws2811 support +* Add pin definitions for the leonardo - should fix spi support and pin mappings +* Add warnings when pin definitions are missing +* Added google+ community for fastspi users - https://plus.google.com/communities/109127054924227823508 +# Add pin definitions for Teensy++ 2.0 + + +## Preview 1 +* Initial release + + diff --git a/release_notes.txt b/release_notes.txt deleted file mode 100644 index 11d2a6c6..00000000 --- a/release_notes.txt +++ /dev/null @@ -1,65 +0,0 @@ -* FastLED2 - -* Full release of the library - -* Release Candidate 6 -* Rename library, offically, to FastLED, move to github -* Update keywords with all the new stuffs - -Release Candidate 5 -* Gemma and Trinket: supported except for global "setBrightness" - -Release Candidate 4 -* Added NEOPIXEL as a synonym for WS2811 -* Fix WS2811/WS2812B timings, bring it in line to exactly 1.25ns/bit. -* Fix handling of constant color definitions (damn you, gcc!) - -Release Candidate 3 -* Fixed bug when Clock and Data were on the same port -* Added ability to set pixel color directly from HSV -* Added ability to retrieve current random16 seed - -Release Candidate 2 -* mostly bug fixes -* Fix SPI macro definitions for latest teensy3 software update -* Teensy 2 compilation fix -* hsv2rgb_rainbow performance fix - -Release Candidate 1 -* New unified/simplified API for adding/using controllers -* fleshout clockless chip support -* add hsv (spectrum and rainbow style colors) -* high speed memory management operations -* library for interpolation/easing functions -* various api changes, addition of clear and showColor functions -* scale value applied to all show methods -* bug fixes for SM16716 -* performance improvements, lpd8806 exceeds 22Mbit now -* hardware def fixes -* allow alternate rgb color orderings -* high speed math methods -* rich CRGB structure - -Preview 3 -* True hardware SPI support for teensy (up to 20Mbit output!) -* Minor bug fixes/tweaks - -Preview 2 -* Rename pin class to FastPin -* Replace latch with select, more accurate description of what it does -* Enforce intra-frame timing for ws2801s -* SM16716 support -* Add #define FAST_SPI_INTERRUPTS_WRITE_PINS to make sure world is ok w/interrupts and SPI -* Add #define FORCE_SOFTWARE_SPI for those times when you absolutely don't want to use hardware SPI, ev -en if you're using the hardware SPI pins -* Add pin definitions for the arduino megas - should fix ws2811 support -* Add pin definitions for the leonardo - should fix spi support and pin mappings -* Add warnings when pin definitions are missing -* Added google+ community for fastspi users - https://plus.google.com/communities/109127054924227823508 -# Add pin definitions for Teensy++ 2.0 - - -Preview 1 -* Initial release - - -- cgit v1.2.3 From 5b2c7cfa635c264a8b8823535d7b916735dda5ef Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Sun, 12 Oct 2014 15:31:11 -0700 Subject: Add even more keywords --- dithertodo.txt | 18 ---------- keywords.txt | 105 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 102 insertions(+), 21 deletions(-) delete mode 100644 dithertodo.txt diff --git a/dithertodo.txt b/dithertodo.txt deleted file mode 100644 index db093189..00000000 --- a/dithertodo.txt +++ /dev/null @@ -1,18 +0,0 @@ -SPI: -x due -x bitbang -x k20 -x avr -o stm - -Clockless: -X due -x k20 -x avr -o stm - -Chipsets: -x LPD8806 -x WS2801 -x P9813 -x SM1676 diff --git a/keywords.txt b/keywords.txt index 2591b1ef..c652466f 100644 --- a/keywords.txt +++ b/keywords.txt @@ -15,6 +15,15 @@ FastPin KEYWORD1 FastSPI KEYWORD1 FastSPI_LED2 KEYWORD1 +CRGBPalette16 KEYWORD1 +CRGBPalette256 KEYWORD1 +CHSVPalette16 KEYWORD1 +CHSVPalette256 KEYWORD1 +CHSVPalette16 KEYWORD1 +CHSVPalette256 KEYWORD1 +CRGBPalette16 KEYWORD1 +CRGBPalette256 KEYWORD1 + ####################################### # Methods and Functions (KEYWORD2) ####################################### @@ -32,6 +41,21 @@ setDither KEYWORD2 countFPS KEYWORD2 getFPS KEYWORD2 +# Noise methods +inoise16_raw KEYWORD2 +inoise8_raw KEYWORD2 +inoise16 KEYWORD2 +inoise8 KEYWORD2 +fill_2dnoise16 KEYWORD2 +fill_2dnoise8 KEYWORD2 +fill_noise16 KEYWORD2 +fill_noise8 KEYWORD2 +fill_raw_2dnoise16 KEYWORD2 +fill_raw_2dnoise16into8 KEYWORD2 +fill_raw_2dnoise8 KEYWORD2 +fill_raw_noise16into8 KEYWORD2 +fill_raw_noise8 KEYWORD2 + # Lib8tion methods qadd8 KEYWORD2 qadd7 KEYWORD2 @@ -40,9 +64,6 @@ add8 KEYWORD2 sub8 KEYWORD2 scale8 KEYWORD2 scale8_video KEYWORD2 -scale8_LEAVING_R1_DIRTY KEYWORD2 -nscale8_LEAVING_R1_DIRTY KEYWORD2 -scale8_video_LEAVING_R1_DIRTY KEYWORD2 cleanup_R1 KEYWORD2 nscale8x3 KEYWORD2 nscale8x3_video KEYWORD2 @@ -56,8 +77,10 @@ qmul8 KEYWORD2 abs8 KEYWORD2 dim8_raw KEYWORD2 dim8_video KEYWORD2 +dim8_lin KEYWORD2 brighten8_raw KEYWORD2 brighten8_video KEYWORD2 +brighten8_lin KEYWORD2 random8 KEYWORD2 random16 KEYWORD2 random8 KEYWORD2 @@ -70,13 +93,43 @@ random16_add_entropy KEYWORD2 sin16_avr KEYWORD2 sin16_C KEYWORD2 cos16 KEYWORD2 +sin8_C KEYWORD2 +cos8 KEYWORD2 lerp8by8 KEYWORD2 lerp16by16 KEYWORD2 lerp16by8 KEYWORD2 lerp15by8 KEYWORD2 +lerp15by16 KEYWORD2 +map8 KEYWORD2 +ease8InOutQuad KEYWORD2 ease8InOutCubic KEYWORD2 ease8InOutApprox KEYWORD2 ease8InOutApprox KEYWORD2 +triwave8 KEYWORD2 +quadwave8 KEYWORD2 +cubicwave8 KEYWORD2 +sqrt16 KEYWORD2 + +# Color util methods +blend KEYWORD2 +nblend KEYWORD2 +ColorFromPalette KEYWORD2 +HeatColor KEYWORD2 +UpscalePalette KEYWORD2 +blend KEYWORD2 +fadeLightBy KEYWORD2 +fadeToBlackBy KEYWORD2 +fade_raw KEYWORD2 +fade_video KEYWORD2 +fill_gradient KEYWORD2 +fill_gradient_RGB KEYWORD2 +fill_palette KEYWORD2 +fill_rainbow KEYWORD2 +fill_solid KEYWORD2 +map_data_into_colors_through_palette KEYWORD2 +nblend KEYWORD2 +nscale8 KEYWORD2 +nscale8_video KEYWORD2 # HSV methods hsv2grb_rainbow KEYWORD2 @@ -266,3 +319,49 @@ GRB LITERAL1 GBR LITERAL1 BRG LITERAL1 BGR LITERAL1 + +# hue literals +HUE_RED LITERAL1 +HUE_ORANGE LITERAL1 +HUE_YELLOW LITERAL1 +HUE_GREEN LITERAL1 +HUE_AQUA LITERAL1 +HUE_BLUE LITERAL1 +HUE_PURPLE LITERAL1 +HUE_PINK LITERAL1 + +# Color correction values +TypicalSMD5050 LITERAL1 +TypicalLEDStrip LITERAL1 +Typical8mmPixel LITERAL1 +TypicalPixelString LITERAL1 +UncorrectedColor LITERAL1 +Candle LITERAL1 +Tungsten40W LITERAL1 +Tungsten100W LITERAL1 +Halogen LITERAL1 +CarbonArc LITERAL1 +HighNoonSun LITERAL1 +DirectSunlight LITERAL1 +OvercastSky LITERAL1 +ClearBlueSky LITERAL1 +WarmFluorescent LITERAL1 +StandardFluorescent LITERAL1 +CoolWhiteFluorescent LITERAL1 +FullSpectrumFluorescent LITERAL1 +GrowLightFluorescent LITERAL1 +BlackLightFluorescent LITERAL1 +MercuryVapor LITERAL1 +SodiumVapor LITERAL1 +MetalHalide LITERAL1 +HighPressureSodium LITERAL1 +UncorrectedTemperature LITERAL1 + +# Color util literals +FORWARD_HUES LITERAL1 +BACKWARD_HUES LITERAL1 +SHORTEST_HUES LITERAL1 +LONGEST_HUES LITERAL1 +BLEND LITERAL1 +NOBLEND LITERAL1 + -- cgit v1.2.3 From 3e312c671122164efd41a679eb58c8950222a611 Mon Sep 17 00:00:00 2001 From: Mark Kriegsman Date: Tue, 14 Oct 2014 12:13:52 -0400 Subject: Fix for #79, improve HSV ramps to/from pure black/white. --- colorutils.cpp | 30 ++++++++++++++++++++++++++++-- colorutils.h | 16 ++++++++++++++++ 2 files changed, 44 insertions(+), 2 deletions(-) diff --git a/colorutils.cpp b/colorutils.cpp index 781651a8..995db69e 100644 --- a/colorutils.cpp +++ b/colorutils.cpp @@ -83,12 +83,16 @@ void fill_gradient_RGB( CRGB* leds, bdistance87 = (endcolor.b - startcolor.b) << 7; uint16_t pixeldistance = endpos - startpos; - uint16_t p2 = pixeldistance / 2; - int16_t divisor = p2 ? p2 : 1; + int16_t divisor = pixeldistance ? pixeldistance : 1; + saccum87 rdelta87 = rdistance87 / divisor; saccum87 gdelta87 = gdistance87 / divisor; saccum87 bdelta87 = bdistance87 / divisor; + rdelta87 *= 2; + gdelta87 *= 2; + bdelta87 *= 2; + accum88 r88 = startcolor.r << 8; accum88 g88 = startcolor.g << 8; accum88 b88 = startcolor.b << 8; @@ -485,6 +489,28 @@ CHSV ColorFromPalette( const struct CHSVPalette16& pal, uint8_t index, uint8_t b uint8_t sat2 = entry->sat; uint8_t val2 = entry->val; + // Now some special casing for blending to or from + // either black or white. Black and white don't have + // proper 'hue' of their own, so when ramping from + // something else to/from black/white, we set the 'hue' + // of the black/white color to be the same as the hue + // of the other color, so that you get the expected + // brightness or saturation ramp, with hue staying + // constant: + + // If we are starting from white (sat=0) + // or black (val=0), adopt the target hue. + if( sat1 == 0 || val1 == 0) { + hue1 = hue2; + } + + // If we are ending at white (sat=0) + // or black (val=0), adopt the starting hue. + if( sat2 == 0 || val2 == 0) { + hue2 = hue1; + } + + sat1 = scale8_LEAVING_R1_DIRTY( sat1, f1); val1 = scale8_LEAVING_R1_DIRTY( val1, f1); diff --git a/colorutils.h b/colorutils.h index 1a3a8d85..3ca9829a 100644 --- a/colorutils.h +++ b/colorutils.h @@ -72,6 +72,22 @@ void fill_gradient( T* targetArray, endpos = startpos; } + // If we're fading toward black (val=0) or white (sat=0), + // then set the endhue to the starthue. + // This lets us ramp smoothly to black or white, regardless + // of what 'hue' was set in the endcolor (since it doesn't matter) + if( endcolor.value == 0 || endcolor.saturation == 0) { + endcolor.hue = startcolor.hue; + } + + // Similarly, if we're fading in from black (val=0) or white (sat=0) + // then set the starthue to the endhue. + // This lets us ramp smoothly up from black or white, regardless + // of what 'hue' was set in the startcolor (since it doesn't matter) + if( statcolor.value == 0 || startcolor.saturation == 0) { + startcolor.hue = endcolor.hue; + } + saccum87 huedistance87; saccum87 satdistance87; saccum87 valdistance87; -- cgit v1.2.3 From a96f0213e889ad956c0761d3c8e1c45438b9ab39 Mon Sep 17 00:00:00 2001 From: Mark Kriegsman Date: Tue, 14 Oct 2014 12:16:37 -0400 Subject: Typo fix. --- colorutils.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/colorutils.h b/colorutils.h index 3ca9829a..55772c7f 100644 --- a/colorutils.h +++ b/colorutils.h @@ -84,7 +84,7 @@ void fill_gradient( T* targetArray, // then set the starthue to the endhue. // This lets us ramp smoothly up from black or white, regardless // of what 'hue' was set in the startcolor (since it doesn't matter) - if( statcolor.value == 0 || startcolor.saturation == 0) { + if( startcolor.value == 0 || startcolor.saturation == 0) { startcolor.hue = endcolor.hue; } -- cgit v1.2.3 From 4fe768688f421b42eff299782300348ddb465c6d Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Sun, 19 Oct 2014 17:26:41 -0400 Subject: Change default order of APA102 RGB to BGR. --- chipsets.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/chipsets.h b/chipsets.h index 7faf384e..5e15baa6 100644 --- a/chipsets.h +++ b/chipsets.h @@ -129,7 +129,7 @@ class WS2803Controller : public WS2801Controller +template class APA102Controller : public CLEDController { typedef SPIOutput SPI; SPI mSPI; @@ -137,8 +137,8 @@ class APA102Controller : public CLEDController { void startBoundary() { mSPI.writeWord(0); mSPI.writeWord(0); } void endBoundary() { /*mSPI.writeWord(0xFFFF); mSPI.writeWord(0xFFFF); */} - inline void writeLed(uint8_t r, uint8_t g, uint8_t b) __attribute__((always_inline)) { - mSPI.writeByte(0xFF); mSPI.writeByte(r); mSPI.writeByte(g); mSPI.writeByte(b); + inline void writeLed(uint8_t b0, uint8_t b1, uint8_t b2) __attribute__((always_inline)) { + mSPI.writeByte(0xFF); mSPI.writeByte(b0); mSPI.writeByte(b1); mSPI.writeByte(b2); } public: -- cgit v1.2.3 From 4c281d1f03a7874ae7783f4d7564a04d556e0e31 Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Mon, 20 Oct 2014 22:58:03 -0400 Subject: Forcibly break compilation under arduino 1.5.7 and later until I can fix GCC compilation. --- led_sysdefs.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/led_sysdefs.h b/led_sysdefs.h index f9f4578b..c49410d0 100644 --- a/led_sysdefs.h +++ b/led_sysdefs.h @@ -34,6 +34,9 @@ typedef volatile uint8_t RwReg; /**< Read-Write 8-bit register (volatile u #endif +#if defined(ARDUINO) && defined(FASTLED_AVR) && ARDUINO >= 157 +#error Arduion versions 1.5.7 and later not yet supported by FastLED for AVR +#endif // Arduino.h needed for convinience functions digitalPinToPort/BitMask/portOutputRegister and the pinMode methods. #include -- cgit v1.2.3 From ad408b049e7738a01773e735c46527c15565d1a3 Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Tue, 21 Oct 2014 20:31:57 -0400 Subject: tweaking release notes --- release_notes.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/release_notes.md b/release_notes.md index a921fe66..3df2d4e2 100644 --- a/release_notes.md +++ b/release_notes.md @@ -1,8 +1,6 @@ FastLED2.1 ========== -* Remove Squant (takes up space!) -* A number of performance/memory improvements * Added support for the following platforms: * Arduino due * Teensy 3.1 @@ -37,6 +35,8 @@ FastLED2.1 * Timing adjustments for existing SPI chipsets * Cleaned up the code layout to make platform support easier * Many bug fixes +* A number of performance/memory improvements +* Remove Squant (takes up space!) FastLED2 ======== -- cgit v1.2.3 From 82894a15fd780a7b8941bde5aa8f281002734a84 Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Tue, 21 Oct 2014 22:43:16 -0400 Subject: Fix readme warning about 1.5.7 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index cb9cdc3a..e355d3fc 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ FastLED ======= IMPORTANT NOTE: If you are building for AVR based systems, please do not use any version of the arduino -IDE after 1.5.7 yet. It messes with some of the asm output which will cause you problems. +IDE 1.5.7 or later yet. It messes with some of the asm output which will cause you problems. This is a library for easily & efficiently controlling a wide variety of LED chipsets, like the ones sold by adafruit (Neopixel, LPD8806), Sparkfun (WS2801), and aliexpress. In addition to writing to the -- cgit v1.2.3 From 5e359c9d7cb7b0668f771343085a152e479471f1 Mon Sep 17 00:00:00 2001 From: Mark Kriegsman Date: Tue, 21 Oct 2014 22:50:17 -0400 Subject: Add compile-time 'warning' with FastLED version number. Bumped to 2.1.1 --- FastLED.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/FastLED.h b/FastLED.h index afb117c6..19b1b8b7 100644 --- a/FastLED.h +++ b/FastLED.h @@ -6,7 +6,10 @@ #define xstr(s) str(s) #define str(s) #s -#define FASTLED_VERSION 2001000 + +#define FASTLED_VERSION 2001001 +#warning FastLED version 2001001 (Not really a warning, just telling you here.) + #define __PROG_TYPES_COMPAT__ #ifdef SmartMatrix_h -- cgit v1.2.3 From 8416d5a77a0f576a2c10cfe32c032d86bb5a5ea1 Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Tue, 21 Oct 2014 23:01:20 -0400 Subject: Silently disable dithering if the frame rate is < 100fps --- FastLED.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/FastLED.cpp b/FastLED.cpp index 814cfbf5..c87e8e31 100644 --- a/FastLED.cpp +++ b/FastLED.cpp @@ -37,7 +37,10 @@ CLEDController &CFastLED::addLeds(CLEDController *pLed, void CFastLED::show(uint8_t scale) { CLEDController *pCur = CLEDController::head(); while(pCur) { + uint8_t d = pCur->getDither(); + if(m_nFPS < 100) { pCur->setDither(0); } pCur->showLeds(scale); + pCur->setDither(d); pCur = pCur->next(); } countFPS(); @@ -68,7 +71,10 @@ CLEDController & CFastLED::operator[](int x) { void CFastLED::showColor(const struct CRGB & color, uint8_t scale) { CLEDController *pCur = CLEDController::head(); while(pCur) { + uint8_t d = pCur->getDither(); + if(m_nFPS < 100) { pCur->setDither(0); } pCur->showColor(color, scale); + pCur->setDither(d); pCur = pCur->next(); } countFPS(); -- cgit v1.2.3 From 9b26dc0d6386bb035c8b020f9ba3d636e6b8e8d2 Mon Sep 17 00:00:00 2001 From: Mark Kriegsman Date: Fri, 24 Oct 2014 06:46:36 -0400 Subject: Fixing sin8 and sin16 keywords --- keywords.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/keywords.txt b/keywords.txt index c652466f..e1aaebec 100644 --- a/keywords.txt +++ b/keywords.txt @@ -91,9 +91,9 @@ random16_set_seed KEYWORD2 random16_get_seed KEYWORD2 random16_add_entropy KEYWORD2 sin16_avr KEYWORD2 -sin16_C KEYWORD2 +sin16 KEYWORD2 cos16 KEYWORD2 -sin8_C KEYWORD2 +sin8 KEYWORD2 cos8 KEYWORD2 lerp8by8 KEYWORD2 lerp16by16 KEYWORD2 -- cgit v1.2.3 From 50f3c8579c54cedc98ed141b433d345842efe8af Mon Sep 17 00:00:00 2001 From: Mark Kriegsman Date: Fri, 24 Oct 2014 11:46:46 -0400 Subject: Added beat (BPM) generators. --- lib8tion.h | 120 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 120 insertions(+) diff --git a/lib8tion.h b/lib8tion.h index 272d33cc..228fe8f9 100644 --- a/lib8tion.h +++ b/lib8tion.h @@ -140,6 +140,18 @@ memcpy8( dest, src, bytecount) memset8( buf, value, bytecount) + - Beat generators which return sine or sawtooth + waves in a specified number of Beats Per Minute. + Sine wave beat generators can specify a low and + high range for the output. Sawtooth wave beat + generators always range 0-255 or 0-65535. + beatsin8( BPM, low8, high8) + = (sine(beatphase) * (high8-low8)) + low8 + beatsin16( BPM, low16, high16) + = (sine(beatphase) * (high16-low16)) + low16 + beat8( BPM) = 8-bit repeating sawtooth wave + beat16( BPM) = 16-bit repeating sawtooth wave + Lib8tion is pronounced like 'libation': lie-BAY-shun @@ -1669,4 +1681,112 @@ typedef q q62; typedef q q88; typedef q q124; + + +// Beat generators - These functions produce waves at a given +// number of 'beats per minute'. Internally, they use +// the Arduino function 'millis' to track elapsed time. +// Accuracy is a bit better than one part in a thousand. +// +// beat8( BPM ) returns an 8-bit value that cycles 'BPM' times +// per minute, rising from 0 to 255, resetting to zero, +// rising up again, etc.. The output of this function +// is suitable for feeding directly into sin8, and cos8, +// triwave8, quadwave8, and cubicwave8. +// beat16( BPM ) returns a 16-bit value that cycles 'BPM' times +// per minute, rising from 0 to 65535, resetting to zero, +// rising up again, etc. The output of this function is +// suitable for feeding directly into sin16 and cos16. +// +// beatsin8( BPM, uint8_t low, uint8_t high) returns an 8-bit value that +// rises and falls in a sine wave, 'BPM' times per minute, +// between the values of 'low' and 'high'. +// beatsin16( BPM, uint16_t low, uint16_t high) returns a 16-bit value +// that rises and falls in a sine wave, 'BPM' times per +// minute, between the values of 'low' and 'high'. +// +// BPM can be supplied two ways. The simpler way of specifying BPM is as +// a simple 8-bit integer from 1-255, (e.g., "120"). +// The more sophisticated way of specifying BPM allows for fractional +// "Q8.8" fixed point number (an 'accum88') with an 8-bit integer part and +// an 8-bit fractional part. The easiest way to construct this is to multiply +// a floating point BPM value (e.g. 120.3) by 256, (e.g. resulting in 30796 +// in this case), and pass that as the 16-bit BPM argument. +// +// Originally designed to make an entire animation project pulse with brightness. +// For that effect, add this line just above your existing call to "FastLED.show()": +// +// uint8_t bright = beatsin8( 60 /*BPM*/, 192 /*dimmest*/, 255 /*brightest*/ )); +// FastLED.setBrightness( bright ); +// FastLED.show(); +// +// The entire animation will now pulse between brightness 192 and 255 once per second. + + +// The beat generators need access to a millisecond counter. +// On Arduino, this is "millis()". On other platforms, you'll +// need to provide a function with this signature: +// uint32_t get_millisecond_timer(); +// that provides similar functionality. +// You can also force use of the get_millisecond_timer function +// by #defining USE_GET_MILLISECOND_TIMER. +#if defined(ARDUINO) && !defined(USE_GET_MILLISECOND_TIMER) +// Forward declaration of Arduino function 'millis'. +uint32_t millis(); +#define GET_MILLIS (millis()) +#else +uint32_t get_millisecond_timer(); +#define GET_MILLIS (get_millisecond_timer()) +#endif + +// beat16 generates a 16-bit 'sawtooth' wave at a given BPM +LIB8STATIC uint16_t beat16( accum88 beats_per_minute) +{ + // Convert simple 8-bit BPM's to full Q8.8 accum88's if needed + if( beats_per_minute < 256) beats_per_minute <<= 8; + + // BPM is 'beats per minute', or 'beats per 60000ms'. + // To avoid using the (slower) division operator, we + // want to convert 'beats per 60000ms' to 'beats per 65536ms', + // and then use a simple, fast bit-shift to divide by 65536. + // + // The ratio 65536:60000 is 279.620266667:256; we'll call it 280:256. + // The conversion is accurate to about 0.05%, more or less, + // e.g. if you ask for "120 BPM", you'll get about "119.93". + // If you need more precision than that, you can specify a + // sixteen-bit BPM value in Q8.8 fixed-point (an 'accum88'). + return ((GET_MILLIS) * beats_per_minute * 280) >> 16; +} + +// beat8 generates an 8-bit 'sawtooth' wave at a given BPM +LIB8STATIC uint8_t beat8( accum88 beats_per_minute) +{ + return beat16( beats_per_minute) >> 8; +} + +// beatsin16 generates a 16-bit sine wave at a given BPM, +// that oscillates within a given range. +LIB8STATIC uint16_t beatsin16( accum88 beats_per_minute, uint16_t lowest = 0, uint16_t highest = 65535) +{ + uint16_t beat = beat16( beats_per_minute); + uint16_t beatsin = (sin16( beat) + 32768); + uint16_t rangewidth = highest - lowest; + uint16_t scaledbeat = scale16( beatsin, rangewidth); + uint16_t result = lowest + scaledbeat; + return result; +} + +// beatsin8 generates an 8-bit sine wave at a given BPM, +// that oscillates within a given range. +LIB8STATIC uint8_t beatsin8( accum88 beats_per_minute, uint8_t lowest = 0, uint8_t highest = 255) +{ + uint8_t beat = beat8( beats_per_minute); + uint8_t beatsin = sin8( beat); + uint8_t rangewidth = highest - lowest; + uint8_t scaledbeat = scale8( beatsin, rangewidth); + uint8_t result = lowest + scaledbeat; + return result; +} + + #endif -- cgit v1.2.3 From 2608f081daf68d403b4ee29c5d0fc982b9eb8ded Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Fri, 24 Oct 2014 12:34:59 -0400 Subject: noise tweak --- noise.cpp | 6 ++++-- noise.h | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/noise.cpp b/noise.cpp index 163d4663..f60accf7 100644 --- a/noise.cpp +++ b/noise.cpp @@ -659,7 +659,7 @@ void fill_2dnoise8(CRGB *leds, int width, int height, bool serpentine, void fill_2dnoise16(CRGB *leds, int width, int height, bool serpentine, uint8_t octaves, uint32_t x, int xscale, uint32_t y, int yscale, uint32_t time, - uint8_t hue_octaves, uint16_t hue_x, int hue_xscale, uint16_t hue_y, uint16_t hue_yscale,uint16_t hue_time, bool blend) { + uint8_t hue_octaves, uint16_t hue_x, int hue_xscale, uint16_t hue_y, uint16_t hue_yscale,uint16_t hue_time, bool blend, uint16_t hue_shift) { uint8_t V[height][width]; uint8_t H[height][width]; @@ -674,10 +674,12 @@ void fill_2dnoise16(CRGB *leds, int width, int height, bool serpentine, int w1 = width-1; int h1 = height-1; + hue_shift >>= 8; + for(int i = 0; i < height; i++) { int wb = i*width; for(int j = 0; j < width; j++) { - CRGB led(CHSV(H[h1-i][w1-j],255,V[i][j])); + CRGB led(CHSV(hue_shift + (H[h1-i][w1-j]),196,V[i][j])); int pos = j; if(serpentine && (i & 0x1)) { diff --git a/noise.h b/noise.h index b71bf0a6..4e11a318 100644 --- a/noise.h +++ b/noise.h @@ -111,6 +111,6 @@ void fill_2dnoise8(CRGB *leds, int width, int height, bool serpentine, uint8_t hue_octaves, uint16_t hue_x, int hue_xscale, uint16_t hue_y, uint16_t hue_yscale,uint16_t hue_time,bool blend); void fill_2dnoise16(CRGB *leds, int width, int height, bool serpentine, uint8_t octaves, uint32_t x, int xscale, uint32_t y, int yscale, uint32_t time, - uint8_t hue_octaves, uint16_t hue_x, int hue_xscale, uint16_t hue_y, uint16_t hue_yscale,uint16_t hue_time, bool blend); + uint8_t hue_octaves, uint16_t hue_x, int hue_xscale, uint16_t hue_y, uint16_t hue_yscale,uint16_t hue_time, bool blend, uint16_t hue_shift=0); #endif -- cgit v1.2.3