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

github.com/FastLED/FastLED.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordanielgarcia@gmail.com <danielgarcia@gmail.com@4ad4ec5c-605d-bd5c-5796-512c9b60011b>2013-11-10 05:36:14 +0400
committerdanielgarcia@gmail.com <danielgarcia@gmail.com@4ad4ec5c-605d-bd5c-5796-512c9b60011b>2013-11-10 05:36:14 +0400
commite9d4489e508a99dc9e949f7762c2d6f3529524bb (patch)
treedb02d9fe781a3bdbc3b6ebd5af148f6ffe1c7f91
parent7185b516211105fc9644063548240c0057d77012 (diff)
parentadc78ce93b7b6b009aab35e9fce94074920b6bf5 (diff)
Sync w/main FastSPI_LED2 branch
-rw-r--r--FastSPI_LED2.h3
-rw-r--r--chipsets.h21
-rw-r--r--clockless.h179
-rw-r--r--delay.h3
-rw-r--r--examples/FirstLight/FirstLight.ino13
-rw-r--r--fastpin.h15
-rw-r--r--hsv2rgb.cpp4
-rw-r--r--lib8tion.h2
-rw-r--r--preview_changes.txt7
9 files changed, 124 insertions, 123 deletions
diff --git a/FastSPI_LED2.h b/FastSPI_LED2.h
index 8bcedc93..d83c2aa9 100644
--- a/FastSPI_LED2.h
+++ b/FastSPI_LED2.h
@@ -28,6 +28,7 @@ enum EClocklessChipsets {
WS2812,
WS2812B,
UCS1903,
+ WS2811_400,
NEOPIXEL,
TM1829
};
@@ -111,6 +112,7 @@ public:
case WS2812B:
case NEOPIXEL:
case WS2811: return addLeds(new WS2811Controller800Khz<DATA_PIN>(), data, nLedsOrOffset, nLedsIfOffset);
+ case WS2811_400: return addLeds(new WS2811Controller400Khz<DATA_PIN>(), data, nLedsOrOffset, nLedsIfOffset);
}
return NULL;
}
@@ -129,6 +131,7 @@ public:
case WS2812B:
case NEOPIXEL:
case WS2811: return addLeds(new WS2811Controller800Khz<DATA_PIN, RGB_ORDER>(), data, nLedsOrOffset, nLedsIfOffset);
+ case WS2811_400: return addLeds(new WS2811Controller400Khz<DATA_PIN, RGB_ORDER>(), data, nLedsOrOffset, nLedsIfOffset);
}
return NULL;
}
diff --git a/chipsets.h b/chipsets.h
index 9979f48d..64adc837 100644
--- a/chipsets.h
+++ b/chipsets.h
@@ -93,7 +93,7 @@ template <uint8_t DATA_PIN, uint8_t CLOCK_PIN, EOrder RGB_ORDER = RGB, uint8_t S
class WS2801Controller : public CLEDController {
typedef SPIOutput<DATA_PIN, CLOCK_PIN, SPI_SPEED> SPI;
SPI mSPI;
- CMinWait<24> mWaitDelay;
+ CMinWait<500> mWaitDelay;
public:
WS2801Controller() {}
@@ -300,19 +300,22 @@ class UCS1903Controller400Khz : public ClocklessController<DATA_PIN, NS(500), NS
// TM1809 - 312.5ns, 312.5ns, 325ns
template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
class TM1809Controller800Khz : public ClocklessController<DATA_PIN, NS(350), NS(350), NS(550), RGB_ORDER> {};
-#if NO_TIME(320, 320, 550)
+#if NO_TIME(350, 350, 550)
#warning "Not enough clock cycles available for the TM1809"
#endif
-// WS2811 - 350n, 350ns, 550ns
+// WS2811 - 400ns, 400ns, 450ns
template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
-class WS2811Controller800Khz : public ClocklessController<DATA_PIN, NS(320), NS(320), NS(550), RGB_ORDER> {};
-
-template <uint8_t DATA_PIN, uint8_t DATA_PIN2, EOrder RGB_ORDER = RGB>
-class WS2811Controller2800Khz : public ClocklessController2<DATA_PIN, DATA_PIN2, NS(320), NS(320), NS(550), RGB_ORDER> {};
+class WS2811Controller800Khz : public ClocklessController<DATA_PIN, NS(400), NS(400), NS(450), RGB_ORDER> {};
+#if NO_TIME(400, 400, 450)
+#warning "No enough clock cycles available for the WS2811 (800khz)"
+#endif
-#if NO_TIME(320, 320, 550)
-#warning "Not enough clock cycles available for the WS2811"
+// WS2811@400khz - 800ns, 800ns, 900ns
+template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
+class WS2811Controller400Khz : public ClocklessController<DATA_PIN, NS(800), NS(800), NS(900), RGB_ORDER> {};
+#if NO_TIME(800, 800, 900)
+#warning "No enough clock cycles available for the WS2811 (400Khz)"
#endif
// 750NS, 750NS, 750NS
diff --git a/clockless.h b/clockless.h
index 270fcfc5..9bffb9fc 100644
--- a/clockless.h
+++ b/clockless.h
@@ -9,10 +9,10 @@
// #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)
+#define CLKS_TO_MICROS(_CLKS) ((long)(_CLKS)) / (F_CPU / 1000000L)
#else
#define NS(_NS) ( (_NS * (F_CPU / 2000000L))) / 1000
-#define CLKS_TO_MICROS(_CLKS) _CLKS / (F_CPU / 2000000L)
+#define CLKS_TO_MICROS(_CLKS) ((long)(_CLKS)) / (F_CPU / 2000000L)
#endif
// Macro for making sure there's enough time available
@@ -34,6 +34,14 @@
# endif
#endif
+// 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
+
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Base template for clockless controllers. These controllers have 3 control points in their cycle for each bit. The first point
@@ -62,23 +70,6 @@ public:
mPort = FastPin<DATA_PIN>::port();
}
- template <int N>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
- delaycycles<T1 - (_CYCLES(DATA_PIN) + 1)>(); // 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
- SET_LO; // 1/2 clock cycle if using out
- delaycycles<T2 - _CYCLES(DATA_PIN)>(); // 2nd cycle length minus 1/2 clock for out
-
- // Third cycle
- SET_LO; // 1 clock cycle if using out
- delaycycles<T3 - _CYCLES(DATA_PIN)>(); // 3rd cycle length minus 1 clock for out
- }
-
- #define END_OF_BYTE
- #define END_OF_LOOP 6 // loop compare, jump, next uint8_t load
template <int N, int ADJ>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
@@ -106,7 +97,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 = CLKS_TO_MICROS((long)nLeds * 8 * (T1 + T2 + T3));
MS_COUNTER += (microsTaken / 1000);
sei();
mWait.mark();
@@ -119,7 +110,7 @@ public:
showRGBInternal<0, true>(nLeds, scale, (const byte*)rgbdata);
// Adjust the timer
- long microsTaken = CLKS_TO_MICROS(nLeds * 8 * (T1 + T2 + T3));
+ long microsTaken = CLKS_TO_MICROS((long)nLeds * 8 * (T1 + T2 + T3));
MS_COUNTER += (microsTaken / 1000);
sei();
mWait.mark();
@@ -130,10 +121,10 @@ public:
mWait.wait();
cli();
- showRGBInternal<1, true>(nLeds, scale, (const byte*)rgbdata);
+ showRGBInternal<1, true>((long)nLeds, scale, (const byte*)rgbdata);
// Adjust the timer
- long microsTaken = CLKS_TO_MICROS(nLeds * 8 * (T1 + T2 + T3));
+ long microsTaken = CLKS_TO_MICROS((long)nLeds * 8 * (T1 + T2 + T3));
MS_COUNTER += (microsTaken / 1000);
sei();
mWait.mark();
@@ -154,7 +145,7 @@ public:
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);
+ b = INLINE_SCALE(b, scale);
register uint8_t c;
register uint8_t d;
@@ -165,11 +156,13 @@ public:
}
delaycycles<1>();
// Leave an extra 2 clocks for the next byte load
- bitSetLast<7, 0>(port, hi, lo, b);
+ bitSetLast<7, 1>(port, hi, lo, b);
+ delaycycles<1>();
+
// Leave an extra 4 clocks for the scale
- bitSetLast<6, 5>(port, hi, lo, b);
+ bitSetLast<6, 6>(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);
+ INLINE_SCALE(c, scale);
bitSetLast<5, 1>(port, hi, lo, b);
for(register byte x=5; x; x--) {
@@ -178,11 +171,13 @@ public:
}
delaycycles<1>();
// Leave an extra 2 clocks for the next byte load
- bitSetLast<7, 0>(port, hi, lo, c);
+ bitSetLast<7, 1>(port, hi, lo, c);
+ delaycycles<1>();
+
// Leave an extra 4 clocks for the scale
- bitSetLast<6, 5>(port, hi, lo, c);
+ bitSetLast<6, 6>(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);
+ INLINE_SCALE(d, scale);
bitSetLast<5, 1>(port, hi, lo, c);
for(register byte x=5; x; x--) {
@@ -194,9 +189,9 @@ public:
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);
+ bitSetLast<6, 6>(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);
+ INLINE_SCALE(b, scale);
bitSetLast<5, 6>(port, hi, lo, d);
}
cleanup_R1();
@@ -231,7 +226,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 = CLKS_TO_MICROS((long)nLeds * 8 * (T1 + T2 + T3));
MS_COUNTER += (microsTaken / 1000);
sei();
mWait.mark();
@@ -244,7 +239,7 @@ public:
showRGBInternal<0, true>(nLeds, scale, (const byte*)rgbdata);
// Adjust the timer
- long microsTaken = CLKS_TO_MICROS(nLeds * 8 * (T1 + T2 + T3));
+ long microsTaken = CLKS_TO_MICROS((long)nLeds * 8 * (T1 + T2 + T3));
MS_COUNTER += (microsTaken / 1000);
sei();
mWait.mark();
@@ -258,73 +253,63 @@ public:
showRGBInternal<1, true>(nLeds, scale, (const byte*)rgbdata);
// Adjust the timer
- long microsTaken = CLKS_TO_MICROS(nLeds * 8 * (T1 + T2 + T3));
+ 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<DATA_PIN>::fastset(port, hi);
+ delaycycles<T1 - 5>(); // 5 cycles - 2 store, 1 and, 1 test, 1 if
+ if(b & 0x80) { FastPin<DATA_PIN>::fastset(port, hi); } else { FastPin<DATA_PIN>::fastset(port, lo); }
+ b <<= 1;
+ delaycycles<T2 - 2>(); // 2 cycles, 1 store/skip, 1 shift
+ FastPin<DATA_PIN>::fastset(port, lo);
+ delaycycles<T3 - 5>(); // 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<DATA_PIN>::fastset(port, hi);
+ delaycycles<T1 - 6>();
+ if(b & 0x80) { FastPin<DATA_PIN>::fastset(port, hi); } else { FastPin<DATA_PIN>::fastset(port, lo); }
+ delaycycles<T2 - 2>(); // 4 cycles, 2 store, store/skip
+ FastPin<DATA_PIN>::fastset(port, lo);
+ }
+
+ // This method is made static to force making register Y available to use for data on AVR - if the method is non-static, then
+ // gcc will use register Y for the this pointer.
template<int SKIP, bool ADVANCE> static void showRGBInternal(register int nLeds, register uint8_t scale, register const byte *rgbdata) {
register byte *data = (byte*)rgbdata;
+ register data_t mask = FastPin<DATA_PIN>::mask();
register data_ptr_t port = FastPin<DATA_PIN>::port();
nLeds *= (3 + SKIP);
register uint8_t *end = data + nLeds;
- register data_t hi = FastPin<DATA_PIN>::hival();
- register data_t lo = FastPin<DATA_PIN>::loval();;
+ register data_t hi = *port | mask;
+ register data_t lo = *port & ~mask;
*port = lo;
register uint32_t b;
- b = ADVANCE ? data[SKIP + RGB_BYTE0(RGB_ORDER)] :rgbdata[SKIP + RGB_BYTE0(RGB_ORDER)];
+ b = ((ADVANCE)?data: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
- // will bite me in the ass at some point, I know it.
- for(register uint32_t i = 7; i > 0; i--) {
- SET_HI;
- delaycycles<T1 - 3>(); // 3 cycles - 1 store, 1 test, 1 if
- if(b & 0x80) { SET_HI; } else { SET_LO; }
- b <<= 1;
- delaycycles<T2 - 3>(); // 3 cycles, 1 store, 1 store/skip, 1 shift
- SET_LO;
- delaycycles<T3 - 3>(); // 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
- SET_HI;
- delaycycles<T1 - 3>();
- if(b & 0x80) { SET_HI; } else { SET_LO; }
- delaycycles<T2 - 2>(); // 4 cycles, 2 store, store/skip
- SET_LO;
-
- b = ADVANCE ? data[SKIP + RGB_BYTE1(RGB_ORDER)] :rgbdata[SKIP + RGB_BYTE1(RGB_ORDER)];
- b = scale8(b, scale);
+ // 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<T3 - 5>(); // 1 store, 2 load, 1 mul, 1 shift,
- for(register uint32_t i = 7; i > 0; i--) {
- SET_HI;
- delaycycles<T1 - 3>(); // 3 cycles - 1 store, 1 test, 1 if
- if(b & 0x80) { SET_HI; } else { SET_LO; }
- b <<= 1;
- delaycycles<T2 - 3>(); // 3 cycles, 1 store, 1 store/skip, 1 shift
- SET_LO;
- delaycycles<T3 - 3>(); // 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
- SET_HI;
- delaycycles<T1 - 3>();
- if(b & 0x80) { SET_HI; } else { SET_LO; }
- delaycycles<T2 - 2>(); // 4 cycles, 2 store, store/skip
- SET_LO;
+ // Write second byte
+ write8Bits(port, hi, lo, b);
- b = ADVANCE ? data[SKIP + RGB_BYTE2(RGB_ORDER)] :rgbdata[SKIP + RGB_BYTE2(RGB_ORDER)];
- b = scale8(b, scale);
+ b = ((ADVANCE)?data:rgbdata)[SKIP + RGB_BYTE2(RGB_ORDER)];
+ INLINE_SCALE(b, scale);
data += 3 + SKIP;
if((RGB_ORDER & 0070) == 0) {
@@ -333,29 +318,13 @@ public:
delaycycles<T3 - 5>(); // 1 store, 2 load, 1 mul, 1 shift,
}
- for(register uint32_t i = 7; i > 0; i--) {
- SET_HI;
- delaycycles<T1 - 3>(); // 3 cycles - 1 store, 1 test, 1 if
- if(b & 0x80) { SET_HI; } else { SET_LO; }
- b <<= 1;
- delaycycles<T2 - 3>(); // 3 cycles, 1 store, 1 store/skip, 1 shift
- SET_LO;
- delaycycles<T3 - 3>(); // 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
- SET_HI;
- delaycycles<T1 - 3>();
- if(b & 0x80) { SET_HI; } else { SET_LO; }
- delaycycles<T2 - 2>(); // 4 cycles, 2 store, store/skip
- SET_LO;
+ // Write third byte
+ write8Bits(port, hi, lo, b);
- b = ADVANCE ? data[SKIP + RGB_BYTE0(RGB_ORDER)] :rgbdata[SKIP + RGB_BYTE0(RGB_ORDER)];
- b = scale8(b, scale);
+ b = ((ADVANCE)?data:rgbdata)[SKIP + RGB_BYTE0(RGB_ORDER)];
+ INLINE_SCALE(b, scale);
- delaycycles<T3 - 8>(); // 1 store, 2 load (with increment), 1 mul, 1 shift, 1 cmp, 1 branch backwards, 1 movim
+ delaycycles<T3 - 11>(); // 1 store, 2 load (with increment), 1 mul, 1 shift, 1 cmp, 1 branch backwards, 1 movim
};
}
};
@@ -389,7 +358,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 = CLKS_TO_MICROS((long)nLeds * 8 * (T1 + T2 + T3));
MS_COUNTER += (microsTaken / 1000);
savedClock.restore();
sei();
@@ -405,7 +374,7 @@ public:
showRGBInternal<0, true>(nLeds, scale, (const byte*)rgbdata);
// Adjust the timer
- long microsTaken = CLKS_TO_MICROS(nLeds * 8 * (T1 + T2 + T3));
+ long microsTaken = CLKS_TO_MICROS((long)nLeds * 8 * (T1 + T2 + T3));
MS_COUNTER += (microsTaken / 1000);
savedClock.restore();
sei();
@@ -421,7 +390,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 = CLKS_TO_MICROS((long)nLeds * 8 * (T1 + T2 + T3));
MS_COUNTER += (microsTaken / 1000);
savedClock.restore();
sei();
diff --git a/delay.h b/delay.h
index 34a19363..3797e487 100644
--- a/delay.h
+++ b/delay.h
@@ -64,6 +64,9 @@ template<int CYCLES> __attribute__((always_inline)) inline void delaycycles() {
// pre-instantiations for values small enough to not need the loop, as well as sanity holders
// for some negative values.
+template<> __attribute__((always_inline)) inline void delaycycles<-6>() {}
+template<> __attribute__((always_inline)) inline void delaycycles<-5>() {}
+template<> __attribute__((always_inline)) inline void delaycycles<-4>() {}
template<> __attribute__((always_inline)) inline void delaycycles<-3>() {}
template<> __attribute__((always_inline)) inline void delaycycles<-2>() {}
template<> __attribute__((always_inline)) inline void delaycycles<-1>() {}
diff --git a/examples/FirstLight/FirstLight.ino b/examples/FirstLight/FirstLight.ino
index 25de2673..13340ebd 100644
--- a/examples/FirstLight/FirstLight.ino
+++ b/examples/FirstLight/FirstLight.ino
@@ -1,3 +1,5 @@
+#define FORCE_SOFTWARE_SPI
+#define FORCE_SOFTWARE_PINS
#include "FastSPI_LED2.h"
///////////////////////////////////////////////////////////////////////////////////////////
@@ -7,7 +9,7 @@
//
// How many leds are in the strip?
-#define NUM_LEDS 40
+#define NUM_LEDS 60
// Data pin that led data will be written out over
#define DATA_PIN 23
@@ -27,14 +29,17 @@ void setup() {
// FastLED.addLeds<TM1803, DATA_PIN, RGB>(leds, NUM_LEDS);
// FastLED.addLeds<TM1804, DATA_PIN, RGB>(leds, NUM_LEDS);
// FastLED.addLeds<TM1809, DATA_PIN, RGB>(leds, NUM_LEDS);
- FastLED.addLeds<WS2811, DATA_PIN, RGB>(leds, NUM_LEDS);
+ // FastSPI_LED2.addLeds<WS2811, DATA_PIN, GRB>(leds+18, NUM_LEDS/3);
+ // FastLED.addLeds<WS2811, 8, RGB>(leds + 225, NUM_LEDS/4);
// FastLED.addLeds<WS2812, DATA_PIN, RGB>(leds, NUM_LEDS);
// FastLED.addLeds<WS2812B, DATA_PIN, RGB>(leds, NUM_LEDS);
+ // FastLED.addLeds<NEOPIXEL, DATA_PIN, RGB>(leds, NUM_LEDS);
+ // FastLED.addLeds<WS2811_400, DATA_PIN, RGB>(leds, NUM_LEDS);
// FastLED.addLeds<UCS1903, DATA_PIN, RGB>(leds, NUM_LEDS);
// FastLED.addLeds<WS2801, RGB>(leds, NUM_LEDS);
// FastLED.addLeds<SM16716, RGB>(leds, NUM_LEDS);
- // FastLED.addLeds<LPD8806, RGB>(leds, NUM_LEDS);
+ FastLED.addLeds<LPD8806, RGB>(leds, NUM_LEDS);
// FastLED.addLeds<WS2801, DATA_PIN, CLOCK_PIN, RGB>(leds, NUM_LEDS);
// FastLED.addLeds<SM16716, DATA_PIN, CLOCK_PIN, RGB>(leds, NUM_LEDS);
@@ -58,4 +63,4 @@ void loop() {
// Turn our current led back to black for the next loop around
leds[whiteLed] = CRGB::Black;
}
-} \ No newline at end of file
+}
diff --git a/fastpin.h b/fastpin.h
index 386fbb98..e3ba5c99 100644
--- a/fastpin.h
+++ b/fastpin.h
@@ -28,7 +28,11 @@ 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:
@@ -326,8 +330,17 @@ typedef volatile uint32_t * ptr_reg32_t;
// built on, then much higher speed access will be possible, namely with direct GPIO register accesses.
//
///////////////////////////////////////////////////////////////////////////////////////////////////////////
+#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);
-#if defined(__AVR_ATmega328P__) || defined(__AVR_ATmega168__)
+#elif defined(__AVR_ATmega328P__) || defined(__AVR_ATmega168__)
// Accelerated port definitions for arduino avrs
_IO(D); _IO(B); _IO(C);
diff --git a/hsv2rgb.cpp b/hsv2rgb.cpp
index 748144fb..b0abdab9 100644
--- a/hsv2rgb.cpp
+++ b/hsv2rgb.cpp
@@ -48,7 +48,7 @@
void hsv2rgb_raw_C (const struct CHSV & hsv, struct CRGB & rgb);
void hsv2rgb_raw_avr(const struct CHSV & hsv, struct CRGB & rgb);
-#if defined(__AVR__)
+#if defined(__AVR__) && !defined( LIB8_ATTINY )
void hsv2rgb_raw(const struct CHSV & hsv, struct CRGB & rgb)
{
hsv2rgb_raw_avr( hsv, rgb);
@@ -154,7 +154,7 @@ void hsv2rgb_raw_C (const struct CHSV & hsv, struct CRGB & rgb)
-#if defined(__AVR__)
+#if defined(__AVR__) && !defined( LIB8_ATTINY )
void hsv2rgb_raw_avr(const struct CHSV & hsv, struct CRGB & rgb)
{
uint8_t hue, saturation, value;
diff --git a/lib8tion.h b/lib8tion.h
index 276c1589..65aa6fcb 100644
--- a/lib8tion.h
+++ b/lib8tion.h
@@ -196,7 +196,7 @@ Lib8tion is pronounced like 'libation': lie-BAY-shun
// On ATtiny, we just use C implementations
#define SCALE8_C 1
#define SCALE16BY8_C 1
-#define SCALE16_C 0
+#define SCALE16_C 1
#define MUL8_C 1
#define QMUL8_C 1
#define EASE8_C 1
diff --git a/preview_changes.txt b/preview_changes.txt
index ccf4bafc..9b1a8831 100644
--- a/preview_changes.txt
+++ b/preview_changes.txt
@@ -1,5 +1,10 @@
-(Post RC3)
+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