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 <danielgarcia@gmail.com>2016-01-24 01:10:13 +0300
committerDaniel Garcia <danielgarcia@gmail.com>2016-01-24 01:10:13 +0300
commitdbf4292184110d1a5e36818c437a44004786c92f (patch)
treea0761df2ce1ff676ff0e0ee98e852f072674428f
parent1e21888813ddd280e59d3d2711569a14dee16771 (diff)
Switch Teensy parallel output to use CPixelLEDController objects
-rw-r--r--FastLED.h4
-rw-r--r--platforms/arm/k20/clockless_block_arm_k20.h181
2 files changed, 71 insertions, 114 deletions
diff --git a/FastLED.h b/FastLED.h
index 496411a1..5cf6d3fa 100644
--- a/FastLED.h
+++ b/FastLED.h
@@ -388,8 +388,8 @@ public:
case WS2811_400_PORTD: return addLeds(new InlineBlockClocklessController<NUM_LANES, PORTD_FIRST_PIN, NS(800), NS(800), NS(900), RGB_ORDER>(), data, nLedsOrOffset, nLedsIfOffset);
#endif
#ifdef HAS_PORTDC
- case WS2811_PORTDC: return addLeds(new SixteenWayInlineBlockClocklessController<16,NS(320), NS(320), NS(640), RGB_ORDER>(), data, nLedsOrOffset, nLedsIfOffset);
- case WS2811_400_PORTDC: return addLeds(new SixteenWayInlineBlockClocklessController<16,NS(800), NS(800), NS(900), RGB_ORDER>(), data, nLedsOrOffset, nLedsIfOffset);
+ case WS2811_PORTDC: return addLeds(new SixteenWayInlineBlockClocklessController<NUM_LANES,NS(320), NS(320), NS(640), RGB_ORDER>(), data, nLedsOrOffset, nLedsIfOffset);
+ case WS2811_400_PORTDC: return addLeds(new SixteenWayInlineBlockClocklessController<NUM_LANES,NS(800), NS(800), NS(900), RGB_ORDER>(), data, nLedsOrOffset, nLedsIfOffset);
#endif
}
}
diff --git a/platforms/arm/k20/clockless_block_arm_k20.h b/platforms/arm/k20/clockless_block_arm_k20.h
index b5e4007a..f2b76468 100644
--- a/platforms/arm/k20/clockless_block_arm_k20.h
+++ b/platforms/arm/k20/clockless_block_arm_k20.h
@@ -13,14 +13,14 @@
#define PORT_MASK (((1<<LANES)-1) & ((FIRST_PIN==2) ? 0xFF : 0xFFF))
#define MIN(X,Y) (((X)<(Y)) ? (X):(Y))
-#define LANES ((FIRST_PIN==2) ? MIN(__LANES,8) : MIN(__LANES,12))
+#define USED_LANES ((FIRST_PIN==2) ? MIN(LANES,8) : MIN(LANES,12))
#include "kinetis.h"
FASTLED_NAMESPACE_BEGIN
-template <uint8_t __LANES, int FIRST_PIN, int T1, int T2, int T3, EOrder RGB_ORDER = GRB, int XTRA0 = 0, bool FLIP = false, int WAIT_TIME = 40>
-class InlineBlockClocklessController : public CLEDController {
+template <uint8_t LANES, int FIRST_PIN, int T1, int T2, int T3, EOrder RGB_ORDER = GRB, int XTRA0 = 0, bool FLIP = false, int WAIT_TIME = 40>
+class InlineBlockClocklessController : public CPixelLEDController<RGB_ORDER, LANES, PORT_MASK> {
typedef typename FastPin<FIRST_PIN>::port_ptr_t data_ptr_t;
typedef typename FastPin<FIRST_PIN>::port_t data_t;
@@ -28,11 +28,23 @@ 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 showPixels(PixelController<RGB_ORDER, LANES, PORT_MASK> & pixels) {
+ mWait.wait();
+ uint32_t clocks = showRGBInternal(pixels);
+ #if FASTLED_ALLOW_INTTERUPTS == 0
+ // Adjust the timer
+ long microsTaken = CLKS_TO_MICROS(clocks);
+ MS_COUNTER += (1 + (microsTaken / 1000));
+ #endif
+
+ mWait.mark();
+ }
virtual void init() {
if(FIRST_PIN == PORTC_FIRST_PIN) { // PORTC
- switch(LANES) {
+ switch(USED_LANES) {
case 12: FastPin<30>::setOutput();
case 11: FastPin<29>::setOutput();
case 10: FastPin<27>::setOutput();
@@ -47,7 +59,7 @@ public:
case 1: FastPin<15>::setOutput();
}
} else if(FIRST_PIN == PORTD_FIRST_PIN) { // PORTD
- switch(LANES) {
+ switch(USED_LANES) {
case 8: FastPin<5>::setOutput();
case 7: FastPin<21>::setOutput();
case 6: FastPin<20>::setOutput();
@@ -64,39 +76,6 @@ 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();
- 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();
- }
-
- virtual void show(const struct CRGB *rgbdata, int nLeds, CRGB scale) {
- PixelController<RGB_ORDER,LANES,PORT_MASK> 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();
- }
-
-
-
typedef union {
uint8_t bytes[12];
uint16_t shorts[6];
@@ -105,7 +84,7 @@ public:
template<int BITS,int PX> __attribute__ ((always_inline)) inline static void writeBits(register uint32_t & next_mark, register Lines & b, PixelController<RGB_ORDER, LANES, PORT_MASK> &pixels) { // , register uint32_t & b2) {
register Lines b2;
- if(LANES>8) {
+ if(USED_LANES>8) {
transpose8<1,2>(b.bytes,b2.bytes);
transpose8<1,2>(b.bytes+8,b2.bytes+1);
} else {
@@ -114,13 +93,13 @@ public:
register uint8_t d = pixels.template getd<PX>(pixels);
register uint8_t scale = pixels.template getscale<PX>(pixels);
- for(register uint32_t i = 0; i < (LANES/2); i++) {
+ for(register uint32_t i = 0; i < (USED_LANES/2); i++) {
while(ARM_DWT_CYCCNT < next_mark);
next_mark = ARM_DWT_CYCCNT + (T1+T2+T3)-3;
*FastPin<FIRST_PIN>::sport() = PORT_MASK;
while((next_mark - ARM_DWT_CYCCNT) > (T2+T3+(2*(F_CPU/24000000))));
- if(LANES>8) {
+ if(USED_LANES>8) {
*FastPin<FIRST_PIN>::cport() = ((~b2.shorts[i]) & PORT_MASK);
} else {
*FastPin<FIRST_PIN>::cport() = ((~b2.bytes[7-i]) & PORT_MASK);
@@ -130,20 +109,20 @@ public:
*FastPin<FIRST_PIN>::cport() = PORT_MASK;
b.bytes[i] = pixels.template loadAndScale<PX>(pixels,i,d,scale);
- b.bytes[i+(LANES/2)] = pixels.template loadAndScale<PX>(pixels,i+(LANES/2),d,scale);
+ b.bytes[i+(USED_LANES/2)] = pixels.template loadAndScale<PX>(pixels,i+(USED_LANES/2),d,scale);
}
// if folks use an odd numnber of lanes, get the last byte's value here
- if(LANES & 0x01) {
- b.bytes[LANES-1] = pixels.template loadAndScale<PX>(pixels,LANES-1,d,scale);
+ if(USED_LANES & 0x01) {
+ b.bytes[USED_LANES-1] = pixels.template loadAndScale<PX>(pixels,USED_LANES-1,d,scale);
}
- for(register uint32_t i = LANES/2; i < 8; i++) {
+ for(register uint32_t i = USED_LANES/2; i < 8; i++) {
while(ARM_DWT_CYCCNT < next_mark);
next_mark = ARM_DWT_CYCCNT + (T1+T2+T3)-3;
*FastPin<FIRST_PIN>::sport() = PORT_MASK;
while((next_mark - ARM_DWT_CYCCNT) > (T2+T3+(2*(F_CPU/24000000))));
- if(LANES>8) {
+ if(USED_LANES>8) {
*FastPin<FIRST_PIN>::cport() = ((~b2.shorts[i]) & PORT_MASK);
} else {
// b2.bytes[0] = 0;
@@ -154,28 +133,13 @@ public:
*FastPin<FIRST_PIN>::cport() = PORT_MASK;
}
-
-
- // while(ARM_DWT_CYCCNT < next_mark);
- // next_mark = ARM_DWT_CYCCNT + (T1+T2+T3)-3;
- // *FastPin<FIRST_PIN>::sport() = PORT_MASK;
- //
- // while((next_mark - ARM_DWT_CYCCNT) > (T2+T3+6));
- // if(LANES>8) {
- // *FastPin<FIRST_PIN>::cport() = ((~b2.shorts[7]) & PORT_MASK);
- // } else {
- // *FastPin<FIRST_PIN>::cport() = PORT_MASK; // ((~b2.bytes[7-i]) & PORT_MASK);
- // }
- //
- // while((next_mark - ARM_DWT_CYCCNT) > (T3));
- // *FastPin<FIRST_PIN>::cport() = PORT_MASK;
}
// 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) {
// Get access to the clock
ARM_DEMCR |= ARM_DEMCR_TRCENA;
ARM_DWT_CTRL |= ARM_DWT_CTRL_CYCCNTENA;
@@ -186,14 +150,14 @@ public:
register Lines b0;
allpixels.preStepFirstByteDithering();
- for(int i = 0; i < LANES; i++) {
+ for(int i = 0; i < USED_LANES; i++) {
b0.bytes[i] = allpixels.loadAndScale0(i);
}
cli();
uint32_t next_mark = ARM_DWT_CYCCNT + (T1+T2+T3);
- while(nLeds--) {
+ while(allpixels.has(1)) {
#if (FASTLED_ALLOW_INTERRUPTS == 1)
cli();
// if interrupts took longer than 45µs, punt on the current frame
@@ -221,13 +185,12 @@ public:
}
};
-#define DLANES (MIN(__LANES,16))
-#define PMASK ((1<<(DLANES))-1)
+#define PMASK ((1<<(LANES))-1)
#define PMASK_HI (PMASK>>8 & 0xFF)
#define PMASK_LO (PMASK & 0xFF)
-template <uint8_t __LANES, int T1, int T2, int T3, EOrder RGB_ORDER = GRB, int XTRA0 = 0, bool FLIP = false, int WAIT_TIME = 50>
-class SixteenWayInlineBlockClocklessController : public CLEDController {
+template <uint8_t LANES, int T1, int T2, int T3, EOrder RGB_ORDER = GRB, int XTRA0 = 0, bool FLIP = false, int WAIT_TIME = 50>
+class SixteenWayInlineBlockClocklessController : public CPixelLEDController<RGB_ORDER, LANES, PMASK> {
typedef typename FastPin<PORTC_FIRST_PIN>::port_ptr_t data_ptr_t;
typedef typename FastPin<PORTC_FIRST_PIN>::port_t data_t;
@@ -236,47 +199,41 @@ class SixteenWayInlineBlockClocklessController : public CLEDController {
CMinWait<WAIT_TIME> mWait;
public:
virtual void init() {
- // FastPin<30>::setOutput();
- // FastPin<29>::setOutput();
- // FastPin<27>::setOutput();
- // FastPin<28>::setOutput();
- switch(DLANES) {
- case 16: FastPin<12>::setOutput();
- case 15: FastPin<11>::setOutput();
- case 14: FastPin<13>::setOutput();
- case 13: FastPin<10>::setOutput();
- case 12: FastPin<9>::setOutput();
- case 11: FastPin<23>::setOutput();
- case 10: FastPin<22>::setOutput();
- case 9: FastPin<15>::setOutput();
-
- case 8: FastPin<5>::setOutput();
- case 7: FastPin<21>::setOutput();
- case 6: FastPin<20>::setOutput();
- case 5: FastPin<6>::setOutput();
- case 4: FastPin<8>::setOutput();
- case 3: FastPin<7>::setOutput();
- case 2: FastPin<14>::setOutput();
- case 1: FastPin<2>::setOutput();
- }
- }
-
- virtual void clearLeds(int nLeds) {
- showColor(CRGB(0, 0, 0), nLeds, 0);
+ static_assert(LANES <= 16, "Maximum of 16 lanes for Teensy parallel controllers!");
+ // FastPin<30>::setOutput();
+ // FastPin<29>::setOutput();
+ // FastPin<27>::setOutput();
+ // FastPin<28>::setOutput();
+ switch(LANES) {
+ case 16: FastPin<12>::setOutput();
+ case 15: FastPin<11>::setOutput();
+ case 14: FastPin<13>::setOutput();
+ case 13: FastPin<10>::setOutput();
+ case 12: FastPin<9>::setOutput();
+ case 11: FastPin<23>::setOutput();
+ case 10: FastPin<22>::setOutput();
+ case 9: FastPin<15>::setOutput();
+
+ case 8: FastPin<5>::setOutput();
+ case 7: FastPin<21>::setOutput();
+ case 6: FastPin<20>::setOutput();
+ case 5: FastPin<6>::setOutput();
+ case 4: FastPin<8>::setOutput();
+ case 3: FastPin<7>::setOutput();
+ case 2: FastPin<14>::setOutput();
+ case 1: FastPin<2>::setOutput();
+ }
}
- // 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,DLANES,PMASK> pixels(rgbdata,nLeds, scale, getDither() );
+ virtual void showPixels(PixelController<RGB_ORDER, LANES, PMASK> & pixels) {
mWait.wait();
- showRGBInternal(pixels,nLeds);
- mWait.mark();
- }
+ uint32_t clocks = showRGBInternal(pixels);
+ #if FASTLED_ALLOW_INTTERUPTS == 0
+ // Adjust the timer
+ long microsTaken = CLKS_TO_MICROS(clocks);
+ MS_COUNTER += (1 + (microsTaken / 1000));
+ #endif
- virtual void show(const struct CRGB *rgbdata, int nLeds, CRGB scale) {
- PixelController<RGB_ORDER,DLANES,PMASK> pixels(rgbdata,nLeds, scale, getDither() );
- mWait.wait();
- showRGBInternal(pixels,nLeds);
mWait.mark();
}
@@ -286,14 +243,14 @@ public:
uint32_t raw[4];
} Lines;
- template<int BITS,int PX> __attribute__ ((always_inline)) inline static void writeBits(register uint32_t & next_mark, register Lines & b, PixelController<RGB_ORDER,DLANES, PMASK> &pixels) { // , register uint32_t & b2) {
+ template<int BITS,int PX> __attribute__ ((always_inline)) inline static void writeBits(register uint32_t & next_mark, register Lines & b, PixelController<RGB_ORDER,LANES, PMASK> &pixels) { // , register uint32_t & b2) {
register Lines b2;
transpose8x1(b.bytes,b2.bytes);
transpose8x1(b.bytes+8,b2.bytes+8);
register uint8_t d = pixels.template getd<PX>(pixels);
register uint8_t scale = pixels.template getscale<PX>(pixels);
- for(register uint32_t i = 0; (i < DLANES) && (i < 8); i++) {
+ for(register uint32_t i = 0; (i < LANES) && (i < 8); i++) {
while(ARM_DWT_CYCCNT < next_mark);
next_mark = ARM_DWT_CYCCNT + (T1+T2+T3)-3;
*FastPin<PORTD_FIRST_PIN>::sport() = PMASK_LO;
@@ -308,7 +265,7 @@ public:
*FastPin<PORTC_FIRST_PIN>::cport() = PMASK_HI;
b.bytes[i] = pixels.template loadAndScale<PX>(pixels,i,d,scale);
- if(DLANES==16 || (DLANES>8 && ((i+8) < DLANES))) {
+ if(LANES==16 || (LANES>8 && ((i+8) < LANES))) {
b.bytes[i+8] = pixels.template loadAndScale<PX>(pixels,i+8,d,scale);
}
}
@@ -318,7 +275,7 @@ public:
// 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,DLANES, PMASK> &allpixels, int nLeds) {
+ static uint32_t showRGBInternal(PixelController<RGB_ORDER,LANES, PMASK> &allpixels) {
// Get access to the clock
ARM_DEMCR |= ARM_DEMCR_TRCENA;
ARM_DWT_CTRL |= ARM_DWT_CTRL_CYCCNTENA;
@@ -329,14 +286,14 @@ public:
register Lines b0;
allpixels.preStepFirstByteDithering();
- for(int i = 0; i < DLANES; i++) {
+ for(int i = 0; i < LANES; i++) {
b0.bytes[i] = allpixels.loadAndScale0(i);
}
cli();
uint32_t next_mark = ARM_DWT_CYCCNT + (T1+T2+T3);
- while(nLeds--) {
+ while(allpixels.has(1)) {
allpixels.stepDithering();
#if 0 && (FASTLED_ALLOW_INTERRUPTS == 1)
cli();