diff options
author | Daniel Garcia <danielgarcia@gmail.com> | 2016-01-24 00:38:57 +0300 |
---|---|---|
committer | Daniel Garcia <danielgarcia@gmail.com> | 2016-01-24 00:38:57 +0300 |
commit | 82133f4e054ac94149edc68dc76f49114eccb404 (patch) | |
tree | 68a39a6fd4373bd3a1de38d36a4ed97750e84c5c | |
parent | 5c4122fdb09619da2897eced5896f95e6e63ccd4 (diff) |
DUE parallel controller now uses CPixelLedController as a base
-rw-r--r-- | controller.h | 12 | ||||
-rw-r--r-- | platforms/arm/sam/clockless_block_arm_sam.h | 116 |
2 files changed, 57 insertions, 71 deletions
diff --git a/controller.h b/controller.h index 03027286..8c06c0ca 100644 --- a/controller.h +++ b/controller.h @@ -340,10 +340,10 @@ struct PixelController { template<int SLOT> __attribute__((always_inline)) inline static uint8_t loadByte(PixelController & pc, int lane) { return pc.mData[pc.mOffsets[lane] + RO(SLOT)]; } template<int SLOT> __attribute__((always_inline)) inline static uint8_t dither(PixelController & pc, uint8_t b) { return b ? qadd8(b, pc.d[RO(SLOT)]) : 0; } - template<int SLOT> __attribute__((always_inline)) inline static uint8_t dither(PixelController & pc, uint8_t b, uint8_t d) { return b ? qadd8(b,d) : 0; } + template<int SLOT> __attribute__((always_inline)) inline static uint8_t dither(PixelController & , uint8_t b, uint8_t d) { return b ? qadd8(b,d) : 0; } template<int SLOT> __attribute__((always_inline)) inline static uint8_t scale(PixelController & pc, uint8_t b) { return scale8(b, pc.mScale.raw[RO(SLOT)]); } - template<int SLOT> __attribute__((always_inline)) inline static uint8_t scale(PixelController & pc, uint8_t b, uint8_t scale) { return scale8(b, scale); } + template<int SLOT> __attribute__((always_inline)) inline static uint8_t scale(PixelController & , uint8_t b, uint8_t scale) { return scale8(b, scale); } // composite shortcut functions for loading, dithering, and scaling template<int SLOT> __attribute__((always_inline)) inline static uint8_t loadAndScale(PixelController & pc) { return scale<SLOT>(pc, pc.dither<SLOT>(pc, pc.loadByte<SLOT>(pc))); } @@ -371,16 +371,16 @@ struct PixelController { __attribute__((always_inline)) inline uint8_t stepAdvanceAndLoadAndScale0() { stepDithering(); return advanceAndLoadAndScale<0>(*this); } }; -template<EOrder RGB_ORDER> class CPixelLEDController : public CLEDController { +template<EOrder RGB_ORDER, int LANES=1, uint32_t MASK=0xFFFFFFFF> class CPixelLEDController : public CLEDController { protected: - virtual void showPixels(PixelController<RGB_ORDER> & pixels) = 0; + virtual void showPixels(PixelController<RGB_ORDER,LANES,MASK> & 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()); + PixelController<RGB_ORDER, LANES, MASK> pixels(data, nLeds, scale, getDither()); showPixels(pixels); } @@ -389,7 +389,7 @@ protected: ///@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()); + PixelController<RGB_ORDER, LANES, MASK> pixels(data, nLeds, scale, getDither()); showPixels(pixels); } diff --git a/platforms/arm/sam/clockless_block_arm_sam.h b/platforms/arm/sam/clockless_block_arm_sam.h index 1044ff31..2bfcf2b2 100644 --- a/platforms/arm/sam/clockless_block_arm_sam.h +++ b/platforms/arm/sam/clockless_block_arm_sam.h @@ -30,7 +30,7 @@ typedef union { #define T1_MARK (TOTAL - (T1+TADJUST)) #define T2_MARK (T1_MARK - (T2+TADJUST)) template <uint8_t LANES, int FIRST_PIN, int T1, int T2, int T3, EOrder RGB_ORDER = RGB, int XTRA0 = 0, bool FLIP = false, int WAIT_TIME = 50> -class InlineBlockClocklessController : public CLEDController { +class InlineBlockClocklessController : public CPixelLEDController<RGB_ORDER, LANES, 0xFF> { typedef typename FastPin<FIRST_PIN>::port_ptr_t data_ptr_t; typedef typename FastPin<FIRST_PIN>::port_t data_t; @@ -38,8 +38,9 @@ class InlineBlockClocklessController : public CLEDController { data_ptr_t mPort; CMinWait<WAIT_TIME> mWait; public: - virtual int size() { return m_nLeds * LANES; } + virtual int size() { return CLEDController::size() * LANES; } virtual void init() { + static_assert(LANES <= 8, "Maximum of 8 lanes for Due parallel controllers!"); if(FIRST_PIN == PORTA_FIRST_PIN) { switch(LANES) { case 8: FastPin<31>::setOutput(); @@ -80,74 +81,23 @@ 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,LANES,PORT_MASK> pixels(rgbdata,nLeds, scale, getDither() ); - mWait.wait(); - showRGBInternal(pixels, nLeds); - sei(); - mWait.mark(); - } - -// #define ADV_RGB -#define ADV_RGB if(maskbit & PORT_MASK) { rgbdata += nLeds; } maskbit <<= 1; - - virtual void show(const struct CRGB *rgbdata, int nLeds, CRGB scale) { - PixelController<RGB_ORDER,LANES,PORT_MASK> pixels(rgbdata,nLeds, scale, getDither() ); - mWait.wait(); - showRGBInternal(pixels, nLeds); - mWait.mark(); - } - - template<int BITS,int PX> __attribute__ ((always_inline)) inline static void writeBits(register uint32_t & next_mark, register Lines & b, Lines & b3, PixelController<RGB_ORDER,LANES, PORT_MASK> &pixels) { // , register uint32_t & b2) { - register Lines b2; - transpose8x1(b.bytes,b2.bytes); - - register uint8_t d = pixels.template getd<PX>(pixels); - register uint8_t scale = pixels.template getscale<PX>(pixels); - - for(uint32_t i = 0; (i < LANES) && (i<8); i++) { - while(DUE_TIMER_VAL < next_mark); - next_mark = (DUE_TIMER_VAL+TOTAL); - - *FastPin<FIRST_PIN>::sport() = PORT_MASK; - - while((next_mark - DUE_TIMER_VAL) > (T2+T3+6)); - *FastPin<FIRST_PIN>::cport() = (~b2.bytes[7-i]) & PORT_MASK; - - while((next_mark - (DUE_TIMER_VAL)) > T3); - *FastPin<FIRST_PIN>::cport() = PORT_MASK; - - b3.bytes[i] = pixels.template loadAndScale<PX>(pixels,i,d,scale); - } - - for(uint32_t i = LANES; i < 8; i++) { - while(DUE_TIMER_VAL > next_mark); - - next_mark = DUE_TIMER_VAL - (TOTAL-3); - *FastPin<FIRST_PIN>::sport() = PORT_MASK; - - while((next_mark - DUE_TIMER_VAL) > (T2+T3+6)); - *FastPin<FIRST_PIN>::cport() = (~b2.bytes[7-i]) & PORT_MASK; - - while((next_mark - DUE_TIMER_VAL) > T3); - *FastPin<FIRST_PIN>::cport() = PORT_MASK; - } - } + virtual void showPixels(PixelController<RGB_ORDER, LANES, 0xFF> & pixels) { + mWait.wait(); + showRGBInternal(pixels); + sei(); + mWait.mark(); + } - // 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, LANES, PORT_MASK> &allpixels, int nLeds) { + static uint32_t showRGBInternal(PixelController<RGB_ORDER, LANES, PORT_MASK> &allpixels) { // Serial.println("Entering show"); - // Setup the pixel controller and load/scale the first byte + + int nLeds = allpixels.mLen; + + // Setup the pixel controller and load/scale the first byte Lines b0,b1,b2; allpixels.preStepFirstByteDithering(); - for(int i = 0; i < LANES; i++) { + for(uint8_t i = 0; i < LANES; i++) { b0.bytes[i] = allpixels.loadAndScale0(i); } @@ -189,6 +139,42 @@ public: return DUE_TIMER_VAL; } + template<int BITS,int PX> __attribute__ ((always_inline)) inline static void writeBits(register uint32_t & next_mark, register Lines & b, Lines & b3, PixelController<RGB_ORDER,LANES, PORT_MASK> &pixels) { // , register uint32_t & b2) { + Lines b2; + transpose8x1(b.bytes,b2.bytes); + + register uint8_t d = pixels.template getd<PX>(pixels); + register uint8_t scale = pixels.template getscale<PX>(pixels); + + for(uint32_t i = 0; (i < LANES) && (i<8); i++) { + while(DUE_TIMER_VAL < next_mark); + next_mark = (DUE_TIMER_VAL+TOTAL); + + *FastPin<FIRST_PIN>::sport() = PORT_MASK; + + while((next_mark - DUE_TIMER_VAL) > (T2+T3+6)); + *FastPin<FIRST_PIN>::cport() = (~b2.bytes[7-i]) & PORT_MASK; + + while((next_mark - (DUE_TIMER_VAL)) > T3); + *FastPin<FIRST_PIN>::cport() = PORT_MASK; + + b3.bytes[i] = pixels.template loadAndScale<PX>(pixels,i,d,scale); + } + + for(uint32_t i = LANES; i < 8; i++) { + while(DUE_TIMER_VAL > next_mark); + + next_mark = DUE_TIMER_VAL - (TOTAL-3); + *FastPin<FIRST_PIN>::sport() = PORT_MASK; + + while((next_mark - DUE_TIMER_VAL) > (T2+T3+6)); + *FastPin<FIRST_PIN>::cport() = (~b2.bytes[7-i]) & PORT_MASK; + + while((next_mark - DUE_TIMER_VAL) > T3); + *FastPin<FIRST_PIN>::cport() = PORT_MASK; + } + } + }; |