diff options
author | Daniel Garcia <dgarcia@dgarcia.net> | 2018-10-15 01:21:13 +0300 |
---|---|---|
committer | Daniel Garcia <dgarcia@dgarcia.net> | 2018-10-15 01:21:13 +0300 |
commit | fdba485b44ba8006383e0af46a06189173846b56 (patch) | |
tree | 6738d0b43bdfb695ff399541f93b71f1f843b738 | |
parent | 691ccdc467e1c102013e2ff71b24714e901c55ee (diff) | |
parent | 38105c61de097066946f2df4d2bb2c36ddc78d7c (diff) |
Merge branch 'master' of https://github.com/FastLED/FastLED
-rw-r--r-- | chipsets.h | 80 | ||||
-rw-r--r-- | controller.h | 15 | ||||
-rw-r--r-- | fastled_config.h | 4 | ||||
-rw-r--r-- | platforms/esp/32/clockless_esp32.h | 2 |
4 files changed, 69 insertions, 32 deletions
@@ -162,8 +162,19 @@ class APA102Controller : public CPixelLEDController<RGB_ORDER> { void startBoundary() { mSPI.writeWord(0); mSPI.writeWord(0); } void endBoundary(int nLeds) { int nDWords = (nLeds/32); do { mSPI.writeByte(0xFF); mSPI.writeByte(0x00); mSPI.writeByte(0x00); mSPI.writeByte(0x00); } while(nDWords--); } - inline void writeLed(uint8_t b0, uint8_t b1, uint8_t b2) __attribute__((always_inline)) { - mSPI.writeByte(0xFF); mSPI.writeByte(b0); mSPI.writeByte(b1); mSPI.writeByte(b2); + inline void writeLed(uint8_t brightness, uint8_t b0, uint8_t b1, uint8_t b2) __attribute__((always_inline)) { +#ifdef FASTLED_SPI_BYTE_ONLY + mSPI.writeByte(0xE0 | brightness); + mSPI.writeByte(b0); + mSPI.writeByte(b1); + mSPI.writeByte(b2); +#else + uint16_t b = 0xE000 | (brightness << 8) | (uint16_t)b0; + mSPI.writeWord(b); + uint16_t w = b1 << 8; + w |= b2; + mSPI.writeWord(w); +#endif } public: @@ -178,24 +189,25 @@ protected: virtual void showPixels(PixelController<RGB_ORDER> & pixels) { mSPI.select(); - startBoundary(); - while(pixels.has(1)) { -#ifdef FASTLED_SPI_BYTE_ONLY - mSPI.writeByte(0xFF); - mSPI.writeByte(pixels.loadAndScale0()); - mSPI.writeByte(pixels.loadAndScale1()); - mSPI.writeByte(pixels.loadAndScale2()); + uint8_t s0 = pixels.getScale0(), s1 = pixels.getScale1(), s2 = pixels.getScale2(); +#if FASTLED_USE_GLOBAL_BRIGHTNESS == 1 + const uint16_t maxBrightness = 0x1F; + uint16_t brightness = (max(max(s0, s1), s2) * maxBrightness >> 8) + 1; + s0 = ((uint16_t)s0 + 1) * maxBrightness / brightness - 1; + s1 = ((uint16_t)s1 + 1) * maxBrightness / brightness - 1; + s2 = ((uint16_t)s2 + 1) * maxBrightness / brightness - 1; #else - uint16_t b = 0xFF00 | (uint16_t)pixels.loadAndScale0(); - mSPI.writeWord(b); - uint16_t w = pixels.loadAndScale1() << 8; - w |= pixels.loadAndScale2(); - mSPI.writeWord(w); + const uint8_t brightness = 0x1F; #endif + + startBoundary(); + while (pixels.has(1)) { + writeLed(brightness, pixels.loadAndScale0(0, s0), pixels.loadAndScale1(0, s1), pixels.loadAndScale2(0, s2)); pixels.stepDithering(); pixels.advanceData(); } endBoundary(pixels.size()); + mSPI.waitFully(); mSPI.release(); } @@ -215,8 +227,19 @@ class SK9822Controller : public CPixelLEDController<RGB_ORDER> { void startBoundary() { mSPI.writeWord(0); mSPI.writeWord(0); } void endBoundary(int nLeds) { int nLongWords = (nLeds/32); do { mSPI.writeByte(0x00); mSPI.writeByte(0x00); mSPI.writeByte(0x00); mSPI.writeByte(0x00); } while(nLongWords--); } - inline void writeLed(uint8_t b0, uint8_t b1, uint8_t b2) __attribute__((always_inline)) { - mSPI.writeByte(0xFF); mSPI.writeByte(b0); mSPI.writeByte(b1); mSPI.writeByte(b2); + inline void writeLed(uint8_t brightness, uint8_t b0, uint8_t b1, uint8_t b2) __attribute__((always_inline)) { +#ifdef FASTLED_SPI_BYTE_ONLY + mSPI.writeByte(0xE0 | brightness); + mSPI.writeByte(b0); + mSPI.writeByte(b1); + mSPI.writeByte(b2); +#else + uint16_t b = 0xE000 | (brightness << 8) | (uint16_t)b0; + mSPI.writeWord(b); + uint16_t w = b1 << 8; + w |= b2; + mSPI.writeWord(w); +#endif } public: @@ -231,24 +254,23 @@ protected: virtual void showPixels(PixelController<RGB_ORDER> & pixels) { mSPI.select(); - startBoundary(); - while(pixels.has(1)) { -#ifdef FASTLED_SPI_BYTE_ONLY - mSPI.writeByte(0xFF); - mSPI.writeByte(pixels.loadAndScale0()); - mSPI.writeByte(pixels.loadAndScale1()); - mSPI.writeByte(pixels.loadAndScale2()); + uint8_t s0 = pixels.getScale0(), s1 = pixels.getScale1(), s2 = pixels.getScale2(); +#if FASTLED_USE_GLOBAL_BRIGHTNESS == 1 + const uint16_t maxBrightness = 0x1F; + uint16_t brightness = (max(max(s0, s1), s2) * maxBrightness >> 8) + 1; + s0 = ((uint16_t)s0 + 1) * maxBrightness / brightness - 1; + s1 = ((uint16_t)s1 + 1) * maxBrightness / brightness - 1; + s2 = ((uint16_t)s2 + 1) * maxBrightness / brightness - 1; #else - uint16_t b = 0xFF00 | (uint16_t)pixels.loadAndScale0(); - mSPI.writeWord(b); - uint16_t w = pixels.loadAndScale1() << 8; - w |= pixels.loadAndScale2(); - mSPI.writeWord(w); + const uint8_t brightness = 0x1F; #endif + + startBoundary(); + while (pixels.has(1)) { + writeLed(brightness, pixels.loadAndScale0(0, s0), pixels.loadAndScale1(0, s1), pixels.loadAndScale2(0, s2)); pixels.stepDithering(); pixels.advanceData(); } - endBoundary(pixels.size()); mSPI.waitFully(); diff --git a/controller.h b/controller.h index 61b5a94a..30e4c111 100644 --- a/controller.h +++ b/controller.h @@ -357,11 +357,18 @@ struct PixelController { template<int SLOT> __attribute__((always_inline)) inline static uint8_t advanceAndLoadAndScale(PixelController & pc) { pc.advanceData(); return pc.loadAndScale<SLOT>(pc); } template<int SLOT> __attribute__((always_inline)) inline static uint8_t advanceAndLoadAndScale(PixelController & pc, int lane) { pc.advanceData(); return pc.loadAndScale<SLOT>(pc, lane); } + template<int SLOT> __attribute__((always_inline)) inline static uint8_t advanceAndLoadAndScale(PixelController & pc, int lane, uint8_t scale) { pc.advanceData(); return pc.loadAndScale<SLOT>(pc, lane, scale); } - template<int SLOT> __attribute__((always_inline)) inline static uint8_t getd(PixelController & pc) { return pc.d[RO(SLOT)]; } - template<int SLOT> __attribute__((always_inline)) inline static uint8_t getscale(PixelController & pc) { return pc.mScale.raw[RO(SLOT)]; } + template<int SLOT> __attribute__((always_inline)) inline static uint8_t getd(PixelController & pc) { return pc.d[RO(SLOT)]; } + template<int SLOT> __attribute__((always_inline)) inline static uint8_t getscale(PixelController & pc) { return pc.mScale.raw[RO(SLOT)]; } // Helper functions to get around gcc stupidities + __attribute__((always_inline)) inline uint8_t loadAndScale0(int lane, uint8_t scale) { return loadAndScale<0>(*this, lane, scale); } + __attribute__((always_inline)) inline uint8_t loadAndScale1(int lane, uint8_t scale) { return loadAndScale<1>(*this, lane, scale); } + __attribute__((always_inline)) inline uint8_t loadAndScale2(int lane, uint8_t scale) { return loadAndScale<2>(*this, lane, scale); } + __attribute__((always_inline)) inline uint8_t advanceAndLoadAndScale0(int lane, uint8_t scale) { return advanceAndLoadAndScale<0>(*this, lane, scale); } + __attribute__((always_inline)) inline uint8_t stepAdvanceAndLoadAndScale0(int lane, uint8_t scale) { stepDithering(); return advanceAndLoadAndScale<0>(*this, lane, scale); } + __attribute__((always_inline)) inline uint8_t loadAndScale0(int lane) { return loadAndScale<0>(*this, lane); } __attribute__((always_inline)) inline uint8_t loadAndScale1(int lane) { return loadAndScale<1>(*this, lane); } __attribute__((always_inline)) inline uint8_t loadAndScale2(int lane) { return loadAndScale<2>(*this, lane); } @@ -373,6 +380,10 @@ struct PixelController { __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 getScale0() { return getscale<0>(*this); } + __attribute__((always_inline)) inline uint8_t getScale1() { return getscale<1>(*this); } + __attribute__((always_inline)) inline uint8_t getScale2() { return getscale<2>(*this); } }; template<EOrder RGB_ORDER, int LANES=1, uint32_t MASK=0xFFFFFFFF> class CPixelLEDController : public CLEDController { diff --git a/fastled_config.h b/fastled_config.h index 99500c94..6e415274 100644 --- a/fastled_config.h +++ b/fastled_config.h @@ -61,5 +61,9 @@ #define FASTLED_INTERRUPT_RETRY_COUNT 2 #endif +// Use this toggle to enable global brightness in contollers that support is (ADA102 and SK9822). +// It changes how color scaling works and uses global brightness before scaling down color values. +// This enable much more accurate color control on low brightness settings. +//#define FASTLED_USE_GLOBAL_BRIGHTNESS 1 #endif diff --git a/platforms/esp/32/clockless_esp32.h b/platforms/esp/32/clockless_esp32.h index c66eb0ce..df43ca88 100644 --- a/platforms/esp/32/clockless_esp32.h +++ b/platforms/esp/32/clockless_esp32.h @@ -49,7 +49,7 @@ * co-exist. To switch to this mode, add the following directive * before you include FastLED.h: * - * #define FASTLED_RMT_BUILTIN_DRIVER + * #define FASTLED_RMT_BUILTIN_DRIVER 1 * * There may be a performance penalty for using this mode. We need to * compute the RMT signal for the entire LED strip ahead of time, |