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:
authorDaniel Garcia <dgarcia@dgarcia.net>2018-10-15 01:21:13 +0300
committerDaniel Garcia <dgarcia@dgarcia.net>2018-10-15 01:21:13 +0300
commitfdba485b44ba8006383e0af46a06189173846b56 (patch)
tree6738d0b43bdfb695ff399541f93b71f1f843b738
parent691ccdc467e1c102013e2ff71b24714e901c55ee (diff)
parent38105c61de097066946f2df4d2bb2c36ddc78d7c (diff)
Merge branch 'master' of https://github.com/FastLED/FastLED
-rw-r--r--chipsets.h80
-rw-r--r--controller.h15
-rw-r--r--fastled_config.h4
-rw-r--r--platforms/esp/32/clockless_esp32.h2
4 files changed, 69 insertions, 32 deletions
diff --git a/chipsets.h b/chipsets.h
index 659eeb2c..4a50844c 100644
--- a/chipsets.h
+++ b/chipsets.h
@@ -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,