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>2014-11-24 23:11:38 +0300
committerDaniel Garcia <danielgarcia@gmail.com>2014-11-24 23:11:38 +0300
commitc2f9d3159ae858e6ca2af118cb3666f9a05d560f (patch)
tree63c7a89884a589763b86ba34d477fbfc3ff87c97
parentd51d5c7ce1ffeba8739cd0faaaaf5e8379a9176d (diff)
Add configuration option for allowing/disallowing interrupts. Disable by default for AVR, block out AVR implementation of wiring functions.
-rw-r--r--fastled_config.h7
-rw-r--r--led_sysdefs.h2
-rw-r--r--platforms.h2
-rw-r--r--platforms/arm/k20/clockless_arm_k20.h7
-rw-r--r--platforms/arm/k20/clockless_block_arm_k20.h37
-rw-r--r--platforms/arm/k20/led_sysdefs_arm_k20.h5
-rw-r--r--platforms/arm/sam/clockless_arm_sam.h4
-rw-r--r--platforms/arm/sam/clockless_block_arm_sam.h7
-rw-r--r--platforms/arm/sam/led_sysdefs_arm_sam.h5
-rw-r--r--platforms/avr/clockless_trinket.h20
-rw-r--r--platforms/avr/led_sysdefs_avr.h14
-rw-r--r--wiring.cpp4
12 files changed, 108 insertions, 6 deletions
diff --git a/fastled_config.h b/fastled_config.h
index 3e5a8c4e..e085f61a 100644
--- a/fastled_config.h
+++ b/fastled_config.h
@@ -9,4 +9,11 @@
// Use this option only for debugging bitbang'd spi access or to work around bugs in hardware
// spi access. Forces use of bit-banged spi, even on pins that has hardware SPI available.
// #define FORCE_SOFTWARE_SPI
+
+// Use this to force FastLED to allow interrupts in the clockless chipsets (or to force it to
+// disallow), overriding the default on platforms that support this. Set the value to 1 to
+// allow interrupts or 0 to disallow them.
+// #define FASTLED_ALLOW_INTERRUPTS 1
+// #define FASTLED_ALLOW_INTERRUPTS 0
+
#endif
diff --git a/led_sysdefs.h b/led_sysdefs.h
index 29bced42..3e7ebaa2 100644
--- a/led_sysdefs.h
+++ b/led_sysdefs.h
@@ -1,6 +1,8 @@
#ifndef __INC_LED_SYSDEFS_H
#define __INC_LED_SYSDEFS_H
+#include "fastled_config.h"
+
#if defined(__MK20DX128__) || defined(__MK20DX256__)
// Include k20/T3 headers
#include "platforms/arm/k20/led_sysdefs_arm_k20.h"
diff --git a/platforms.h b/platforms.h
index 9f1c7579..5b34ddc0 100644
--- a/platforms.h
+++ b/platforms.h
@@ -1,6 +1,8 @@
#ifndef __INC_PLATFORMS_H
#define __INC_PLATFORMS_H
+#include "fastled_config.h"
+
#if defined(__MK20DX128__) || defined(__MK20DX256__)
// Include k20/T3 headers
#include "platforms/arm/k20/fastled_arm_k20.h"
diff --git a/platforms/arm/k20/clockless_arm_k20.h b/platforms/arm/k20/clockless_arm_k20.h
index d96c9bb2..53b6f85b 100644
--- a/platforms/arm/k20/clockless_arm_k20.h
+++ b/platforms/arm/k20/clockless_arm_k20.h
@@ -97,17 +97,20 @@ protected:
pixels.preStepFirstByteDithering();
register uint8_t b = pixels.loadAndScale0();
+ #if (FASTLED_ALLOW_INTERRUPTS == 1)
cli();
uint32_t next_mark = ARM_DWT_CYCCNT + (T1+T2+T3);
+ #endif
while(pixels.has(1)) {
pixels.stepDithering();
+ #if (FASTLED_ALLOW_INTERRUPTS == 1)
cli();
// if interrupts took longer than 45µs, punt on the current frame
if(ARM_DWT_CYCCNT > next_mark) {
if((ARM_DWT_CYCCNT-next_mark) > ((WAIT_TIME-INTERRUPT_THRESHOLD)*CLKS_PER_US)) { sei(); return ARM_DWT_CYCCNT; }
}
-
+ #endif
// Write first byte, read next byte
writeBits<8+XTRA0>(next_mark, port, hi, lo, b);
b = pixels.loadAndScale1();
@@ -119,7 +122,9 @@ protected:
// Write third byte, read 1st byte of next pixel
writeBits<8+XTRA0>(next_mark, port, hi, lo, b);
b = pixels.advanceAndLoadAndScale0();
+ #if (FASTLED_ALLOW_INTERRUPTS == 1)
sei();
+ #endif
};
return ARM_DWT_CYCCNT;
diff --git a/platforms/arm/k20/clockless_block_arm_k20.h b/platforms/arm/k20/clockless_block_arm_k20.h
index 63dc5030..bebbf0d7 100644
--- a/platforms/arm/k20/clockless_block_arm_k20.h
+++ b/platforms/arm/k20/clockless_block_arm_k20.h
@@ -88,9 +88,9 @@ public:
typedef union {
- uint8_t bytes[16];
- uint16_t shorts[8];
- uint32_t raw[4];
+ uint8_t bytes[12];
+ uint16_t shorts[6];
+ uint32_t raw[3];
} Lines;
template<int BITS,int PX> __attribute__ ((always_inline)) inline static void writeBits(register uint32_t & next_mark, register Lines & b, MultiPixelController<LANES, PORT_MASK, RGB_ORDER> &pixels) { // , register uint32_t & b2) {
@@ -132,11 +132,11 @@ public:
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[i]) & PORT_MASK);
} else {
+ // b2.bytes[0] = 0;
*FastPin<FIRST_PIN>::cport() = ((~b2.bytes[7-i]) & PORT_MASK);
}
@@ -144,6 +144,21 @@ 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;
}
@@ -165,15 +180,19 @@ public:
b0.bytes[i] = allpixels.loadAndScale0(i);
}
+ #if (FASTLED_ALLOW_INTERRUPTS == 1)
cli();
uint32_t next_mark = ARM_DWT_CYCCNT + (T1+T2+T3);
+ #endif
while(nLeds--) {
+ #if (FASTLED_ALLOW_INTERRUPTS == 1)
cli();
// if interrupts took longer than 45µs, punt on the current frame
if(ARM_DWT_CYCCNT > next_mark) {
if((ARM_DWT_CYCCNT-next_mark) > ((WAIT_TIME-5)*CLKS_PER_US)) { sei(); return ARM_DWT_CYCCNT; }
}
+ #endif
allpixels.stepDithering();
// Write first byte, read next byte
@@ -185,7 +204,9 @@ public:
// Write third byte
writeBits<8+XTRA0,0>(next_mark, b0, allpixels);
+ #if (FASTLED_ALLOW_INTERRUPTS == 1)
sei();
+ #endif
};
return ARM_DWT_CYCCNT;
@@ -314,16 +335,21 @@ public:
b0.bytes[i] = allpixels.loadAndScale0(i);
}
+ #if (FASTLED_ALLOW_INTERRUPTS == 1)
cli();
uint32_t next_mark = ARM_DWT_CYCCNT + (T1+T2+T3);
+ #endif
while(nLeds--) {
allpixels.stepDithering();
+ #if (FASTLED_ALLOW_INTERRUPTS == 1)
cli();
// if interrupts took longer than 45µs, punt on the current frame
if(ARM_DWT_CYCCNT > next_mark) {
if((ARM_DWT_CYCCNT-next_mark) > ((WAIT_TIME-INTERRUPT_THRESHOLD)*CLKS_PER_US)) { sei(); return ARM_DWT_CYCCNT; }
}
+ #endif
+
// Write first byte, read next byte
writeBits<8+XTRA0,1>(next_mark, b0, allpixels);
@@ -333,7 +359,10 @@ public:
// Write third byte
writeBits<8+XTRA0,0>(next_mark, b0, allpixels);
+
+ #if (FASTLED_ALLOW_INTERRUPTS == 1)
sei();
+ #endif
};
return ARM_DWT_CYCCNT;
diff --git a/platforms/arm/k20/led_sysdefs_arm_k20.h b/platforms/arm/k20/led_sysdefs_arm_k20.h
index abed80f9..e0a8a979 100644
--- a/platforms/arm/k20/led_sysdefs_arm_k20.h
+++ b/platforms/arm/k20/led_sysdefs_arm_k20.h
@@ -9,6 +9,11 @@
#define INTERRUPT_THRESHOLD 1
#endif
+// Default to allowing interrupts
+#ifndef FASTLED_ALLOW_INTERRUPTS
+#define FASTLED_ALLOW_INTERRUPTS 1
+#endif
+
#if (F_CPU == 96000000)
#define CLK_DBL 1
#endif
diff --git a/platforms/arm/sam/clockless_arm_sam.h b/platforms/arm/sam/clockless_arm_sam.h
index 6924cc9d..ebc8c0ad 100644
--- a/platforms/arm/sam/clockless_arm_sam.h
+++ b/platforms/arm/sam/clockless_arm_sam.h
@@ -107,10 +107,12 @@ protected:
while(pixels.has(1)) {
pixels.stepDithering();
+ #if (FASTLED_ALLOW_INTERRUPTS == 1)
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; }
}
+ #endif
writeBits<8+XTRA0>(next_mark, port, b);
@@ -121,7 +123,9 @@ protected:
writeBits<8+XTRA0>(next_mark, port,b);
b = pixels.advanceAndLoadAndScale0();
+ #if (FASTLED_ALLOW_INTERRUPTS == 1)
sei();
+ #endif
};
TC_Stop(DUE_TIMER,DUE_TIMER_CHANNEL);
diff --git a/platforms/arm/sam/clockless_block_arm_sam.h b/platforms/arm/sam/clockless_block_arm_sam.h
index 51eb1b92..128617a2 100644
--- a/platforms/arm/sam/clockless_block_arm_sam.h
+++ b/platforms/arm/sam/clockless_block_arm_sam.h
@@ -159,16 +159,20 @@ public:
pmc_enable_periph_clk(DUE_TIMER_ID);
TC_Start(DUE_TIMER,DUE_TIMER_CHANNEL);
+ #if (FASTLED_ALLOW_INTERRUPTS == 1)
cli();
+ #endif
uint32_t next_mark = (DUE_TIMER_VAL + (TOTAL));
while(nLeds--) {
allpixels.stepDithering();
+ #if (FASTLED_ALLOW_INTERRUPTS == 1)
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;
}
}
+ #endif
// Write first byte, read next byte
writeBits<8+XTRA0,1>(next_mark, b0, b1, allpixels);
@@ -179,7 +183,10 @@ public:
allpixels.advanceData();
// Write third byte
writeBits<8+XTRA0,0>(next_mark, b2, b0, allpixels);
+
+ #if (FASTLED_ALLOW_INTERRUPTS == 1)
sei();
+ #endif
}
return DUE_TIMER_VAL;
diff --git a/platforms/arm/sam/led_sysdefs_arm_sam.h b/platforms/arm/sam/led_sysdefs_arm_sam.h
index e45f9609..a6ef12bb 100644
--- a/platforms/arm/sam/led_sysdefs_arm_sam.h
+++ b/platforms/arm/sam/led_sysdefs_arm_sam.h
@@ -22,6 +22,11 @@
#define INTERRUPT_THRESHOLD 1
#endif
+// Default to allowing interrupts
+#ifndef FASTLED_ALLOW_INTERRUPTS
+#define FASTLED_ALLOW_INTERRUPTS 1
+#endif
+
// reuseing/abusing cli/sei defs for due
#define cli() __disable_irq(); __disable_fault_irq();
#define sei() __enable_irq(); __enable_fault_irq();
diff --git a/platforms/avr/clockless_trinket.h b/platforms/avr/clockless_trinket.h
index 4630719d..fd831319 100644
--- a/platforms/avr/clockless_trinket.h
+++ b/platforms/avr/clockless_trinket.h
@@ -104,6 +104,16 @@ protected:
showRGBInternal(pixels);
+ // 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));
+ if(microsTaken > 1024) {
+ MS_COUNTER += (microsTaken >> 10);
+ } else {
+ MS_COUNTER++;
+ }
+ #endif
+
sei();
mWait.mark();
}
@@ -243,9 +253,11 @@ protected:
uint8_t loopvar=0;
+ #if (FASTLED_ALLOW_INTERRUPTS == 1)
TCCR0A |= 0x30;
OCR0B = (uint8_t)(TCNT0 + ((WAIT_TIME-INTERRUPT_THRESHOLD)/US_PER_TICK));
TIFR0 = 0x04;
+ #endif
{
while(count--)
{
@@ -256,8 +268,8 @@ protected:
ADJDITHER2(d1,e1);
ADJDITHER2(d2,e2);
+ #if (FASTLED_ALLOW_INTERRUPTS == 1)
cli();
-
if(TIFR0 & 0x04) {
sei();
TCCR0A &= ~0x30;
@@ -265,6 +277,7 @@ protected:
}
hi = *port | mask;
lo = *port & ~mask;
+ #endif
// Sum of the clock counts across each row should be 10 for 8Mhz, WS2811
// The values in the D1/D2/D3 indicate how many cycles the previous column takes
@@ -347,15 +360,20 @@ protected:
HI1 D1(1) QLO2(b2, 1) D2(0) LO1 D3(0)
HI1 D1(1) QLO2(b2, 0) D2(0) LO1 D3(0)
#endif
+
+ #if (FASTLED_ALLOW_INTERRUPTS == 1)
// set the counter mark
OCR0B = (uint8_t)(TCNT0 + ((WAIT_TIME-INTERRUPT_THRESHOLD)/US_PER_TICK));
TIFR0 = 0x04;
sei();
+ #endif
}
}
+ #if (FASTLED_ALLOW_INTERRUPTS == 1)
// stop using the clock juggler
TCCR0A &= ~0x30;
+ #endif
}
#ifdef SUPPORT_ARGB
diff --git a/platforms/avr/led_sysdefs_avr.h b/platforms/avr/led_sysdefs_avr.h
index 19cfabee..e4972c7d 100644
--- a/platforms/avr/led_sysdefs_avr.h
+++ b/platforms/avr/led_sysdefs_avr.h
@@ -18,4 +18,18 @@ typedef volatile uint8_t RwReg; /**< Read-Write 8-bit register (volatile u
#endif
+// Default to disallowing interrupts (may want to gate this on teensy2 vs. other arm platforms, since the
+// teensy2 has a good, fast millis interrupt implementation)
+#ifndef FASTLED_ALLOW_INTERRUPTS
+#define FASTLED_ALLOW_INTERRUPTS 0
+#endif
+
+# if defined(CORE_TEENSY)
+extern volatile unsigned long timer0_millis_count;
+# define MS_COUNTER timer0_millis_count
+# else
+extern volatile unsigned long timer0_millis;
+# define MS_COUNTER timer0_millis
+# endif
+
#endif
diff --git a/wiring.cpp b/wiring.cpp
index a3ee6d15..62317b2a 100644
--- a/wiring.cpp
+++ b/wiring.cpp
@@ -1,6 +1,7 @@
#define FASTLED_INTERNAL
#include "FastLED.h"
+#if 0
#if defined(FASTLED_AVR) && !defined(TEENSYDUINO) && !defined(LIB8_ATTINY)
extern "C" {
@@ -230,3 +231,6 @@ void init()
}
};
#endif
+
+#endif
+