diff options
-rw-r--r-- | chipsets.h | 227 | ||||
-rw-r--r-- | controller.h | 103 | ||||
-rw-r--r-- | dmx.h | 82 | ||||
-rw-r--r-- | docs/.Doxyfile.swp | bin | 126976 -> 0 bytes | |||
-rw-r--r-- | platforms/arm/d21/clockless_arm_d21.h | 34 | ||||
-rw-r--r-- | platforms/arm/k20/clockless_arm_k20.h | 36 | ||||
-rw-r--r-- | platforms/arm/k20/clockless_block_arm_k20.h | 25 | ||||
-rw-r--r-- | platforms/arm/k20/smartmatrix_t3.h | 48 | ||||
-rw-r--r-- | platforms/arm/kl26/clockless_arm_kl26.h | 34 | ||||
-rw-r--r-- | platforms/arm/nrf51/clockless_arm_nrf51.h | 38 | ||||
-rw-r--r-- | platforms/arm/sam/clockless_arm_sam.h | 32 | ||||
-rw-r--r-- | platforms/arm/sam/clockless_block_arm_sam.h | 8 | ||||
-rw-r--r-- | platforms/arm/stm32/clockless_arm_stm32.h | 28 | ||||
-rw-r--r-- | platforms/avr/clockless_trinket.h | 36 |
14 files changed, 113 insertions, 618 deletions
@@ -25,21 +25,19 @@ FASTLED_NAMESPACE_BEGIN /// @tparam DATAPIN the pin to write data out on /// @tparam RGB_ORDER the RGB ordering for the led data template<uint8_t DATA_PIN, EOrder RGB_ORDER = RGB> -class PixieController : public CLEDController { +class PixieController : public CPixelLEDController<RGB_ORDER> { SoftwareSerial Serial; CMinWait<2000> mWait; public: PixieController() : Serial(-1, DATA_PIN) {} - virtual void clearLeds(int nLeds) { showColor(CRGB(0,0,0), nLeds, CRGB(0,0,0)); }; - protected: virtual void init() { Serial.begin(115200); mWait.mark(); } - void show(PixelController<RGB_ORDER> & pixels) { + virtual void showPixels(PixelController<RGB_ORDER> & pixels) { mWait.wait(); while(pixels.has(1)) { uint8_t r = pixels.loadAndScale0(); @@ -54,22 +52,6 @@ protected: mWait.mark(); } - virtual void showColor(const struct CRGB & data, int nLeds, CRGB scale) { - PixelController<RGB_ORDER> pixels(data, nLeds, scale, getDither()); - show(pixels); - } - - virtual void show(const struct CRGB *data, int nLeds, CRGB scale) { - PixelController<RGB_ORDER> pixels(data, nLeds, scale, getDither()); - show(pixels); - } - -#ifdef SUPPORT_ARGB - virtual void show(const struct CRGB *data, int nLeds, CRGB scale) { - PixelController<RGB_ORDER> pixels(data, nLeds,, scale, getDither()); - show(pixels); - } -#endif }; // template<SoftwareSerial & STREAM, EOrder RGB_ORDER = RGB> @@ -96,7 +78,7 @@ protected: /// @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(12) template <uint8_t DATA_PIN, uint8_t CLOCK_PIN, EOrder RGB_ORDER = RGB, uint8_t SPI_SPEED = DATA_RATE_MHZ(12) > -class LPD8806Controller : public CLEDController { +class LPD8806Controller : public CPixelLEDController<RGB_ORDER> { typedef SPIOutput<DATA_PIN, CLOCK_PIN, SPI_SPEED> SPI; class LPD8806_ADJUST { @@ -110,51 +92,18 @@ class LPD8806Controller : public CLEDController { }; SPI mSPI; - int mClearedLeds; - - void checkClear(int nLeds) { - if(nLeds > mClearedLeds) { - clearLine(nLeds); - mClearedLeds = nLeds; - } - } - - void clearLine(int nLeds) { - int n = ((nLeds*3 + 63) >> 6); - mSPI.writeBytesValue(0, n); - } public: + LPD8806Controller() {} virtual void init() { mSPI.init(); - mClearedLeds = 0; - } - - virtual void clearLeds(int nLeds) { - mSPI.select(); - mSPI.writeBytesValueRaw(0x80, nLeds * 3); - mSPI.writeBytesValueRaw(0, ((nLeds*3+63)>>6)); - mSPI.waitFully(); - mSPI.release(); } protected: - virtual void showColor(const struct CRGB & data, int nLeds, CRGB scale) { - mSPI.template writePixels<0, LPD8806_ADJUST, RGB_ORDER>(PixelController<RGB_ORDER>(data, nLeds, scale, getDither())); - } - - virtual void show(const struct CRGB *data, int nLeds, CRGB scale) { - // TODO rgb-ize scale - mSPI.template writePixels<0, LPD8806_ADJUST, RGB_ORDER>(PixelController<RGB_ORDER>(data, nLeds, scale, getDither())); - } - -#ifdef SUPPORT_ARGB - virtual void show(const struct CARGB *data, int nLeds, uint8_t scale) { - checkClear(nLeds); - mSPI.template writePixels<0, LPD8806_ADJUST, RGB_ORDER>(PixelController<RGB_ORDER>(data, nLeds, scale, getDither())); + virtual void showPixels(PixelController<RGB_ORDER> & pixels) { + mSPI.template writePixels<0, LPD8806_ADJUST, RGB_ORDER>(pixels); } -#endif }; @@ -170,7 +119,7 @@ protected: /// @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(1) template <uint8_t DATA_PIN, uint8_t CLOCK_PIN, EOrder RGB_ORDER = RGB, uint8_t SPI_SPEED = DATA_RATE_MHZ(1)> -class WS2801Controller : public CLEDController { +class WS2801Controller : public CPixelLEDController<RGB_ORDER> { typedef SPIOutput<DATA_PIN, CLOCK_PIN, SPI_SPEED> SPI; SPI mSPI; CMinWait<1000> mWaitDelay; @@ -179,7 +128,7 @@ public: virtual void init() { mSPI.init(); - mWaitDelay.mark(); + mWaitDelay.mark(); } virtual void clearLeds(int nLeds) { @@ -190,25 +139,11 @@ public: protected: - virtual void showColor(const struct CRGB & data, int nLeds, CRGB scale) { - mWaitDelay.wait(); - mSPI.template writePixels<0, DATA_NOP, RGB_ORDER>(PixelController<RGB_ORDER>(data, nLeds, scale, getDither())); - mWaitDelay.mark(); - } - - virtual void show(const struct CRGB *data, int nLeds, CRGB scale) { - mWaitDelay.wait(); - mSPI.template writePixels<0, DATA_NOP, RGB_ORDER>(PixelController<RGB_ORDER>(data, nLeds, scale, getDither())); - mWaitDelay.mark(); - } - -#ifdef SUPPORT_ARGB - virtual void show(const struct CRGB *data, int nLeds, CRGB scale) { + virtual void showPixels(PixelController<RGB_ORDER> & pixels) { mWaitDelay.wait(); - mSPI.template writePixels<0, DATA_NOP, RGB_ORDER>(PixelController<RGB_ORDER>(data, nLeds, scale, getDither())); + mSPI.template writePixels<0, DATA_NOP, RGB_ORDER>(pixels); mWaitDelay.mark(); } -#endif }; template <uint8_t DATA_PIN, uint8_t CLOCK_PIN, EOrder RGB_ORDER = RGB, uint8_t SPI_SPEED = DATA_RATE_MHZ(25)> @@ -226,7 +161,7 @@ class WS2803Controller : public WS2801Controller<DATA_PIN, CLOCK_PIN, RGB_ORDER, /// @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 = BGR, uint8_t SPI_SPEED = DATA_RATE_MHZ(24)> -class APA102Controller : public CLEDController { +class APA102Controller : public CPixelLEDController<RGB_ORDER> { typedef SPIOutput<DATA_PIN, CLOCK_PIN, SPI_SPEED> SPI; SPI mSPI; @@ -244,46 +179,13 @@ public: mSPI.init(); } - virtual void clearLeds(int nLeds) { - showColor(CRGB(0,0,0), nLeds, CRGB(0,0,0)); - } - protected: - virtual void showColor(const struct CRGB & data, int nLeds, CRGB scale) { - PixelController<RGB_ORDER> pixels(data, nLeds, scale, getDither()); - + virtual void showPixels(PixelController<RGB_ORDER> & pixels) { mSPI.select(); startBoundary(); - for(int i = 0; i < nLeds; i++) { -#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(); - } - endBoundary(nLeds); - - mSPI.waitFully(); - mSPI.release(); - } - - virtual void show(const struct CRGB *data, int nLeds, CRGB scale) { - PixelController<RGB_ORDER> pixels(data, nLeds, scale, getDither()); - - mSPI.select(); - - startBoundary(); - for(int i = 0; i < nLeds; i++) { + while(pixels.has(1)) { #ifdef FASTLED_SPI_BYTE_ONLY mSPI.writeByte(0xFF); mSPI.writeByte(pixels.loadAndScale0()); @@ -299,31 +201,11 @@ protected: pixels.stepDithering(); pixels.advanceData(); } - endBoundary(nLeds); + endBoundary(pixels.size()); mSPI.waitFully(); mSPI.release(); } -#ifdef SUPPORT_ARGB - virtual void show(const struct CRGB *data, int nLeds, CRGB scale) { - PixelController<RGB_ORDER> pixels(data, nLeds,, scale, getDither()); - - mSPI.select(); - - startBoundary(); - for(int i = 0; i < nLeds; i++) { - mSPI.writeByte(0xFF); - uint8_t b = pixels.loadAndScale0(); mSPI.writeByte(b); - b = pixels.loadAndScale1(); mSPI.writeByte(b); - b = pixels.loadAndScale2(); mSPI.writeByte(b); - pixels.advanceData(); - pixels.stepDithering(); - } - endBoundary(nLeds); - mSPI.waitFully(); - mSPI.release(); - } -#endif }; @@ -339,7 +221,7 @@ protected: /// @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(10) template <uint8_t DATA_PIN, uint8_t CLOCK_PIN, EOrder RGB_ORDER = RGB, uint8_t SPI_SPEED = DATA_RATE_MHZ(10)> -class P9813Controller : public CLEDController { +class P9813Controller : public CPixelLEDController<RGB_ORDER> { typedef SPIOutput<DATA_PIN, CLOCK_PIN, SPI_SPEED> SPI; SPI mSPI; @@ -357,35 +239,13 @@ public: mSPI.init(); } - virtual void clearLeds(int nLeds) { - showColor(CRGB(0,0,0), nLeds, CRGB(0,0,0)); - } - protected: - virtual void showColor(const struct CRGB & data, int nLeds, CRGB scale) { - PixelController<RGB_ORDER> pixels(data, nLeds, scale, getDither()); - + virtual void showPixels(PixelController<RGB_ORDER> & pixels) { 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<RGB_ORDER> pixels(data, nLeds, scale, getDither()); - - mSPI.select(); - - writeBoundary(); - for(int i = 0; i < nLeds; i++) { + while(pixels.has(1)) { writeLed(pixels.loadAndScale0(), pixels.loadAndScale1(), pixels.loadAndScale2()); pixels.advanceData(); pixels.stepDithering(); @@ -396,24 +256,6 @@ protected: mSPI.release(); } -#ifdef SUPPORT_ARGB - virtual void show(const struct CRGB *data, int nLeds, CRGB scale) { - PixelController<RGB_ORDER> 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.waitFully(); - - mSPI.release(); - } -#endif }; @@ -429,7 +271,7 @@ protected: /// @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(16) template <uint8_t DATA_PIN, uint8_t CLOCK_PIN, EOrder RGB_ORDER = RGB, uint8_t SPI_SPEED = DATA_RATE_MHZ(16)> -class SM16716Controller : public CLEDController { +class SM16716Controller : public CPixelLEDController<RGB_ORDER> { typedef SPIOutput<DATA_PIN, CLOCK_PIN, SPI_SPEED> SPI; SPI mSPI; @@ -450,45 +292,16 @@ public: mSPI.init(); } - virtual void clearLeds(int nLeds) { - mSPI.select(); - while(nLeds--) { - mSPI.template writeBit<0>(1); - mSPI.writeByte(0); - mSPI.writeByte(0); - mSPI.writeByte(0); - } - mSPI.waitFully(); - mSPI.release(); - writeHeader(); - } - protected: - virtual void showColor(const struct CRGB & data, int nLeds, CRGB scale) { - mSPI.template writePixels<FLAG_START_BIT, DATA_NOP, RGB_ORDER>(PixelController<RGB_ORDER>(data, nLeds, scale, getDither())); - writeHeader(); - } - - virtual void show(const struct CRGB *data, int nLeds, CRGB scale) { + virtual void showPixels(PixelController<RGB_ORDER> & pixels) { // 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<FLAG_START_BIT, DATA_NOP, RGB_ORDER>( PixelController<RGB_ORDER>(data, nLeds, scale, getDither())); + mSPI.template writePixels<FLAG_START_BIT, DATA_NOP, RGB_ORDER>( pixels ); writeHeader(); } -#ifdef SUPPORT_ARGB - 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); - - // 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<FLAG_START_BIT, DATA_NOP, RGB_ORDER>(PixelController<RGB_ORDER>(data, nLeds, scale, getDither())); - } -#endif }; /// @} ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/controller.h b/controller.h index 3df29ee7..06d3c47e 100644 --- a/controller.h +++ b/controller.h @@ -59,10 +59,6 @@ protected: ///@param scale the rgb scaling to apply to each led before writing it out 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: /// create an led controller object, add it to the chain of controllers CLEDController() : m_Data(NULL), m_ColorCorrection(UncorrectedColor), m_ColorTemperature(UncorrectedTemperature), m_DitherMode(BINARY_DITHER), m_nLeds(0) { @@ -76,7 +72,7 @@ public: virtual void init() = 0; ///clear out/zero out the given number of leds. - virtual void clearLeds(int nLeds) = 0; + virtual void clearLeds(int nLeds) { showColor(CRGB::Black, nLeds, CRGB::Black); } /// show function w/integer brightness, will scale for color correction and temperature void show(const struct CRGB *data, int nLeds, uint8_t brightness) { @@ -103,13 +99,6 @@ public: /// get the next controller in the chain after this one. will return NULL at the end of the chain 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) { - show(data, nLeds, getAdjustment(brightness)) - } -#endif - /// set the default array of leds to be used by this controller CLEDController & setLeds(CRGB *data, int nLeds) { m_Data = data; @@ -187,7 +176,7 @@ public: template<EOrder RGB_ORDER> struct PixelController { const uint8_t *mData; - int mLen; + int mLen,mLenRemaining; uint8_t d[3]; uint8_t e[3]; CRGB mScale; @@ -205,6 +194,7 @@ struct PixelController { mScale = other.mScale; mAdvance = other.mAdvance; mLen = other.mLen; + mLenRemaining = other.mLenRemaining; } @@ -216,37 +206,22 @@ struct PixelController { ///@param dither the dither mode for these pixels ///@param advance whether or not to walk through the array of data for each pixel, or just write out the first pixel len times ///@param skip whether or not there is extra data to skip when writing out led data, e.g. if passed in argb data - 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) { + PixelController(const uint8_t *d, int len, CRGB & s, EDitherMode dither = BINARY_DITHER, bool advance=true, uint8_t skip=0) : mData(d), mLen(len), mLenRemaining(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) { + PixelController(const CRGB *d, int len, CRGB & s, EDitherMode dither = BINARY_DITHER) : mData((const uint8_t*)d), mLen(len), mLenRemaining(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), 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), mLen(len), mScale(s) { + PixelController(const CRGB &d, int len, CRGB & s, EDitherMode dither = BINARY_DITHER) : mData((const uint8_t*)&d), mLen(len), mLenRemaining(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), mLen(len), mScale(s) { - enable_dithering(dither); - // skip the A in CARGB - mData += 1; - mAdvance = 4; - } -#endif ///@} /// initialize the binary dithering for this controller @@ -328,7 +303,7 @@ struct PixelController { /// Do we have n pixels left to process? __attribute__((always_inline)) inline bool has(int n) { - return mLen >= n; + return mLenRemaining >= n; } /// toggle dithering enable @@ -339,11 +314,12 @@ struct PixelController { } } + __attribute__((always_inline)) inline int size() { return mLen; } /// 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--;} + __attribute__((always_inline)) inline void advanceData() { mData += mAdvance; mLenRemaining--;} /// step the dithering forward __attribute__((always_inline)) inline void stepDithering() { @@ -381,7 +357,7 @@ struct PixelController { template<int LANES,int MASK, EOrder RGB_ORDER> struct MultiPixelController { const uint8_t *mData; - int mLen; + int mLen,mLenRemaining; uint8_t d[3]; uint8_t e[3]; CRGB mScale; @@ -398,7 +374,7 @@ struct MultiPixelController { mData = other.mData; mScale = other.mScale; mAdvance = other.mAdvance; - mLen = other.mLen; + mLenRemaining = mLen = other.mLen; for(int i = 0; i < LANES; i++) { mOffsets[i] = other.mOffsets[i]; } } @@ -411,43 +387,25 @@ struct MultiPixelController { } } - MultiPixelController(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) { + MultiPixelController(const uint8_t *d, int len, CRGB & s, EDitherMode dither = BINARY_DITHER, bool advance=true, uint8_t skip=0) : mData(d), mLen(len), mLenRemaining(len), mScale(s) { enable_dithering(dither); mData += skip; mAdvance = (advance) ? 3+skip : 0; initOffsets(len); } - MultiPixelController(const CRGB *d, int len, CRGB & s, EDitherMode dither = BINARY_DITHER) : mData((const uint8_t*)d), mLen(len), mScale(s) { + MultiPixelController(const CRGB *d, int len, CRGB & s, EDitherMode dither = BINARY_DITHER) : mData((const uint8_t*)d), mLen(len), mLenRemaining(len), mScale(s) { enable_dithering(dither); mAdvance = 3; initOffsets(len); } - MultiPixelController(const CRGB &d, int len, CRGB & s, EDitherMode dither = BINARY_DITHER) : mData((const uint8_t*)&d), mLen(len), mScale(s) { + MultiPixelController(const CRGB &d, int len, CRGB & s, EDitherMode dither = BINARY_DITHER) : mData((const uint8_t*)&d), mLen(len), mLenRemaining(len), mScale(s) { enable_dithering(dither); mAdvance = 0; initOffsets(len); } -#ifdef SUPPORT_ARGB - MultiPixelController(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; - initOffsets(len); - } - - MultiPixelController(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 = 4; - initOffsets(len); - } -#endif - void init_binary_dithering() { #if !defined(NO_DITHERING) || (NO_DITHERING != 1) @@ -526,7 +484,7 @@ struct MultiPixelController { // Do we have n pixels left to process? __attribute__((always_inline)) inline bool has(int n) { - return mLen >= n; + return mLenRemaining >= n; } // toggle dithering enable @@ -537,11 +495,13 @@ struct MultiPixelController { } } + __attribute__((always_inline)) inline int size() { return mLen; } + // 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--;} + __attribute__((always_inline)) inline void advanceData() { mData += mAdvance; mLenRemaining--;} // step the dithering forward __attribute__((always_inline)) inline void stepDithering() { @@ -583,6 +543,33 @@ struct MultiPixelController { __attribute__((always_inline)) inline uint8_t stepAdvanceAndLoadAndScale0(int lane) { stepDithering(); return advanceAndLoadAndScale<0>(*this, lane); } }; +template<EOrder RGB_ORDER> class CPixelLEDController : public CLEDController { +protected: + virtual void showPixels(PixelController<RGB_ORDER> & pixels) = 0; + + /// set all the leds on the controller to a given color + ///@param data the crgb color to set the leds to + ///@param nLeds the numner of leds to set to this color + ///@param scale the rgb scaling value for outputting color + virtual void showColor(const struct CRGB & data, int nLeds, CRGB scale) { + PixelController<RGB_ORDER> pixels(data, nLeds, scale, getDither()); + showPixels(pixels); + } + +/// write the passed in rgb data out to the leds managed by this controller +///@param data the rgb data to write out to the strip +///@param nLeds the number of leds being written out +///@param scale the rgb scaling to apply to each led before writing it out + virtual void show(const struct CRGB *data, int nLeds, CRGB scale) { + PixelController<RGB_ORDER> pixels(data, nLeds, scale, getDither()); + showPixels(pixels); + } + +public: + CPixelLEDController() : CLEDController() {} +}; + + FASTLED_NAMESPACE_END #endif @@ -12,46 +12,22 @@ FASTLED_NAMESPACE_BEGIN // note - dmx simple must be included before FastSPI for this code to be enabled -template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB> class DMXSimpleController : public CLEDController { +template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB> class DMXSimpleController : public CPixelLEDController<RGB_ORDER> { public: // initialize the LED controller virtual void init() { DmxSimple.usePin(DATA_PIN); } - // clear out/zero out the given number of leds. - virtual void clearLeds(int nLeds) { - int count = min(nLeds * 3, DMX_SIZE); - 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, CRGB scale) { - int count = min(nLeds, DMX_SIZE / 3); + virtual void showPixels(PixelController<RGB_ORDER> & pixels) { int iChannel = 1; - for(int i = 0; i < count; i++) { - 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)])); + while(pixels.has(1)) { + DmxSimple.write(iChannel++, pixels.loadAndScale0()); + DmxSimple.write(iChannel++, pixels.loadAndScale1()); + DmxSimple.write(iChannel++, pixels.loadAndScale2()); + pixels.advanceData(); + pixels.stepDithering(); } } - - // 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) { - 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.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)])); - } - - } - -#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; -#endif }; FASTLED_NAMESPACE_END @@ -63,45 +39,21 @@ FASTLED_NAMESPACE_END FASTLED_NAMESPACE_BEGIN -template <EOrder RGB_ORDER = RGB> class DMXSerialController : public CLEDController { +template <EOrder RGB_ORDER = RGB> class DMXSerialController : public CPixelLEDController<RGB_ORDER> { 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, 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, 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.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. - // nLeds is the number of RGB leds being written to - 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.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)])); + virtual void showPixels(PixelController<RGB_ORDER> & pixels) { + int iChannel = 1; + while(pixels.has(1)) { + DMXSerial.write(iChannel++, pixels.loadAndScale0()); + DMXSerial.write(iChannel++, pixels.loadAndScale1()); + DMXSerial.write(iChannel++, pixels.loadAndScale2()); + pixels.advanceData(); + pixels.stepDithering(); } - } - -#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; -#endif }; FASTLED_NAMESPACE_END diff --git a/docs/.Doxyfile.swp b/docs/.Doxyfile.swp Binary files differdeleted file mode 100644 index d223ba7d..00000000 --- a/docs/.Doxyfile.swp +++ /dev/null diff --git a/platforms/arm/d21/clockless_arm_d21.h b/platforms/arm/d21/clockless_arm_d21.h index c6ca1792..94b596d7 100644 --- a/platforms/arm/d21/clockless_arm_d21.h +++ b/platforms/arm/d21/clockless_arm_d21.h @@ -6,7 +6,7 @@ FASTLED_NAMESPACE_BEGIN #define FASTLED_HAS_CLOCKLESS 1 template <uint8_t DATA_PIN, int T1, int T2, int T3, EOrder RGB_ORDER = RGB, int XTRA0 = 0, bool FLIP = false, int WAIT_TIME = 50> -class ClocklessController : public CLEDController { +class ClocklessController : public CPixelLEDController<RGB_ORDER> { typedef typename FastPinBB<DATA_PIN>::port_ptr_t data_ptr_t; typedef typename FastPinBB<DATA_PIN>::port_t data_t; @@ -22,43 +22,13 @@ public: virtual uint16_t getMaxRefreshRate() const { return 400; } - 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 & rgbdata, int nLeds, CRGB scale) { - PixelController<RGB_ORDER> pixels(rgbdata, nLeds, scale, getDither()); - mWait.wait(); - cli(); - - showRGBInternal(pixels); - - sei(); - mWait.mark(); - } - - virtual void show(const struct CRGB *rgbdata, int nLeds, CRGB scale) { - PixelController<RGB_ORDER> pixels(rgbdata, nLeds, scale, getDither()); - mWait.wait(); - cli(); - - showRGBInternal(pixels); - - sei(); - mWait.mark(); - } - -#ifdef SUPPORT_ARGB - virtual void show(const struct CARGB *rgbdata, int nLeds, CRGB scale) { - PixelController<RGB_ORDER> pixels(rgbdata, nLeds, scale, getDither()); + virtual void showPixels(PixelController<RGB_ORDER> & pixels) { mWait.wait(); cli(); showRGBInternal(pixels); 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. diff --git a/platforms/arm/k20/clockless_arm_k20.h b/platforms/arm/k20/clockless_arm_k20.h index f17ba72d..c0fef13a 100644 --- a/platforms/arm/k20/clockless_arm_k20.h +++ b/platforms/arm/k20/clockless_arm_k20.h @@ -10,7 +10,7 @@ FASTLED_NAMESPACE_BEGIN #define FASTLED_HAS_CLOCKLESS 1 template <int DATA_PIN, int T1, int T2, int T3, EOrder RGB_ORDER = RGB, int XTRA0 = 0, bool FLIP = false, int WAIT_TIME = 50> -class ClocklessController : public CLEDController { +class ClocklessController : public CPixelLEDController<RGB_ORDER> { typedef typename FastPin<DATA_PIN>::port_ptr_t data_ptr_t; typedef typename FastPin<DATA_PIN>::port_t data_t; @@ -26,37 +26,13 @@ public: virtual uint16_t getMaxRefreshRate() const { return 400; } - virtual void clearLeds(int nLeds) { - 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<RGB_ORDER> pixels(rgbdata, nLeds, scale, getDither()); - - mWait.wait(); - showRGBInternal(pixels); - mWait.mark(); - } - - virtual void show(const struct CRGB *rgbdata, int nLeds, CRGB scale) { - PixelController<RGB_ORDER> pixels(rgbdata, nLeds, scale, getDither()); - - mWait.wait(); - showRGBInternal(pixels); - mWait.mark(); - } - -#ifdef SUPPORT_ARGB - virtual void show(const struct CARGB *rgbdata, int nLeds, CRGB scale) { - PixelController<RGB_ORDER> pixels(rgbdata, nLeds, scale, getDither()); - mWait.wait(); - showRGBInternal(pixels); - mWait.mark(); - } -#endif + virtual void showPixels(PixelController<RGB_ORDER> & pixels) { + mWait.wait(); + showRGBInternal(pixels); + mWait.mark(); + } template<int BITS> __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--) { diff --git a/platforms/arm/k20/clockless_block_arm_k20.h b/platforms/arm/k20/clockless_block_arm_k20.h index dda85ac3..5be19909 100644 --- a/platforms/arm/k20/clockless_block_arm_k20.h +++ b/platforms/arm/k20/clockless_block_arm_k20.h @@ -95,21 +95,6 @@ public: mWait.mark(); } -#ifdef SUPPORT_ARGB - virtual void show(const struct CARGB *rgbdata, int nLeds, CRGB scale) { - MultiPixelController<LANES,PORT_MASK,RGB_ORDER> pixels(rgbdata,nLeds, scale, getDither() ); - mWait.wait(); - uint32_t clocks = showRGBInternal(pixels,nLeds); - - #if FASTLED_ALLOW_INTTERUPTS == 0 - // Adjust the timer - long microsTaken = CLKS_TO_MICROS(clocks); - MS_COUNTER += (1 + (microsTaken / 1000)); - #endif - - mWait.mark(); - } -#endif typedef union { @@ -295,16 +280,6 @@ public: mWait.mark(); } -#ifdef SUPPORT_ARGB - virtual void show(const struct CARGB *rgbdata, int nLeds, CRGB scale) { - MultiPixelController<DLANES,PMASK,RGB_ORDER> pixels(rgbdata,nLeds, scale, getDither() ); - mWait.wait(); - showRGBInternal(pixels,nLeds); - mWait.mark(); - } -#endif - - typedef union { uint8_t bytes[16]; uint16_t shorts[8]; diff --git a/platforms/arm/k20/smartmatrix_t3.h b/platforms/arm/k20/smartmatrix_t3.h index 06b04f18..14c3734c 100644 --- a/platforms/arm/k20/smartmatrix_t3.h +++ b/platforms/arm/k20/smartmatrix_t3.h @@ -9,7 +9,7 @@ FASTLED_NAMESPACE_BEGIN extern SmartMatrix *pSmartMatrix; // note - dmx simple must be included before FastSPI for this code to be enabled -class CSmartMatrixController : public CLEDController { +class CSmartMatrixController : public CPixelLEDController<RGB_ORDER> { SmartMatrix matrix; public: @@ -26,37 +26,13 @@ public: 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<RGB> 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(); + virtual void showPixels(PixelController<RGB_ORDER> & pixels) { + if(SMART_MATRIX_CAN_TRIPLE_BUFFER) { + rgb24 *md = matrix.getRealBackBuffer(); + } else { + rgb24 *md = matrix.backBuffer(); } - 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<RGB> pixels(data, nLeds, scale, getDither()); -#ifdef SMART_MATRIX_CAN_TRIPLE_BUFFER - rgb24 *md = matrix.getRealBackBuffer(); -#else - rgb24 *md = matrix.backBuffer(); -#endif - while(nLeds--) { + while(pixels.has(1)) { md->red = pixels.loadAndScale0(); md->green = pixels.loadAndScale1(); md->blue = pixels.loadAndScale2(); @@ -65,15 +41,11 @@ public: pixels.stepDithering(); } matrix.swapBuffers(); -#ifdef SMART_MATRIX_CAN_TRIPLE_BUFFER - matrix.setBackBuffer((rgb24*)data); -#endif + if(SMART_MATRIX_CAN_TRIPLE_BUFFER && pixels.advanceBy() > 0) { + matrix.setBackBuffer(pixels.mData); + } } -#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 }; FASTLED_NAMESPACE_END diff --git a/platforms/arm/kl26/clockless_arm_kl26.h b/platforms/arm/kl26/clockless_arm_kl26.h index 8c441a8e..aba132f2 100644 --- a/platforms/arm/kl26/clockless_arm_kl26.h +++ b/platforms/arm/kl26/clockless_arm_kl26.h @@ -6,7 +6,7 @@ FASTLED_NAMESPACE_BEGIN #define FASTLED_HAS_CLOCKLESS 1 template <uint8_t DATA_PIN, int T1, int T2, int T3, EOrder RGB_ORDER = RGB, int XTRA0 = 0, bool FLIP = false, int WAIT_TIME = 50> -class ClocklessController : public CLEDController { +class ClocklessController : public CPixelLEDController<RGB_ORDER> { typedef typename FastPinBB<DATA_PIN>::port_ptr_t data_ptr_t; typedef typename FastPinBB<DATA_PIN>::port_t data_t; @@ -22,43 +22,13 @@ public: virtual uint16_t getMaxRefreshRate() const { return 400; } - 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 & rgbdata, int nLeds, CRGB scale) { - PixelController<RGB_ORDER> pixels(rgbdata, nLeds, scale, getDither()); - mWait.wait(); - cli(); - - showRGBInternal(pixels); - - sei(); - mWait.mark(); - } - - virtual void show(const struct CRGB *rgbdata, int nLeds, CRGB scale) { - PixelController<RGB_ORDER> pixels(rgbdata, nLeds, scale, getDither()); - mWait.wait(); - cli(); - - showRGBInternal(pixels); - - sei(); - mWait.mark(); - } - -#ifdef SUPPORT_ARGB - virtual void show(const struct CARGB *rgbdata, int nLeds, CRGB scale) { - PixelController<RGB_ORDER> pixels(rgbdata, nLeds, scale, getDither()); + virtual void showPixels(PixelController<RGB_ORDER> & pixels) { mWait.wait(); cli(); showRGBInternal(pixels); 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. diff --git a/platforms/arm/nrf51/clockless_arm_nrf51.h b/platforms/arm/nrf51/clockless_arm_nrf51.h index 98408ada..0fb56e3e 100644 --- a/platforms/arm/nrf51/clockless_arm_nrf51.h +++ b/platforms/arm/nrf51/clockless_arm_nrf51.h @@ -19,7 +19,7 @@ #include "platforms/arm/common/m0clockless.h" template <uint8_t DATA_PIN, int T1, int T2, int T3, EOrder RGB_ORDER = RGB, int XTRA0 = 0, bool FLIP = false, int WAIT_TIME = 75> -class ClocklessController : public CLEDController { +class ClocklessController : public CPixelLEDController<RGB_ORDER> { typedef typename FastPinBB<DATA_PIN>::port_ptr_t data_ptr_t; typedef typename FastPinBB<DATA_PIN>::port_t data_t; @@ -35,51 +35,17 @@ public: virtual uint16_t getMaxRefreshRate() const { return 400; } - 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 & rgbdata, int nLeds, CRGB scale) { - PixelController<RGB_ORDER> pixels(rgbdata, nLeds, scale, getDither()); + virtual void showPixels(PixelController<RGB_ORDER> & pixels) { mWait.wait(); cli(); - - // attempt to re-show a frame if we exit early because of interrupts. if(!showRGBInternal(pixels)) { sei(); delayMicroseconds(WAIT_TIME); cli(); showRGBInternal(pixels); } - sei(); mWait.mark(); } - virtual void show(const struct CRGB *rgbdata, int nLeds, CRGB scale) { - PixelController<RGB_ORDER> pixels(rgbdata, nLeds, scale, getDither()); - mWait.wait(); - cli(); - - if(!showRGBInternal(pixels)) { - sei(); delayMicroseconds(WAIT_TIME); cli(); - showRGBInternal(pixels); - } - - sei(); - mWait.mark(); - } - -#ifdef SUPPORT_ARGB - virtual void show(const struct CARGB *rgbdata, int nLeds, CRGB scale) { - PixelController<RGB_ORDER> pixels(rgbdata, nLeds, scale, getDither()); - mWait.wait(); - cli(); - showRGBInternal(pixels); - 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. static uint32_t showRGBInternal(PixelController<RGB_ORDER> & pixels) { diff --git a/platforms/arm/sam/clockless_arm_sam.h b/platforms/arm/sam/clockless_arm_sam.h index 4cbdf27f..08864b37 100644 --- a/platforms/arm/sam/clockless_arm_sam.h +++ b/platforms/arm/sam/clockless_arm_sam.h @@ -11,15 +11,11 @@ FASTLED_NAMESPACE_BEGIN #define TADJUST 0 #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) #define FASTLED_HAS_CLOCKLESS 1 template <uint8_t DATA_PIN, int T1, int T2, int T3, EOrder RGB_ORDER = RGB, int XTRA0 = 0, bool FLIP = false, int WAIT_TIME = 50> -class ClocklessController : public CLEDController { +class ClocklessController : public CPixelLEDController<RGB_ORDER> { typedef typename FastPinBB<DATA_PIN>::port_ptr_t data_ptr_t; typedef typename FastPinBB<DATA_PIN>::port_t data_t; @@ -35,38 +31,14 @@ public: virtual uint16_t getMaxRefreshRate() const { return 400; } - virtual void clearLeds(int nLeds) { - 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<RGB_ORDER> pixels(rgbdata, nLeds, scale, getDither()); - mWait.wait(); - showRGBInternal(pixels); - mWait.mark(); - } - - virtual void show(const struct CRGB *rgbdata, int nLeds, CRGB scale) { - PixelController<RGB_ORDER> pixels(rgbdata, nLeds, scale, getDither()); + virtual void showPixels(PixelController<RGB_ORDER> & pixels) { mWait.wait(); showRGBInternal(pixels); mWait.mark(); } -#ifdef SUPPORT_ARGB - virtual void show(const struct CARGB *rgbdata, int nLeds, CRGB scale) { - PixelController<RGB_ORDER> pixels(rgbdata, nLeds, scale, getDither()); - mWait.wait(); - showRGBInternal(pixels); - sei(); - mWait.mark(); - } -#endif - - template<int BITS> __attribute__ ((always_inline)) inline static void writeBits(register uint32_t & next_mark, register data_ptr_t port, register uint8_t & b) { // Make sure we don't slot into a wrapping spot, this will delay up to 12.5µs for WS2812 // bool bShift=0; diff --git a/platforms/arm/sam/clockless_block_arm_sam.h b/platforms/arm/sam/clockless_block_arm_sam.h index 745f61a6..72b1a0b0 100644 --- a/platforms/arm/sam/clockless_block_arm_sam.h +++ b/platforms/arm/sam/clockless_block_arm_sam.h @@ -103,14 +103,6 @@ public: mWait.mark(); } -#ifdef SUPPORT_ARGB - virtual void show(const struct CARGB *rgbdata, int nLeds, CRGB scale) { - mWait.wait(); - showRGBInternal(PixelController<RGB_ORDER>(rgbdata, nLeds, scale, getDither())); - mWait.mark(); - } -#endif - template<int BITS,int PX> __attribute__ ((always_inline)) inline static void writeBits(register uint32_t & next_mark, register Lines & b, Lines & b3, MultiPixelController<LANES, PORT_MASK, RGB_ORDER> &pixels) { // , register uint32_t & b2) { register Lines b2; transpose8x1(b.bytes,b2.bytes); diff --git a/platforms/arm/stm32/clockless_arm_stm32.h b/platforms/arm/stm32/clockless_arm_stm32.h index d427abab..97786e29 100644 --- a/platforms/arm/stm32/clockless_arm_stm32.h +++ b/platforms/arm/stm32/clockless_arm_stm32.h @@ -8,7 +8,7 @@ FASTLED_NAMESPACE_BEGIN #define FASTLED_HAS_CLOCKLESS 1 template <int DATA_PIN, int T1, int T2, int T3, EOrder RGB_ORDER = RGB, int XTRA0 = 0, bool FLIP = false, int WAIT_TIME = 50> -class ClocklessController : public CLEDController { +class ClocklessController : public CPixelLEDController<RGB_ORDER> { typedef typename FastPin<DATA_PIN>::port_ptr_t data_ptr_t; typedef typename FastPin<DATA_PIN>::port_t data_t; @@ -24,38 +24,14 @@ public: virtual uint16_t getMaxRefreshRate() const { return 400; } - virtual void clearLeds(int nLeds) { - 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<RGB_ORDER> pixels(rgbdata, nLeds, scale, getDither()); - + virtual void showPixels(PixelController<RGB_ORDER> & pixels) { mWait.wait(); showRGBInternal(pixels); mWait.mark(); } - virtual void show(const struct CRGB *rgbdata, int nLeds, CRGB scale) { - PixelController<RGB_ORDER> pixels(rgbdata, nLeds, scale, getDither()); - - mWait.wait(); - showRGBInternal(pixels); - mWait.mark(); - } - - #ifdef SUPPORT_ARGB - virtual void show(const struct CARGB *rgbdata, int nLeds, CRGB scale) { - PixelController<RGB_ORDER> pixels(rgbdata, nLeds, scale, getDither()); - mWait.wait(); - showRGBInternal(pixels); - mWait.mark(); - } - #endif - #define _CYCCNT (*(volatile uint32_t*)(0xE0001004UL)) template<int BITS> __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) { diff --git a/platforms/avr/clockless_trinket.h b/platforms/avr/clockless_trinket.h index 38c26984..2186906e 100644 --- a/platforms/avr/clockless_trinket.h +++ b/platforms/avr/clockless_trinket.h @@ -90,8 +90,8 @@ static uint8_t gTimeErrorAccum256ths; #define FASTLED_HAS_CLOCKLESS 1 template <uint8_t DATA_PIN, int T1, int T2, int T3, EOrder RGB_ORDER = RGB, int XTRA0 = 0, bool FLIP = false, int WAIT_TIME = 10> -class ClocklessController : public CLEDController { - static_assert(T1 >= 2 && T2 >= 2 && T3 >= 3, "Not enough cycles - use a higher clock speed"); +class ClocklessController : public CPixelLEDController<RGB_ORDER> { + static_assert(T1 >= 3 && T2 >= 2 && T3 >= 3, "Not enough cycles - use a higher clock speed"); typedef typename FastPin<DATA_PIN>::port_ptr_t data_ptr_t; typedef typename FastPin<DATA_PIN>::port_t data_t; @@ -104,30 +104,9 @@ public: virtual uint16_t getMaxRefreshRate() const { return 400; } - virtual void clearLeds(int nLeds) { - 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) { - showAdjTime((uint8_t*)rgbdata, nLeds, scale, true, 0); - } - -#ifdef SUPPORT_ARGB - 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) { - PixelController<RGB_ORDER> pixels(data, nLeds, scale, getDither(), advance, skip); + virtual void showPixels(PixelController<RGB_ORDER> & pixels) { mWait.wait(); cli(); @@ -136,12 +115,12 @@ protected: // Adjust the timer #if (!defined(NO_CORRECTION) || (NO_CORRECTION == 0)) && (FASTLED_ALLOW_INTERRUPTS == 0) - uint32_t microsTaken = (uint32_t)nLeds * (uint32_t)CLKS_TO_MICROS(24 * (T1 + T2 + T3)); + uint32_t microsTaken = (uint32_t)pixels.size() * (uint32_t)CLKS_TO_MICROS(24 * (T1 + T2 + T3)); // adust for approximate observed actal runtime (as of January 2015) // roughly 9.6 cycles per pixel, which is 0.6us/pixel at 16MHz // microsTaken += nLeds * 0.6 * CLKS_TO_MICROS(16); - microsTaken += scale16by8(nLeds,(0.6 * 256) + 1) * CLKS_TO_MICROS(16); + microsTaken += scale16by8(pixels.size(),(0.6 * 256) + 1) * CLKS_TO_MICROS(16); // if less than 1000us, there is NO timer impact, // this is because the ONE interrupt that might come in while interrupts @@ -502,11 +481,6 @@ protected: #endif } -#ifdef SUPPORT_ARGB - virtual void showARGB(struct CARGB *data, int nLeds) { - // TODO: IMPLEMENTME - } -#endif }; #endif |