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:
-rw-r--r--clockless_arm_sam.h130
-rw-r--r--clockless_block_arm_sam.h62
-rw-r--r--examples/Cylon/Cylon.ino13
-rw-r--r--led_sysdefs.h20
4 files changed, 67 insertions, 158 deletions
diff --git a/clockless_arm_sam.h b/clockless_arm_sam.h
index 68617af2..0c38b611 100644
--- a/clockless_arm_sam.h
+++ b/clockless_arm_sam.h
@@ -40,39 +40,14 @@ protected:
virtual void showColor(const struct CRGB & rgbdata, int nLeds, CRGB scale) {
PixelController<RGB_ORDER> pixels(rgbdata, nLeds, scale, getDither());
mWait.wait();
- cli();
- SysClockSaver savedClock(TOTAL);
-
- uint32_t clocks = showRGBInternal(pixels);
-
- // Adjust the timer
- long microsTaken = CLKS_TO_MICROS(clocks);
- long millisTaken = (microsTaken / 1000);
- savedClock.restore();
- do { TimeTick_Increment(); } while(--millisTaken > 0);
- sei();
+ 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();
- cli();
- SysClockSaver savedClock(TOTAL);
-
- // Serial.print("Scale is ");
- // Serial.print(scale.raw[0]); Serial.print(" ");
- // Serial.print(scale.raw[1]); Serial.print(" ");
- // Serial.print(scale.raw[2]); Serial.println(" ");
- // FastPinBB<DATA_PIN>::hi(); delay(1); FastPinBB<DATA_PIN>::lo();
- uint32_t clocks = showRGBInternal(pixels);
-
- // Adjust the timer
- long microsTaken = CLKS_TO_MICROS(clocks);
- long millisTaken = (microsTaken / 1000);
- savedClock.restore();
- do { TimeTick_Increment(); } while(--millisTaken > 0);
- sei();
+ showRGBInternal(pixels);
mWait.mark();
}
@@ -80,97 +55,32 @@ protected:
virtual void show(const struct CARGB *rgbdata, int nLeds, CRGB scale) {
PixelController<RGB_ORDER> pixels(rgbdata, nLeds, scale, getDither());
mWait.wait();
- cli();
- SysClockSaver savedClock(TOTAL);
-
- uint32_t clocks = showRGBInternal(pixels);
-
- // Adjust the timer
- long microsTaken = CLKS_TO_MICROS(clocks);
- long millisTaken = (microsTaken / 1000);
- savedClock.restore();
- do { TimeTick_Increment(); } while(--millisTaken > 0);
+ showRGBInternal(pixels);
sei();
mWait.mark();
}
#endif
-#if 0
-// Get the arm defs, register/macro defs from the k20
-#define ARM_DEMCR *(volatile uint32_t *)0xE000EDFC // Debug Exception and Monitor Control
-#define ARM_DEMCR_TRCENA (1 << 24) // Enable debugging & monitoring blocks
-#define ARM_DWT_CTRL *(volatile uint32_t *)0xE0001000 // DWT control register
-#define ARM_DWT_CTRL_CYCCNTENA (1 << 0) // Enable cycle count
-#define ARM_DWT_CYCCNT *(volatile uint32_t *)0xE0001004 // Cycle count register
-
- template<int BITS> __attribute__ ((always_inline)) inline static void writeBits(register uint32_t & next_mark, register data_ptr_t port, register uint8_t & b) {
- for(register uint32_t i = BITS; i > 0; i--) {
- while(ARM_DWT_CYCCNT < next_mark);
- next_mark = ARM_DWT_CYCCNT + (T1+T2+T3);
- *port = 1;
- uint32_t flip_mark = next_mark - ((b&0x80) ? (T3) : (T2+T3));
- b <<= 1;
- while(ARM_DWT_CYCCNT < flip_mark);
- *port = 0;
- }
- }
-
- // 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 void showRGBInternal(PixelController<RGB_ORDER> pixels) {
- register data_ptr_t port = FastPinBB<DATA_PIN>::port();
- *port = 0;
-
- // Setup the pixel controller and load/scale the first byte
- pixels.preStepFirstByteDithering();
- register uint8_t b = pixels.loadAndScale0();
-
- // Get access to the clock
- ARM_DEMCR |= ARM_DEMCR_TRCENA;
- ARM_DWT_CTRL |= ARM_DWT_CTRL_CYCCNTENA;
- ARM_DWT_CYCCNT = 0;
- uint32_t next_mark = ARM_DWT_CYCCNT + (T1+T2+T3);
-
- while(pixels.has(1)) {
- pixels.stepDithering();
-
- // Write first byte, read next byte
- writeBits<8+XTRA0>(next_mark, port, b);
- b = pixels.loadAndScale1();
-
- // Write second byte, read 3rd byte
- writeBits<8+XTRA0>(next_mark, port, b);
- b = pixels.loadAndScale2();
-
- // Write third byte
- writeBits<8+XTRA0>(next_mark, port, b);
- b = pixels.advanceAndLoadAndScale0();
- };
- }
-#else
-// I hate using defines for these, should find a better representation at some point
-#define _CTRL CTPTR[0]
-#define _LOAD CTPTR[1]
-#define _VAL CTPTR[2]
-#define VAL (volatile uint32_t)(*((uint32_t*)(SysTick_BASE + 8)))
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
- // while(VAL < (TOTAL*10));
+ // bool bShift=0;
+ // while(VAL < (TOTAL*10)) { bShift=true; }
+ // if(bShift) { next_mark = (VAL-TOTAL); };
for(register uint32_t i = BITS; i > 0; i--) {
// wait to start the bit, then set the pin high
- while(VAL > next_mark);
- next_mark = (VAL-TOTAL);
+ while(DUE_TIMER_VAL < next_mark);
+ next_mark = (DUE_TIMER_VAL+TOTAL);
*port = 1;
// how long we want to wait next depends on whether or not our bit is set to 1 or 0
if(b&0x80) {
// we're a 1, wait until there's less than T3 clocks left
- while((VAL - next_mark) > (T3));
+ while((next_mark - DUE_TIMER_VAL) > (T3));
} else {
// we're a 0, wait until there's less than (T2+T3+slop) clocks left in this bit
- while((VAL-next_mark) > (T2+T3+6+TADJUST+TADJUST));
+ while((next_mark - DUE_TIMER_VAL) > (T2+T3+6+TADJUST+TADJUST));
}
*port=0;
b <<= 1;
@@ -182,11 +92,9 @@ protected:
// gcc will use register Y for the this pointer.
static uint32_t showRGBInternal(PixelController<RGB_ORDER> & pixels) {
// Setup and start the clock
- register volatile uint32_t *CTPTR asm("r6")= &SysTick->CTRL; FORCE_REFERENCE(CTPTR);
- _LOAD = 0x00FFFFFF;
- _VAL = 0;
- _CTRL |= SysTick_CTRL_CLKSOURCE_Msk;
- _CTRL |= SysTick_CTRL_ENABLE_Msk;
+ TC_Configure(DUE_TIMER,DUE_TIMER_CHANNEL,TC_CMR_TCCLKS_TIMER_CLOCK1);
+ pmc_enable_periph_clk(DUE_TIMER_ID);
+ TC_Start(DUE_TIMER,DUE_TIMER_CHANNEL);
register data_ptr_t port asm("r7") = FastPinBB<DATA_PIN>::port(); FORCE_REFERENCE(port);
*port = 0;
@@ -195,11 +103,15 @@ protected:
pixels.preStepFirstByteDithering();
register uint8_t b = pixels.loadAndScale0();
- // while(VAL < (TOTAL*10));
- uint32_t next_mark = (VAL - (TOTAL));
+ uint32_t next_mark = (VAL + (TOTAL));
while(pixels.has(1)) {
pixels.stepDithering();
+ cli();
+ if(DUE_TIMER_VAL > next_mark) {
+ if((DUE_TIMER_VAL - next_mark) > ((WAIT_TIME-INTERRUPT_THRESHOLD)*CLKS_PER_US)) { sei(); TC_Stop(DUE_TIMER,DUE_TIMER_CHANNEL); return DUE_TIMER_VAL; }
+ }
+
writeBits<8+XTRA0>(next_mark, port, b);
b = pixels.loadAndScale1();
@@ -209,9 +121,11 @@ protected:
writeBits<8+XTRA0>(next_mark, port,b);
b = pixels.advanceAndLoadAndScale0();
+ sei();
};
- return 0x00FFFFFF - _VAL;
+ TC_Stop(DUE_TIMER,DUE_TIMER_CHANNEL);
+ return DUE_TIMER_VAL;
}
#endif
};
diff --git a/clockless_block_arm_sam.h b/clockless_block_arm_sam.h
index f98afb16..6f9fc797 100644
--- a/clockless_block_arm_sam.h
+++ b/clockless_block_arm_sam.h
@@ -88,15 +88,7 @@ public:
virtual void showColor(const struct CRGB & rgbdata, int nLeds, CRGB scale) {
MultiPixelController<LANES,PORT_MASK,RGB_ORDER> pixels(rgbdata,nLeds, scale, getDither() );
mWait.wait();
- cli();
- SysClockSaver savedClock(TOTAL);
-
- uint32_t clocks = showRGBInternal(pixels, nLeds);
-
- long microsTaken = CLKS_TO_MICROS(clocks);
- long millisTaken = (microsTaken / 1000);
- savedClock.restore();
- while(millisTaken-- > 0) { TimeTick_Increment(); }
+ showRGBInternal(pixels, nLeds);
sei();
mWait.mark();
}
@@ -107,38 +99,18 @@ public:
virtual void show(const struct CRGB *rgbdata, int nLeds, CRGB scale) {
MultiPixelController<LANES,PORT_MASK,RGB_ORDER> pixels(rgbdata,nLeds, scale, getDither() );
mWait.wait();
- cli();
- SysClockSaver savedClock(TOTAL);
-
- uint32_t clocks = showRGBInternal(pixels, nLeds);
-
-
- long microsTaken = CLKS_TO_MICROS(clocks);
- long millisTaken = (microsTaken / 1000);
- savedClock.restore();
- while(millisTaken-- > 0) { TimeTick_Increment(); }
- sei();
+ showRGBInternal(pixels, nLeds);
mWait.mark();
}
#ifdef SUPPORT_ARGB
virtual void show(const struct CARGB *rgbdata, int nLeds, CRGB scale) {
mWait.wait();
- cli();
-
showRGBInternal(PixelController<RGB_ORDER>(rgbdata, nLeds, scale, getDither()));
-
-
- // Adjust the timer
- long microsTaken = nLeds * CLKS_TO_MICROS(24 * (T1 + T2 + T3));
- MS_COUNTER += (microsTaken / 1000);
- sei();
mWait.mark();
}
#endif
-#define VAL *((uint32_t*)(SysTick_BASE + 8))
-
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);
@@ -147,15 +119,15 @@ public:
register uint8_t scale = pixels.template getscale<PX>(pixels);
for(uint32_t i = 0; (i < LANES) && (i<8); i++) {
- while(VAL > next_mark);
+ while(DUE_TIMER_VAL < next_mark);
+ next_mark = (DUE_TIMER_VAL+TOTAL);
- next_mark = VAL - (TOTAL-12);
*FastPin<FIRST_PIN>::sport() = PORT_MASK;
- while((VAL-next_mark) > (T2+T3+6));
+ while(next_mark - DUE_TIMER_VAL) > (T2+T3+6));
*FastPin<FIRST_PIN>::cport() = (~b2.bytes[7-i]) & PORT_MASK;
- while((VAL - next_mark) > T3);
+ while((next_mark - DUE_TIMER_VAL) > T3);
*FastPin<FIRST_PIN>::cport() = PORT_MASK;
b3.bytes[i] = pixels.template loadAndScale<PX>(pixels,i,d,scale);
@@ -167,10 +139,10 @@ public:
next_mark = VAL - (TOTAL-3);
*FastPin<FIRST_PIN>::sport() = PORT_MASK;
- while((VAL-next_mark) > (T2+T3+6));
+ while(next_mark - DUE_TIMER_VAL) > (T2+T3+6));
*FastPin<FIRST_PIN>::cport() = (~b2.bytes[7-i]) & PORT_MASK;
- while((VAL - next_mark) > T3);
+ while((next_mark - DUE_TIMER_VAL) > T3);
*FastPin<FIRST_PIN>::cport() = PORT_MASK;
}
}
@@ -188,20 +160,20 @@ public:
}
// Setup and start the clock
- register volatile uint32_t *CTPTR asm("r6")= &SysTick->CTRL; FORCE_REFERENCE(CTPTR);
- _LOAD = 0x00FFFFFF;
- _VAL = 0;
- _CTRL |= SysTick_CTRL_CLKSOURCE_Msk;
- _CTRL |= SysTick_CTRL_ENABLE_Msk;
+ TC_Configure(DUE_TIMER,DUE_TIMER_CHANNEL,TC_CMR_TCCLKS_TIMER_CLOCK1);
+ pmc_enable_periph_clk(DUE_TIMER_ID);
+ TC_Start(DUE_TIMER,DUE_TIMER_CHANNEL);
VAL = 0;
cli();
- uint32_t next_mark = (VAL - (TOTAL));
+ uint32_t next_mark = (DUE_TIMER_VAL + (TOTAL));
while(nLeds--) {
allpixels.stepDithering();
cli();
- if(VAL < next_mark) {
- if((next_mark - VAL) > ((WAIT_TIME*5)*CLKS_PER_US)) { sei(); return 0x00FFFFF - _VAL; }
+ if(DUE_TIMER_VAL > next_mark) {
+ if((DUE_TIMER_VAL - next_mark) > ((WAIT_TIME-INTERRUPT_THRESHOLD)*CLKS_PER_US)) {
+ sei(); TC_Stop(DUE_TIMER,DUE_TIMER_CHANNEL); return DUE_TIMER_VAL;
+ }
}
// Write first byte, read next byte
@@ -216,7 +188,7 @@ public:
sei();
}
- return 0x00FFFFFF - _VAL;
+ return DUE_TIMER_VAL;
}
diff --git a/examples/Cylon/Cylon.ino b/examples/Cylon/Cylon.ino
index 56e2d1d5..76046b41 100644
--- a/examples/Cylon/Cylon.ino
+++ b/examples/Cylon/Cylon.ino
@@ -10,9 +10,11 @@
#define CLOCK_PIN 13
// Define the array of leds
-CRGB leds[40];
+CRGB leds[NUM_LEDS];
void setup() {
+ Serial.begin(57600);
+ Serial.println("resetting");
LEDS.addLeds<NEOPIXEL,DATA_PIN>(leds,NUM_LEDS);
LEDS.setBrightness(84);
}
@@ -20,8 +22,8 @@ void setup() {
void fadeall() { for(int i = 0; i < NUM_LEDS; i++) { leds[i].nscale8(250); } }
void loop() {
- uint8_t hue = 0;
- // Serial.print("x");
+ static uint8_t hue = 0;
+ Serial.print("x");
// First slide the led in one direction
for(int i = 0; i < NUM_LEDS; i++) {
// Set the i'th led to red
@@ -32,8 +34,9 @@ void loop() {
// leds[i] = CRGB::Black;
fadeall();
// Wait a little bit before we loop around and do it again
- delay(100);
+ delay(10);
}
+ Serial.print("x");
// Now go in the other direction.
for(int i = (NUM_LEDS)-1; i >= 0; i--) {
@@ -45,6 +48,6 @@ void loop() {
// leds[i] = CRGB::Black;
fadeall();
// Wait a little bit before we loop around and do it again
- delay(100);
+ delay(10);
}
}
diff --git a/led_sysdefs.h b/led_sysdefs.h
index 894055f1..3ec49ad6 100644
--- a/led_sysdefs.h
+++ b/led_sysdefs.h
@@ -2,6 +2,7 @@
#define __INC_LED_SYSDEFS_H
#if defined(__MK20DX128__) || defined(__MK20DX256__)
+
#define FASTLED_TEENSY3
#define FASTLED_ARM
#define FASTLED_ACCURATE_CLOCK
@@ -11,14 +12,33 @@
#if (F_CPU == 96000000)
#define CLK_DBL 1
#endif
+
#elif defined(__SAM3X8E__)
+
#define FASTLED_ARM
+
+// Setup DUE timer defines/channels/etc...
+#ifndef DUE_TIMER_CHANNEL
+#define DUE_TIMER_GROUP 0
+#endif
+
+#ifndef DUE_TIMER_CHANNEL
+#define DUE_TIMER_CHANNEL 0
+#endif
+
+#define DUE_TIMER ((DUE_TIMER_GROUP==0) ? TC0 : ((DUE_TIMER_GROUP==1) ? TC1 : TC2))
+#define DUE_TIMER_ID (ID_TC0 + (DUE_TIMER_GROUP*3) + DUE_TIMER_CHANNEL)
+#define DUE_TIMER_VAL (DUE_TIMER->TC_CHANNEL[DUE_TIMER_CHANNEL].TC_CV << 1)
+#define DUE_TIMER_RUNNING ((DUE_TIMER->TC_CHANNEL[DUE_TIMER_CHANNEL].TC_SR & TC_SR_CLKSTA) != 0)
+
#else
+
#define FASTLED_AVR
#define FASTLED_ACCURATE_CLOCK
#ifndef INTERRUPT_THRESHOLD
#define INTERRUPT_THRESHOLD 10
#endif
+
#endif
#ifndef CLK_DBL