diff options
author | Daniel Garcia <danielgarcia@gmail.com> | 2016-04-21 08:11:45 +0300 |
---|---|---|
committer | Daniel Garcia <danielgarcia@gmail.com> | 2016-04-21 08:11:45 +0300 |
commit | 4624cd902e41bcb17031e08b2d46c74ec68fcfb6 (patch) | |
tree | 600ec9aa8fc1221c5f4dcf4779172d6c5513b336 | |
parent | c376a50280d8bad78fe378c7352fb6d3acd8960c (diff) |
Fix #291 - while SK9822 claims APA102 compataibility it latches the led data in different ways.
-rw-r--r-- | FastLED.h | 4 | ||||
-rw-r--r-- | chipsets.h | 56 |
2 files changed, 60 insertions, 0 deletions
@@ -67,6 +67,7 @@ enum ESPIChipsets { SM16716, P9813, APA102, + SK9822, DOTSTAR }; @@ -206,6 +207,7 @@ public: case P9813: { static P9813Controller<DATA_PIN, CLOCK_PIN, RGB_ORDER, SPI_DATA_RATE> c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); } case DOTSTAR: case APA102: { static APA102Controller<DATA_PIN, CLOCK_PIN, RGB_ORDER, SPI_DATA_RATE> c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); } + case SK9822: { static SK9822Controller<DATA_PIN, CLOCK_PIN, RGB_ORDER, SPI_DATA_RATE> c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); } } } @@ -218,6 +220,7 @@ public: case P9813: { static P9813Controller<DATA_PIN, CLOCK_PIN> c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); } case DOTSTAR: case APA102: { static APA102Controller<DATA_PIN, CLOCK_PIN> c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); } + case SK9822: { static SK9822Controller<DATA_PIN, CLOCK_PIN> c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); } } } @@ -230,6 +233,7 @@ public: case P9813: { static P9813Controller<DATA_PIN, CLOCK_PIN, RGB_ORDER> c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); } case DOTSTAR: case APA102: { static APA102Controller<DATA_PIN, CLOCK_PIN, RGB_ORDER> c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); } + case SK9822: { static SK9822Controller<DATA_PIN, CLOCK_PIN, RGB_ORDER> c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); } } } @@ -202,6 +202,62 @@ protected: }; +/// SK9822 controller class. +/// @tparam DATA_PIN the data pin for these leds +/// @tparam CLOCK_PIN the clock pin for these leds +/// @tparam RGB_ORDER the RGB ordering for these leds +/// @tparam SPI_SPEED the clock divider used for these leds. Set using the DATA_RATE_MHZ/DATA_RATE_KHZ macros. Defaults to DATA_RATE_MHZ(24) +template <uint8_t DATA_PIN, uint8_t CLOCK_PIN, EOrder RGB_ORDER = RGB, uint8_t SPI_SPEED = DATA_RATE_MHZ(24)> +class SK9822Controller : public CPixelLEDController<RGB_ORDER> { + typedef SPIOutput<DATA_PIN, CLOCK_PIN, SPI_SPEED> SPI; + SPI mSPI; + + 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); + } + +public: + SK9822Controller() {} + + virtual void init() { + mSPI.init(); + } + +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()); +#else + uint16_t b = 0xFF00 | (uint16_t)pixels.loadAndScale0(); + mSPI.writeWord(b); + uint16_t w = pixels.loadAndScale1() << 8; + w |= pixels.loadAndScale2(); + mSPI.writeWord(w); +#endif + pixels.stepDithering(); + pixels.advanceData(); + } + + endBoundary(pixels.size()); + + mSPI.waitFully(); + mSPI.release(); + } + +}; + + ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // |