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--FastLED.cpp52
-rw-r--r--FastLED.h18
-rw-r--r--PORTING.md13
-rw-r--r--bitswap.cpp32
-rw-r--r--chipsets.h10
-rw-r--r--color.h106
-rw-r--r--colorpalettes.cpp18
-rw-r--r--controller.h42
-rw-r--r--fastled_delay.h5
-rw-r--r--fastpin.h27
-rw-r--r--fastspi_bitbang.h1
-rw-r--r--fastspi_ref.h1
-rw-r--r--fastspi_types.h6
-rw-r--r--lib8tion.h42
-rw-r--r--lib8tion/math8.h265
-rw-r--r--lib8tion/scale8.h425
-rw-r--r--lib8tion/trig8.h32
-rw-r--r--noise.cpp569
-rw-r--r--pixelset.h509
-rw-r--r--pixeltypes.h38
-rw-r--r--platforms/apollo3/clockless_apollo3.h107
-rw-r--r--platforms/apollo3/fastpin_apollo3.h33
-rw-r--r--platforms/arm/common/m0clockless.h608
-rw-r--r--platforms/arm/d21/clockless_arm_d21.h82
-rw-r--r--platforms/arm/d21/fastpin_arm_d21.h56
-rw-r--r--platforms/arm/d51/clockless_arm_d51.h14
-rw-r--r--platforms/arm/d51/fastpin_arm_d51.h57
-rw-r--r--platforms/arm/k20/clockless_arm_k20.h14
-rw-r--r--platforms/arm/k20/clockless_block_arm_k20.h2
-rw-r--r--platforms/arm/k20/fastspi_arm_k20.h10
-rw-r--r--platforms/arm/k20/octows2811_controller.h82
-rw-r--r--platforms/arm/k20/smartmatrix_t3.h63
-rw-r--r--platforms/arm/k20/ws2812serial_controller.h47
-rw-r--r--platforms/arm/k66/clockless_arm_k66.h14
-rw-r--r--platforms/arm/k66/clockless_block_arm_k66.h23
-rw-r--r--platforms/arm/k66/fastspi_arm_k66.h10
-rw-r--r--platforms/arm/mxrt1062/block_clockless_arm_mxrt1062.h338
-rw-r--r--platforms/arm/mxrt1062/clockless_arm_mxrt1062.h27
-rw-r--r--platforms/arm/mxrt1062/fastpin_arm_mxrt1062.h2
-rw-r--r--platforms/arm/mxrt1062/fastspi_arm_mxrt1062.h90
-rw-r--r--platforms/arm/nrf51/clockless_arm_nrf51.h101
-rw-r--r--platforms/arm/nrf51/fastpin_arm_nrf51.h88
-rw-r--r--platforms/arm/nrf51/fastspi_arm_nrf51.h247
-rw-r--r--platforms/arm/nrf52/arbiter_nrf52.h1
-rw-r--r--platforms/arm/nrf52/clockless_arm_nrf52.h1
-rw-r--r--platforms/arm/nrf52/fastpin_arm_nrf52.h94
-rw-r--r--platforms/arm/nrf52/fastspi_arm_nrf52.h1
-rw-r--r--platforms/arm/sam/clockless_arm_sam.h20
-rw-r--r--platforms/arm/sam/clockless_block_arm_sam.h237
-rw-r--r--platforms/arm/sam/fastpin_arm_sam.h1
-rw-r--r--platforms/arm/stm32/clockless_arm_stm32.h198
-rw-r--r--platforms/arm/stm32/cm3_regs.h62
-rw-r--r--platforms/arm/stm32/fastpin_arm_stm32.h76
-rw-r--r--platforms/arm/stm32/led_sysdefs_arm_stm32.h24
-rw-r--r--platforms/avr/clockless_trinket.h2
-rw-r--r--platforms/avr/fastspi_avr.h13
-rw-r--r--platforms/esp/32/clockless_block_esp32.h1
-rw-r--r--platforms/esp/32/clockless_esp32.h.orig786
-rw-r--r--platforms/esp/32/clockless_i2s_esp32.h22
-rw-r--r--platforms/esp/32/clockless_rmt_esp32.h2
-rw-r--r--platforms/esp/32/fastpin_esp32.h1
-rw-r--r--platforms/esp/8266/clockless_block_esp8266.h43
-rw-r--r--platforms/esp/8266/clockless_esp8266.h62
-rw-r--r--platforms/esp/8266/fastpin_esp8266.h45
-rw-r--r--power_mgt.cpp12
-rw-r--r--wiring.cpp220
66 files changed, 2733 insertions, 3517 deletions
diff --git a/FastLED.cpp b/FastLED.cpp
index bfcb73c4..b070e808 100644
--- a/FastLED.cpp
+++ b/FastLED.cpp
@@ -31,8 +31,8 @@ CFastLED::CFastLED() {
}
CLEDController &CFastLED::addLeds(CLEDController *pLed,
- struct CRGB *data,
- int nLedsOrOffset, int nLedsIfOffset) {
+ struct CRGB *data,
+ int nLedsOrOffset, int nLedsIfOffset) {
int nOffset = (nLedsIfOffset > 0) ? nLedsOrOffset : 0;
int nLeds = (nLedsIfOffset > 0) ? nLedsIfOffset : nLedsOrOffset;
@@ -204,33 +204,33 @@ extern int noise_min;
extern int noise_max;
void CFastLED::countFPS(int nFrames) {
- static int br = 0;
- static uint32_t lastframe = 0; // millis();
-
- if(br++ >= nFrames) {
- uint32_t now = millis();
- now -= lastframe;
- if( now == 0 ) {
- now = 1; // prevent division by zero below
- }
- m_nFPS = (br * 1000) / now;
- br = 0;
- lastframe = millis();
- }
+ static int br = 0;
+ static uint32_t lastframe = 0; // millis();
+
+ if(br++ >= nFrames) {
+ uint32_t now = millis();
+ now -= lastframe;
+ if(now == 0) {
+ now = 1; // prevent division by zero below
+ }
+ m_nFPS = (br * 1000) / now;
+ br = 0;
+ lastframe = millis();
+ }
}
void CFastLED::setMaxRefreshRate(uint16_t refresh, bool constrain) {
- if(constrain) {
- // if we're constraining, the new value of m_nMinMicros _must_ be higher than previously (because we're only
- // allowed to slow things down if constraining)
- if(refresh > 0) {
- m_nMinMicros = ( (1000000/refresh) > m_nMinMicros) ? (1000000/refresh) : m_nMinMicros;
- }
- } else if(refresh > 0) {
- m_nMinMicros = 1000000 / refresh;
- } else {
- m_nMinMicros = 0;
- }
+ if(constrain) {
+ // if we're constraining, the new value of m_nMinMicros _must_ be higher than previously (because we're only
+ // allowed to slow things down if constraining)
+ if(refresh > 0) {
+ m_nMinMicros = ((1000000 / refresh) > m_nMinMicros) ? (1000000 / refresh) : m_nMinMicros;
+ }
+ } else if(refresh > 0) {
+ m_nMinMicros = 1000000 / refresh;
+ } else {
+ m_nMinMicros = 0;
+ }
}
extern "C" int atexit(void (* /*func*/ )()) { return 0; }
diff --git a/FastLED.h b/FastLED.h
index d7b6375a..0cc1acc4 100644
--- a/FastLED.h
+++ b/FastLED.h
@@ -316,11 +316,11 @@ public:
}
#if defined(__FASTLED_HAS_FIBCC) && (__FASTLED_HAS_FIBCC == 1)
- template<uint8_t NUM_LANES, template<uint8_t DATA_PIN, EOrder RGB_ORDER> class CHIPSET, uint8_t DATA_PIN, EOrder RGB_ORDER=RGB>
- static CLEDController &addLeds(struct CRGB *data, int nLeds) {
- static __FIBCC<CHIPSET, DATA_PIN, NUM_LANES, RGB_ORDER> c;
- return addLeds(&c, data, nLeds);
- }
+ template<uint8_t NUM_LANES, template<uint8_t DATA_PIN, EOrder RGB_ORDER> class CHIPSET, uint8_t DATA_PIN, EOrder RGB_ORDER=RGB>
+ static CLEDController &addLeds(struct CRGB *data, int nLeds) {
+ static __FIBCC<CHIPSET, DATA_PIN, NUM_LANES, RGB_ORDER> c;
+ return addLeds(&c, data, nLeds);
+ }
#endif
#ifdef FASTSPI_USE_DMX_SIMPLE
@@ -556,19 +556,19 @@ public:
uint16_t getFPS() { return m_nFPS; }
/// Get how many controllers have been registered
- /// @returns the number of controllers (strips) that have been added with addLeds
+ /// @returns the number of controllers (strips) that have been added with addLeds
int count();
/// Get a reference to a registered controller
- /// @returns a reference to the Nth controller
+ /// @returns a reference to the Nth controller
CLEDController & operator[](int x);
/// Get the number of leds in the first controller
- /// @returns the number of LEDs in the first controller
+ /// @returns the number of LEDs in the first controller
int size() { return (*this)[0].size(); }
/// Get a pointer to led data for the first controller
- /// @returns pointer to the CRGB buffer for the first controller
+ /// @returns pointer to the CRGB buffer for the first controller
CRGB *leds() { return (*this)[0].leds(); }
};
diff --git a/PORTING.md b/PORTING.md
index 2f925ab2..beb4e6c6 100644
--- a/PORTING.md
+++ b/PORTING.md
@@ -1,6 +1,7 @@
-=New platform porting guide=
+New platform porting guide
+==========================
-== Fast porting for a new board on existing hardware ==
+# Fast porting for a new board on existing hardware
Sometimes "porting" FastLED simply consists of supplying new pin definitions for the given platform. For example, platforms/avr/fastpin_avr.h contains various pin definitions for all the AVR variant chipsets/boards that FastLED supports. Defining a set of pins involves setting up a set of definitions - for example here's one full set from the avr fastpin file:
@@ -26,7 +27,7 @@ The ```_FL_IO``` macro is used to define the port registers for the platform whi
The ```HAS_HARDWARE_PIN_SUPPORT``` define tells the rest of the FastLED library that there is hardware pin support available. There may be other platform specific defines for things like hardware SPI ports and such.
-== Setting up the basic files/folders ==
+## Setting up the basic files/folders
* Create platform directory (e.g. platforms/arm/kl26)
* Create configuration header led_sysdefs_arm_kl26.h:
@@ -38,7 +39,7 @@ The ```HAS_HARDWARE_PIN_SUPPORT``` define tells the rest of the FastLED library
* Modify led_sysdefs.h to conditionally include platform sysdefs header file
* Modify platforms.h to conditionally include platform fastled header
-== Porting fastpin.h ==
+## Porting fastpin.h
The heart of the FastLED library is the fast pin accesss. This is a templated class that provides 1-2 cycle pin access, bypassing digital write and other such things. As such, this will usually be the first bit of the library that you will want to port when moving to a new platform. Once you have FastPIN up and running then you can do some basic work like testing toggles or running bit-bang'd SPI output.
@@ -46,10 +47,10 @@ There's two low level FastPin classes. There's the base FastPIN template class,
Explaining how the macros work and should be used is currently beyond the scope of this document.
-== Porting fastspi.h ==
+## Porting fastspi.h
This is where you define the low level interface to the hardware SPI system (including a writePixels method that does a bunch of housekeeping for writing led data). Use the fastspi_nop.h file as a reference for the methods that need to be implemented. There are ofteh other useful methods that can help with the internals of the SPI code, I recommend taking a look at how the various platforms implement their SPI classes.
-== Porting clockless.h ==
+## Porting clockless.h
This is where you define the code for the clockless controllers. Across ARM platforms this will usually be fairly similar - though different arm platforms will have different clock sources that you can/should use.
diff --git a/bitswap.cpp b/bitswap.cpp
index 67530c72..5be71f02 100644
--- a/bitswap.cpp
+++ b/bitswap.cpp
@@ -4,25 +4,25 @@
/// Simplified form of bits rotating function. Based on code found here - http://www.hackersdelight.org/hdcodetxt/transpose8.c.txt - rotating
/// data into LSB for a faster write (the code using this data can happily walk the array backwards)
void transpose8x1_noinline(unsigned char *A, unsigned char *B) {
- uint32_t x, y, t;
+ uint32_t x, y, t;
- // Load the array and pack it into x and y.
- y = *(unsigned int*)(A);
- x = *(unsigned int*)(A+4);
+ // Load the array and pack it into x and y.
+ y = *(unsigned int*)(A);
+ x = *(unsigned int*)(A+4);
- // pre-transform x
- t = (x ^ (x >> 7)) & 0x00AA00AA; x = x ^ t ^ (t << 7);
- t = (x ^ (x >>14)) & 0x0000CCCC; x = x ^ t ^ (t <<14);
+ // pre-transform x
+ t = (x ^ (x >> 7)) & 0x00AA00AA; x = x ^ t ^ (t << 7);
+ t = (x ^ (x >>14)) & 0x0000CCCC; x = x ^ t ^ (t <<14);
- // pre-transform y
- t = (y ^ (y >> 7)) & 0x00AA00AA; y = y ^ t ^ (t << 7);
- t = (y ^ (y >>14)) & 0x0000CCCC; y = y ^ t ^ (t <<14);
+ // pre-transform y
+ t = (y ^ (y >> 7)) & 0x00AA00AA; y = y ^ t ^ (t << 7);
+ t = (y ^ (y >>14)) & 0x0000CCCC; y = y ^ t ^ (t <<14);
- // final transform
- t = (x & 0xF0F0F0F0) | ((y >> 4) & 0x0F0F0F0F);
- y = ((x << 4) & 0xF0F0F0F0) | (y & 0x0F0F0F0F);
- x = t;
+ // final transform
+ t = (x & 0xF0F0F0F0) | ((y >> 4) & 0x0F0F0F0F);
+ y = ((x << 4) & 0xF0F0F0F0) | (y & 0x0F0F0F0F);
+ x = t;
- *((uint32_t*)B) = y;
- *((uint32_t*)(B+4)) = x;
+ *((uint32_t*)B) = y;
+ *((uint32_t*)(B+4)) = x;
}
diff --git a/chipsets.h b/chipsets.h
index 8e9051d5..ddaf3857 100644
--- a/chipsets.h
+++ b/chipsets.h
@@ -28,6 +28,7 @@ template<uint8_t DATA_PIN, EOrder RGB_ORDER = RGB>
class PixieController : public CPixelLEDController<RGB_ORDER> {
SoftwareSerial Serial;
CMinWait<2000> mWait;
+
public:
PixieController() : Serial(-1, DATA_PIN) {}
@@ -92,8 +93,8 @@ class LPD8806Controller : public CPixelLEDController<RGB_ORDER> {
};
SPI mSPI;
-public:
+public:
LPD8806Controller() {}
virtual void init() {
mSPI.init();
@@ -123,6 +124,7 @@ class WS2801Controller : public CPixelLEDController<RGB_ORDER> {
typedef SPIOutput<DATA_PIN, CLOCK_PIN, SPI_SPEED> SPI;
SPI mSPI;
CMinWait<1000> mWaitDelay;
+
public:
WS2801Controller() {}
@@ -132,7 +134,6 @@ public:
}
protected:
-
virtual void showPixels(PixelController<RGB_ORDER> & pixels) {
mWaitDelay.wait();
mSPI.template writePixels<0, DATA_NOP, RGB_ORDER>(pixels);
@@ -166,7 +167,6 @@ public:
}
protected:
-
virtual void showPixels(PixelController<RGB_ORDER> & pixels) {
mSPI.select();
@@ -232,7 +232,6 @@ public:
}
protected:
-
virtual void showPixels(PixelController<RGB_ORDER> & pixels) {
mSPI.select();
@@ -297,7 +296,6 @@ public:
}
protected:
-
virtual void showPixels(PixelController<RGB_ORDER> & pixels) {
mSPI.select();
@@ -360,7 +358,6 @@ public:
}
protected:
-
virtual void showPixels(PixelController<RGB_ORDER> & pixels) {
mSPI.select();
@@ -418,7 +415,6 @@ public:
}
protected:
-
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
diff --git a/color.h b/color.h
index 1ed60b4d..63687cb5 100644
--- a/color.h
+++ b/color.h
@@ -11,71 +11,71 @@ FASTLED_NAMESPACE_BEGIN
/// definitions for color correction and light temperatures
///@{
typedef enum {
- // Color correction starting points
+ // Color correction starting points
- /// typical values for SMD5050 LEDs
- ///@{
+ /// typical values for SMD5050 LEDs
+ ///@{
TypicalSMD5050=0xFFB0F0 /* 255, 176, 240 */,
TypicalLEDStrip=0xFFB0F0 /* 255, 176, 240 */,
- ///@}
+ ///@}
- /// typical values for 8mm "pixels on a string"
- /// also for many through-hole 'T' package LEDs
- ///@{
- Typical8mmPixel=0xFFE08C /* 255, 224, 140 */,
- TypicalPixelString=0xFFE08C /* 255, 224, 140 */,
- ///@}
+ /// typical values for 8mm "pixels on a string"
+ /// also for many through-hole 'T' package LEDs
+ ///@{
+ Typical8mmPixel=0xFFE08C /* 255, 224, 140 */,
+ TypicalPixelString=0xFFE08C /* 255, 224, 140 */,
+ ///@}
- /// uncorrected color
- UncorrectedColor=0xFFFFFF
+ /// uncorrected color
+ UncorrectedColor=0xFFFFFF
} LEDColorCorrection;
typedef enum {
- /// @name Black-body radiation light sources
- /// Black-body radiation light sources emit a (relatively) continuous
- /// spectrum, and can be described as having a Kelvin 'temperature'
- ///@{
- /// 1900 Kelvin
- Candle=0xFF9329 /* 1900 K, 255, 147, 41 */,
- /// 2600 Kelvin
- Tungsten40W=0xFFC58F /* 2600 K, 255, 197, 143 */,
- /// 2850 Kelvin
- Tungsten100W=0xFFD6AA /* 2850 K, 255, 214, 170 */,
- /// 3200 Kelvin
- Halogen=0xFFF1E0 /* 3200 K, 255, 241, 224 */,
- /// 5200 Kelvin
- CarbonArc=0xFFFAF4 /* 5200 K, 255, 250, 244 */,
- /// 5400 Kelvin
- HighNoonSun=0xFFFFFB /* 5400 K, 255, 255, 251 */,
- /// 6000 Kelvin
- DirectSunlight=0xFFFFFF /* 6000 K, 255, 255, 255 */,
- /// 7000 Kelvin
- OvercastSky=0xC9E2FF /* 7000 K, 201, 226, 255 */,
- /// 20000 Kelvin
- ClearBlueSky=0x409CFF /* 20000 K, 64, 156, 255 */,
- ///@}
+ /// @name Black-body radiation light sources
+ /// Black-body radiation light sources emit a (relatively) continuous
+ /// spectrum, and can be described as having a Kelvin 'temperature'
+ ///@{
+ /// 1900 Kelvin
+ Candle=0xFF9329 /* 1900 K, 255, 147, 41 */,
+ /// 2600 Kelvin
+ Tungsten40W=0xFFC58F /* 2600 K, 255, 197, 143 */,
+ /// 2850 Kelvin
+ Tungsten100W=0xFFD6AA /* 2850 K, 255, 214, 170 */,
+ /// 3200 Kelvin
+ Halogen=0xFFF1E0 /* 3200 K, 255, 241, 224 */,
+ /// 5200 Kelvin
+ CarbonArc=0xFFFAF4 /* 5200 K, 255, 250, 244 */,
+ /// 5400 Kelvin
+ HighNoonSun=0xFFFFFB /* 5400 K, 255, 255, 251 */,
+ /// 6000 Kelvin
+ DirectSunlight=0xFFFFFF /* 6000 K, 255, 255, 255 */,
+ /// 7000 Kelvin
+ OvercastSky=0xC9E2FF /* 7000 K, 201, 226, 255 */,
+ /// 20000 Kelvin
+ ClearBlueSky=0x409CFF /* 20000 K, 64, 156, 255 */,
+ ///@}
- /// @name Gaseous light sources
- /// Gaseous light sources emit discrete spectral bands, and while we can
- /// approximate their aggregate hue with RGB values, they don't actually
- /// have a proper Kelvin temperature.
- ///@{
- WarmFluorescent=0xFFF4E5 /* 0 K, 255, 244, 229 */,
- StandardFluorescent=0xF4FFFA /* 0 K, 244, 255, 250 */,
- CoolWhiteFluorescent=0xD4EBFF /* 0 K, 212, 235, 255 */,
- FullSpectrumFluorescent=0xFFF4F2 /* 0 K, 255, 244, 242 */,
- GrowLightFluorescent=0xFFEFF7 /* 0 K, 255, 239, 247 */,
- BlackLightFluorescent=0xA700FF /* 0 K, 167, 0, 255 */,
- MercuryVapor=0xD8F7FF /* 0 K, 216, 247, 255 */,
- SodiumVapor=0xFFD1B2 /* 0 K, 255, 209, 178 */,
- MetalHalide=0xF2FCFF /* 0 K, 242, 252, 255 */,
- HighPressureSodium=0xFFB74C /* 0 K, 255, 183, 76 */,
- ///@}
+ /// @name Gaseous light sources
+ /// Gaseous light sources emit discrete spectral bands, and while we can
+ /// approximate their aggregate hue with RGB values, they don't actually
+ /// have a proper Kelvin temperature.
+ ///@{
+ WarmFluorescent=0xFFF4E5 /* 0 K, 255, 244, 229 */,
+ StandardFluorescent=0xF4FFFA /* 0 K, 244, 255, 250 */,
+ CoolWhiteFluorescent=0xD4EBFF /* 0 K, 212, 235, 255 */,
+ FullSpectrumFluorescent=0xFFF4F2 /* 0 K, 255, 244, 242 */,
+ GrowLightFluorescent=0xFFEFF7 /* 0 K, 255, 239, 247 */,
+ BlackLightFluorescent=0xA700FF /* 0 K, 167, 0, 255 */,
+ MercuryVapor=0xD8F7FF /* 0 K, 216, 247, 255 */,
+ SodiumVapor=0xFFD1B2 /* 0 K, 255, 209, 178 */,
+ MetalHalide=0xF2FCFF /* 0 K, 242, 252, 255 */,
+ HighPressureSodium=0xFFB74C /* 0 K, 255, 183, 76 */,
+ ///@}
- /// Uncorrected temperature 0xFFFFFF
- UncorrectedTemperature=0xFFFFFF
+ /// Uncorrected temperature 0xFFFFFF
+ UncorrectedTemperature=0xFFFFFF
} ColorTemperature;
FASTLED_NAMESPACE_END
diff --git a/colorpalettes.cpp b/colorpalettes.cpp
index 3c3a1f51..68e42f03 100644
--- a/colorpalettes.cpp
+++ b/colorpalettes.cpp
@@ -161,14 +161,14 @@ extern const TProgmemRGBPalette16 HeatColors_p FL_PROGMEM =
// you want a 'standard' FastLED rainbow as well.
DEFINE_GRADIENT_PALETTE( Rainbow_gp ) {
- 0, 255, 0, 0, // Red
- 32, 171, 85, 0, // Orange
- 64, 171,171, 0, // Yellow
- 96, 0,255, 0, // Green
- 128, 0,171, 85, // Aqua
- 160, 0, 0,255, // Blue
- 192, 85, 0,171, // Purple
- 224, 171, 0, 85, // Pink
- 255, 255, 0, 0};// and back to Red
+ 0, 255, 0, 0, // Red
+ 32, 171, 85, 0, // Orange
+ 64, 171, 171, 0, // Yellow
+ 96, 0, 255, 0, // Green
+ 128, 0, 171, 85, // Aqua
+ 160, 0, 0, 255, // Blue
+ 192, 85, 0, 171, // Purple
+ 224, 171, 0, 85, // Pink
+ 255, 255, 0, 0};// and back to Red
#endif
diff --git a/controller.h b/controller.h
index 30e4c111..951a8a0d 100644
--- a/controller.h
+++ b/controller.h
@@ -50,7 +50,7 @@ protected:
/// 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 nLeds the number 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) = 0;
@@ -388,28 +388,28 @@ struct PixelController {
template<EOrder RGB_ORDER, int LANES=1, uint32_t MASK=0xFFFFFFFF> class CPixelLEDController : public CLEDController {
protected:
- 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, LANES, MASK> 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, LANES, MASK> pixels(data, nLeds, scale, getDither());
- showPixels(pixels);
- }
+ 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, LANES, MASK> 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, LANES, MASK> pixels(data, nLeds, scale, getDither());
+ showPixels(pixels);
+ }
public:
- CPixelLEDController() : CLEDController() {}
+ CPixelLEDController() : CLEDController() {}
};
diff --git a/fastled_delay.h b/fastled_delay.h
index 4649f7d0..a14e8a29 100644
--- a/fastled_delay.h
+++ b/fastled_delay.h
@@ -12,6 +12,7 @@ FASTLED_NAMESPACE_BEGIN
/// this should make sure that chipsets that have
template<int WAIT> class CMinWait {
uint16_t mLastMicros;
+
public:
CMinWait() { mLastMicros = 0; }
@@ -51,8 +52,8 @@ public:
// predeclaration to not upset the compiler
template<int CYCLES> inline void delaycycles();
template<int CYCLES> inline void delaycycles_min1() {
- delaycycles<1>();
- delaycycles<CYCLES-1>();
+ delaycycles<1>();
+ delaycycles<CYCLES-1>();
}
diff --git a/fastpin.h b/fastpin.h
index ed2b8e7e..085a7d1b 100644
--- a/fastpin.h
+++ b/fastpin.h
@@ -42,6 +42,7 @@ class Pin : public Selectable {
mPort = (volatile RwReg*)portOutputRegister(digitalPinToPort(mPin));
mInPort = (volatile RoReg*)portInputRegister(digitalPinToPort(mPin));
}
+
public:
Pin(int pin) : mPin(pin) { _init(); }
@@ -98,6 +99,7 @@ class Pin : public Selectable {
mPort = NULL;
mInPort = NULL;
}
+
public:
Pin(int pin) : mPin(pin) { _init(); }
@@ -169,6 +171,7 @@ template<uint8_t PIN> class FastPin {
sInPort = portInputRegister(digitalPinToPort(PIN));
#endif
}
+
public:
typedef volatile RwReg * port_ptr_t;
typedef RwReg port_t;
@@ -206,8 +209,8 @@ template<uint8_t PIN> class FastPin {
static_assert(validpin(), "Invalid pin specified");
- static void _init() {
- }
+ static void _init() { }
+
public:
typedef volatile RwReg * port_ptr_t;
typedef RwReg port_t;
@@ -253,15 +256,17 @@ template<uint8_t port> struct __FL_PORT_INFO {
// are numeric in nature, e.g. GPIO0, GPIO1. Use _FL_DEFINE_PORT3 for ports that are letters.
// The first parameter will be the letter, the second parameter will be an integer/counter of smoe kind
// (this is because attempts to turn macro parameters into character constants break in some compilers)
-#define _FL_DEFINE_PORT(L, BASE) template<> struct __FL_PORT_INFO<L> { static bool hasPort() { return 1; } \
- static const char *portName() { return #L; } \
- typedef BASE __t_baseType; \
- static const void *portAddr() { return (void*)&__t_baseType::r(); } };
-
-#define _FL_DEFINE_PORT3(L, LC, BASE) template<> struct __FL_PORT_INFO<LC> { static bool hasPort() { return 1; } \
- static const char *portName() { return #L; } \
- typedef BASE __t_baseType; \
- static const void *portAddr() { return (void*)&__t_baseType::r(); } };
+#define _FL_DEFINE_PORT(L, BASE) template<> struct __FL_PORT_INFO<L> { \
+ static bool hasPort() { return 1; } \
+ static const char *portName() { return #L; } \
+ typedef BASE __t_baseType; \
+ static const void *portAddr() { return (void*)&__t_baseType::r(); } };
+
+#define _FL_DEFINE_PORT3(L, LC, BASE) template<> struct __FL_PORT_INFO<LC> { \
+ static bool hasPort() { return 1; } \
+ static const char *portName() { return #L; } \
+ typedef BASE __t_baseType; \
+ static const void *portAddr() { return (void*)&__t_baseType::r(); } };
FASTLED_NAMESPACE_END
diff --git a/fastspi_bitbang.h b/fastspi_bitbang.h
index 019b6dc0..86663f17 100644
--- a/fastspi_bitbang.h
+++ b/fastspi_bitbang.h
@@ -203,6 +203,7 @@ private:
}
#endif
}
+
public:
// select the SPI output (TODO: research whether this really means hi or lo. Alt TODO: move select responsibility out of the SPI classes
diff --git a/fastspi_ref.h b/fastspi_ref.h
index 00c41d34..a12a962a 100644
--- a/fastspi_ref.h
+++ b/fastspi_ref.h
@@ -11,6 +11,7 @@ FASTLED_NAMESPACE_BEGIN
template <uint8_t _DATA_PIN, uint8_t _CLOCK_PIN, uint32_t _SPI_CLOCK_DIVIDER>
class REFHardwareSPIOutput {
Selectable *m_pSelect;
+
public:
SAMHardwareSPIOutput() { m_pSelect = NULL; }
SAMHArdwareSPIOutput(Selectable *pSelect) { m_pSelect = pSelect; }
diff --git a/fastspi_types.h b/fastspi_types.h
index 5510bba8..ea7d46ce 100644
--- a/fastspi_types.h
+++ b/fastspi_types.h
@@ -19,9 +19,9 @@ FASTLED_NAMESPACE_BEGIN
/// TODO: Convinience macro for building these
class DATA_NOP {
public:
- static __attribute__((always_inline)) inline uint8_t adjust(register uint8_t data) { return data; }
- static __attribute__((always_inline)) inline uint8_t adjust(register uint8_t data, register uint8_t scale) { return scale8(data, scale); }
- static __attribute__((always_inline)) inline void postBlock(int /* len */) { }
+ static __attribute__((always_inline)) inline uint8_t adjust(register uint8_t data) { return data; }
+ static __attribute__((always_inline)) inline uint8_t adjust(register uint8_t data, register uint8_t scale) { return scale8(data, scale); }
+ static __attribute__((always_inline)) inline void postBlock(int /* len */) { }
};
#define FLAG_START_BIT 0x80
diff --git a/lib8tion.h b/lib8tion.h
index 62db2b1d..0cc3baa4 100644
--- a/lib8tion.h
+++ b/lib8tion.h
@@ -825,20 +825,20 @@ LIB8STATIC uint8_t squarewave8( uint8_t in, uint8_t pulsewidth=128)
/// Template class for represneting fractional ints.
template<class T, int F, int I> class q {
- T i:I;
- T f:F;
+ T i:I;
+ T f:F;
public:
- q(float fx) { i = fx; f = (fx-i) * (1<<F); }
- q(uint8_t _i, uint8_t _f) {i=_i; f=_f; }
- uint32_t operator*(uint32_t v) { return (v*i) + ((v*f)>>F); }
- uint16_t operator*(uint16_t v) { return (v*i) + ((v*f)>>F); }
- int32_t operator*(int32_t v) { return (v*i) + ((v*f)>>F); }
- int16_t operator*(int16_t v) { return (v*i) + ((v*f)>>F); }
+ q(float fx) { i = fx; f = (fx-i) * (1<<F); }
+ q(uint8_t _i, uint8_t _f) {i=_i; f=_f; }
+ uint32_t operator*(uint32_t v) { return (v*i) + ((v*f)>>F); }
+ uint16_t operator*(uint16_t v) { return (v*i) + ((v*f)>>F); }
+ int32_t operator*(int32_t v) { return (v*i) + ((v*f)>>F); }
+ int16_t operator*(int16_t v) { return (v*i) + ((v*f)>>F); }
#ifdef FASTLED_ARM
- int operator*(int v) { return (v*i) + ((v*f)>>F); }
+ int operator*(int v) { return (v*i) + ((v*f)>>F); }
#endif
#ifdef FASTLED_APOLLO3
- int operator*(int v) { return (v*i) + ((v*f)>>F); }
+ int operator*(int v) { return (v*i) + ((v*f)>>F); }
#endif
};
@@ -1048,17 +1048,17 @@ LIB8STATIC uint16_t div1024_32_16( uint32_t in32)
uint16_t out16;
#if defined(__AVR__)
asm volatile (
- " lsr %D[in] \n\t"
- " ror %C[in] \n\t"
- " ror %B[in] \n\t"
- " lsr %D[in] \n\t"
- " ror %C[in] \n\t"
- " ror %B[in] \n\t"
- " mov %B[out],%C[in] \n\t"
- " mov %A[out],%B[in] \n\t"
- : [in] "+r" (in32),
- [out] "=r" (out16)
- );
+ " lsr %D[in] \n\t"
+ " ror %C[in] \n\t"
+ " ror %B[in] \n\t"
+ " lsr %D[in] \n\t"
+ " ror %C[in] \n\t"
+ " ror %B[in] \n\t"
+ " mov %B[out],%C[in] \n\t"
+ " mov %A[out],%B[in] \n\t"
+ : [in] "+r" (in32),
+ [out] "=r" (out16)
+ );
#else
out16 = (in32 >> 10) & 0xFFFF;
#endif
diff --git a/lib8tion/math8.h b/lib8tion/math8.h
index 4dab820f..a83b1ad2 100644
--- a/lib8tion/math8.h
+++ b/lib8tion/math8.h
@@ -28,18 +28,19 @@ LIB8STATIC_ALWAYS_INLINE uint8_t qadd8( uint8_t i, uint8_t j)
return t;
#elif QADD8_AVRASM == 1
asm volatile(
- /* First, add j to i, conditioning the C flag */
- "add %0, %1 \n\t"
-
- /* Now test the C flag.
- If C is clear, we branch around a load of 0xFF into i.
- If C is set, we go ahead and load 0xFF into i.
- */
- "brcc L_%= \n\t"
- "ldi %0, 0xFF \n\t"
- "L_%=: "
- : "+a" (i)
- : "a" (j) );
+ /* First, add j to i, conditioning the C flag */
+ "add %0, %1 \n\t"
+
+ /* Now test the C flag.
+ If C is clear, we branch around a load of 0xFF into i.
+ If C is set, we go ahead and load 0xFF into i.
+ */
+ "brcc L_%= \n\t"
+ "ldi %0, 0xFF \n\t"
+ "L_%=: "
+ : "+a" (i)
+ : "a" (j)
+ );
return i;
#elif QADD8_ARM_DSP_ASM == 1
asm volatile( "uqadd8 %0, %0, %1" : "+r" (i) : "r" (j));
@@ -61,19 +62,19 @@ LIB8STATIC_ALWAYS_INLINE int8_t qadd7( int8_t i, int8_t j)
return t;
#elif QADD7_AVRASM == 1
asm volatile(
- /* First, add j to i, conditioning the V flag */
- "add %0, %1 \n\t"
-
- /* Now test the V flag.
- If V is clear, we branch around a load of 0x7F into i.
- If V is set, we go ahead and load 0x7F into i.
- */
- "brvc L_%= \n\t"
- "ldi %0, 0x7F \n\t"
- "L_%=: "
- : "+a" (i)
- : "a" (j) );
-
+ /* First, add j to i, conditioning the V flag */
+ "add %0, %1 \n\t"
+
+ /* Now test the V flag.
+ If V is clear, we branch around a load of 0x7F into i.
+ If V is set, we go ahead and load 0x7F into i.
+ */
+ "brvc L_%= \n\t"
+ "ldi %0, 0x7F \n\t"
+ "L_%=: "
+ : "+a" (i)
+ : "a" (j)
+ );
return i;
#elif QADD7_ARM_DSP_ASM == 1
asm volatile( "qadd8 %0, %0, %1" : "+r" (i) : "r" (j));
@@ -94,19 +95,19 @@ LIB8STATIC_ALWAYS_INLINE uint8_t qsub8( uint8_t i, uint8_t j)
#elif QSUB8_AVRASM == 1
asm volatile(
- /* First, subtract j from i, conditioning the C flag */
- "sub %0, %1 \n\t"
-
- /* Now test the C flag.
- If C is clear, we branch around a load of 0x00 into i.
- If C is set, we go ahead and load 0x00 into i.
- */
- "brcc L_%= \n\t"
- "ldi %0, 0x00 \n\t"
- "L_%=: "
- : "+a" (i)
- : "a" (j) );
-
+ /* First, subtract j from i, conditioning the C flag */
+ "sub %0, %1 \n\t"
+
+ /* Now test the C flag.
+ If C is clear, we branch around a load of 0x00 into i.
+ If C is set, we go ahead and load 0x00 into i.
+ */
+ "brcc L_%= \n\t"
+ "ldi %0, 0x00 \n\t"
+ "L_%=: "
+ : "+a" (i)
+ : "a" (j)
+ );
return i;
#else
#error "No implementation for qsub8 available."
@@ -136,11 +137,12 @@ LIB8STATIC_ALWAYS_INLINE uint16_t add8to16( uint8_t i, uint16_t j)
return t;
#elif ADD8_AVRASM == 1
// Add i(one byte) to j(two bytes)
- asm volatile( "add %A[j], %[i] \n\t"
- "adc %B[j], __zero_reg__ \n\t"
- : [j] "+a" (j)
- : [i] "a" (i)
- );
+ asm volatile(
+ "add %A[j], %[i] \n\t"
+ "adc %B[j], __zero_reg__ \n\t"
+ : [j] "+a" (j)
+ : [i] "a" (i)
+ );
return i;
#else
#error "No implementation for add8to16 available."
@@ -172,12 +174,13 @@ LIB8STATIC_ALWAYS_INLINE uint8_t avg8( uint8_t i, uint8_t j)
return (i + j) >> 1;
#elif AVG8_AVRASM == 1
asm volatile(
- /* First, add j to i, 9th bit overflows into C flag */
- "add %0, %1 \n\t"
- /* Divide by two, moving C flag into high 8th bit */
- "ror %0 \n\t"
- : "+a" (i)
- : "a" (j) );
+ /* First, add j to i, 9th bit overflows into C flag */
+ "add %0, %1 \n\t"
+ /* Divide by two, moving C flag into high 8th bit */
+ "ror %0 \n\t"
+ : "+a" (i)
+ : "a" (j)
+ );
return i;
#else
#error "No implementation for avg8 available."
@@ -193,16 +196,17 @@ LIB8STATIC_ALWAYS_INLINE uint16_t avg16( uint16_t i, uint16_t j)
return (uint32_t)((uint32_t)(i) + (uint32_t)(j)) >> 1;
#elif AVG16_AVRASM == 1
asm volatile(
- /* First, add jLo (heh) to iLo, 9th bit overflows into C flag */
- "add %A[i], %A[j] \n\t"
- /* Now, add C + jHi to iHi, 17th bit overflows into C flag */
- "adc %B[i], %B[j] \n\t"
- /* Divide iHi by two, moving C flag into high 16th bit, old 9th bit now in C */
- "ror %B[i] \n\t"
- /* Divide iLo by two, moving C flag into high 8th bit */
- "ror %A[i] \n\t"
- : [i] "+a" (i)
- : [j] "a" (j) );
+ /* First, add jLo (heh) to iLo, 9th bit overflows into C flag */
+ "add %A[i], %A[j] \n\t"
+ /* Now, add C + jHi to iHi, 17th bit overflows into C flag */
+ "adc %B[i], %B[j] \n\t"
+ /* Divide iHi by two, moving C flag into high 16th bit, old 9th bit now in C */
+ "ror %B[i] \n\t"
+ /* Divide iLo by two, moving C flag into high 8th bit */
+ "ror %A[i] \n\t"
+ : [i] "+a" (i)
+ : [j] "a" (j)
+ );
return i;
#else
#error "No implementation for avg16 available."
@@ -220,11 +224,12 @@ LIB8STATIC_ALWAYS_INLINE int8_t avg7( int8_t i, int8_t j)
return ((i + j) >> 1) + (i & 0x1);
#elif AVG7_AVRASM == 1
asm volatile(
- "asr %1 \n\t"
- "asr %0 \n\t"
- "adc %0, %1 \n\t"
- : "+a" (i)
- : "a" (j) );
+ "asr %1 \n\t"
+ "asr %0 \n\t"
+ "adc %0, %1 \n\t"
+ : "+a" (i)
+ : "a" (j)
+ );
return i;
#else
#error "No implementation for avg7 available."
@@ -241,17 +246,18 @@ LIB8STATIC_ALWAYS_INLINE int16_t avg15( int16_t i, int16_t j)
return ((int32_t)((int32_t)(i) + (int32_t)(j)) >> 1) + (i & 0x1);
#elif AVG15_AVRASM == 1
asm volatile(
- /* first divide j by 2, throwing away lowest bit */
- "asr %B[j] \n\t"
- "ror %A[j] \n\t"
- /* now divide i by 2, with lowest bit going into C */
- "asr %B[i] \n\t"
- "ror %A[i] \n\t"
- /* add j + C to i */
- "adc %A[i], %A[j] \n\t"
- "adc %B[i], %B[j] \n\t"
- : [i] "+a" (i)
- : [j] "a" (j) );
+ /* first divide j by 2, throwing away lowest bit */
+ "asr %B[j] \n\t"
+ "ror %A[j] \n\t"
+ /* now divide i by 2, with lowest bit going into C */
+ "asr %B[i] \n\t"
+ "ror %A[i] \n\t"
+ /* add j + C to i */
+ "adc %A[i], %A[j] \n\t"
+ "adc %B[i], %B[j] \n\t"
+ : [i] "+a" (i)
+ : [j] "a" (j)
+ );
return i;
#else
#error "No implementation for avg15 available."
@@ -271,12 +277,12 @@ LIB8STATIC_ALWAYS_INLINE uint8_t mod8( uint8_t a, uint8_t m)
{
#if defined(__AVR__)
asm volatile (
- "L_%=: sub %[a],%[m] \n\t"
- " brcc L_%= \n\t"
- " add %[a],%[m] \n\t"
- : [a] "+r" (a)
- : [m] "r" (m)
- );
+ "L_%=: sub %[a],%[m] \n\t"
+ " brcc L_%= \n\t"
+ " add %[a],%[m] \n\t"
+ : [a] "+r" (a)
+ : [m] "r" (m)
+ );
#else
while( a >= m) a -= m;
#endif
@@ -298,13 +304,13 @@ LIB8STATIC uint8_t addmod8( uint8_t a, uint8_t b, uint8_t m)
{
#if defined(__AVR__)
asm volatile (
- " add %[a],%[b] \n\t"
- "L_%=: sub %[a],%[m] \n\t"
- " brcc L_%= \n\t"
- " add %[a],%[m] \n\t"
- : [a] "+r" (a)
- : [b] "r" (b), [m] "r" (m)
- );
+ " add %[a],%[b] \n\t"
+ "L_%=: sub %[a],%[m] \n\t"
+ " brcc L_%= \n\t"
+ " add %[a],%[m] \n\t"
+ : [a] "+r" (a)
+ : [b] "r" (b), [m] "r" (m)
+ );
#else
a += b;
while( a >= m) a -= m;
@@ -327,13 +333,13 @@ LIB8STATIC uint8_t submod8( uint8_t a, uint8_t b, uint8_t m)
{
#if defined(__AVR__)
asm volatile (
- " sub %[a],%[b] \n\t"
- "L_%=: sub %[a],%[m] \n\t"
- " brcc L_%= \n\t"
- " add %[a],%[m] \n\t"
- : [a] "+r" (a)
- : [b] "r" (b), [m] "r" (m)
- );
+ " sub %[a],%[b] \n\t"
+ "L_%=: sub %[a],%[m] \n\t"
+ " brcc L_%= \n\t"
+ " add %[a],%[m] \n\t"
+ : [a] "+r" (a)
+ : [b] "r" (b), [m] "r" (m)
+ );
#else
a -= b;
while( a >= m) a -= m;
@@ -348,16 +354,16 @@ LIB8STATIC_ALWAYS_INLINE uint8_t mul8( uint8_t i, uint8_t j)
return ((int)i * (int)(j) ) & 0xFF;
#elif MUL8_AVRASM == 1
asm volatile(
- /* Multiply 8-bit i * 8-bit j, giving 16-bit r1,r0 */
- "mul %0, %1 \n\t"
- /* Extract the LOW 8-bits (r0) */
- "mov %0, r0 \n\t"
- /* Restore r1 to "0"; it's expected to always be that */
- "clr __zero_reg__ \n\t"
- : "+a" (i)
- : "a" (j)
- : "r0", "r1");
-
+ /* Multiply 8-bit i * 8-bit j, giving 16-bit r1,r0 */
+ "mul %0, %1 \n\t"
+ /* Extract the LOW 8-bits (r0) */
+ "mov %0, r0 \n\t"
+ /* Restore r1 to "0"; it's expected to always be that */
+ "clr __zero_reg__ \n\t"
+ : "+a" (i)
+ : "a" (j)
+ : "r0", "r1"
+ );
return i;
#else
#error "No implementation for mul8 available."
@@ -375,24 +381,24 @@ LIB8STATIC_ALWAYS_INLINE uint8_t qmul8( uint8_t i, uint8_t j)
return p;
#elif QMUL8_AVRASM == 1
asm volatile(
- /* Multiply 8-bit i * 8-bit j, giving 16-bit r1,r0 */
- " mul %0, %1 \n\t"
- /* If high byte of result is zero, all is well. */
- " tst r1 \n\t"
- " breq Lnospill_%= \n\t"
- /* If high byte of result > 0, saturate low byte to 0xFF */
- " ldi %0,0xFF \n\t"
- " rjmp Ldone_%= \n\t"
- "Lnospill_%=: \n\t"
- /* Extract the LOW 8-bits (r0) */
- " mov %0, r0 \n\t"
- "Ldone_%=: \n\t"
- /* Restore r1 to "0"; it's expected to always be that */
- " clr __zero_reg__ \n\t"
- : "+a" (i)
- : "a" (j)
- : "r0", "r1");
-
+ /* Multiply 8-bit i * 8-bit j, giving 16-bit r1,r0 */
+ " mul %0, %1 \n\t"
+ /* If high byte of result is zero, all is well. */
+ " tst r1 \n\t"
+ " breq Lnospill_%= \n\t"
+ /* If high byte of result > 0, saturate low byte to 0xFF */
+ " ldi %0,0xFF \n\t"
+ " rjmp Ldone_%= \n\t"
+ "Lnospill_%=: \n\t"
+ /* Extract the LOW 8-bits (r0) */
+ " mov %0, r0 \n\t"
+ "Ldone_%=: \n\t"
+ /* Restore r1 to "0"; it's expected to always be that */
+ " clr __zero_reg__ \n\t"
+ : "+a" (i)
+ : "a" (j)
+ : "r0", "r1"
+ );
return i;
#else
#error "No implementation for qmul8 available."
@@ -407,16 +413,15 @@ LIB8STATIC_ALWAYS_INLINE int8_t abs8( int8_t i)
if( i < 0) i = -i;
return i;
#elif ABS8_AVRASM == 1
-
-
asm volatile(
- /* First, check the high bit, and prepare to skip if it's clear */
- "sbrc %0, 7 \n"
+ /* First, check the high bit, and prepare to skip if it's clear */
+ "sbrc %0, 7 \n"
- /* Negate the value */
- "neg %0 \n"
+ /* Negate the value */
+ "neg %0 \n"
- : "+r" (i) : "r" (i) );
+ : "+r" (i) : "r" (i)
+ );
return i;
#else
#error "No implementation for abs8 available."
diff --git a/lib8tion/scale8.h b/lib8tion/scale8.h
index 56392258..6324475b 100644
--- a/lib8tion/scale8.h
+++ b/lib8tion/scale8.h
@@ -55,7 +55,7 @@ LIB8STATIC_ALWAYS_INLINE uint8_t scale8( uint8_t i, fract8 scale)
: [work] "+r" (work), [cnt] "+r" (cnt)
: [scale] "r" (scale), [i] "r" (i)
:
- );
+ );
return work;
#else
asm volatile(
@@ -69,18 +69,18 @@ LIB8STATIC_ALWAYS_INLINE uint8_t scale8( uint8_t i, fract8 scale)
// walk and chew gum at the same time
"adc %0, r1 \n\t"
#else
- /* Multiply 8-bit i * 8-bit scale, giving 16-bit r1,r0 */
- "mul %0, %1 \n\t"
- /* Move the high 8-bits of the product (r1) back to i */
- "mov %0, r1 \n\t"
- /* Restore r1 to "0"; it's expected to always be that */
+ /* Multiply 8-bit i * 8-bit scale, giving 16-bit r1,r0 */
+ "mul %0, %1 \n\t"
+ /* Move the high 8-bits of the product (r1) back to i */
+ "mov %0, r1 \n\t"
+ /* Restore r1 to "0"; it's expected to always be that */
#endif
- "clr __zero_reg__ \n\t"
-
- : "+a" (i) /* writes to i */
- : "a" (scale) /* uses scale */
- : "r0", "r1" /* clobbers r0, r1 */ );
+ "clr __zero_reg__ \n\t"
+ : "+a" (i) /* writes to i */
+ : "a" (scale) /* uses scale */
+ : "r0", "r1" /* clobbers r0, r1 */
+ );
/* Return the result */
return i;
#endif
@@ -115,8 +115,8 @@ LIB8STATIC_ALWAYS_INLINE uint8_t scale8_video( uint8_t i, fract8 scale)
"L_%=: \n\t"
: [j] "+a" (j)
: [i] "a" (i), [scale] "a" (scale)
- : "r0", "r1");
-
+ : "r0", "r1"
+ );
return j;
// uint8_t nonzeroscale = (scale != 0) ? 1 : 0;
// asm volatile(
@@ -127,11 +127,9 @@ LIB8STATIC_ALWAYS_INLINE uint8_t scale8_video( uint8_t i, fract8 scale)
// " add %0, %2 \n"
// " clr __zero_reg__ \n"
// "L_%=: \n"
-
// : "+a" (i)
// : "a" (scale), "a" (nonzeroscale)
// : "r0", "r1");
-
// // Return the result
// return i;
#else
@@ -153,28 +151,27 @@ LIB8STATIC_ALWAYS_INLINE uint8_t scale8_LEAVING_R1_DIRTY( uint8_t i, fract8 scal
#endif
#elif SCALE8_AVRASM == 1
asm volatile(
- #if (FASTLED_SCALE8_FIXED==1)
- // Multiply 8-bit i * 8-bit scale, giving 16-bit r1,r0
- "mul %0, %1 \n\t"
- // Add i to r0, possibly setting the carry flag
- "add r0, %0 \n\t"
- // load the immediate 0 into i (note, this does _not_ touch any flags)
- "ldi %0, 0x00 \n\t"
- // walk and chew gum at the same time
- "adc %0, r1 \n\t"
- #else
- /* Multiply 8-bit i * 8-bit scale, giving 16-bit r1,r0 */
- "mul %0, %1 \n\t"
- /* Move the high 8-bits of the product (r1) back to i */
- "mov %0, r1 \n\t"
- #endif
- /* R1 IS LEFT DIRTY HERE; YOU MUST ZERO IT OUT YOURSELF */
- /* "clr __zero_reg__ \n\t" */
-
- : "+a" (i) /* writes to i */
- : "a" (scale) /* uses scale */
- : "r0", "r1" /* clobbers r0, r1 */ );
-
+#if (FASTLED_SCALE8_FIXED==1)
+ // Multiply 8-bit i * 8-bit scale, giving 16-bit r1,r0
+ "mul %0, %1 \n\t"
+ // Add i to r0, possibly setting the carry flag
+ "add r0, %0 \n\t"
+ // load the immediate 0 into i (note, this does _not_ touch any flags)
+ "ldi %0, 0x00 \n\t"
+ // walk and chew gum at the same time
+ "adc %0, r1 \n\t"
+#else
+ /* Multiply 8-bit i * 8-bit scale, giving 16-bit r1,r0 */
+ "mul %0, %1 \n\t"
+ /* Move the high 8-bits of the product (r1) back to i */
+ "mov %0, r1 \n\t"
+#endif
+ /* R1 IS LEFT DIRTY HERE; YOU MUST ZERO IT OUT YOURSELF */
+ /* "clr __zero_reg__ \n\t" */
+ : "+a" (i) /* writes to i */
+ : "a" (scale) /* uses scale */
+ : "r0", "r1" /* clobbers r0, r1 */
+ );
// Return the result
return i;
#else
@@ -197,27 +194,28 @@ LIB8STATIC_ALWAYS_INLINE void nscale8_LEAVING_R1_DIRTY( uint8_t& i, fract8 scale
#endif
#elif SCALE8_AVRASM == 1
asm volatile(
- #if (FASTLED_SCALE8_FIXED==1)
- // Multiply 8-bit i * 8-bit scale, giving 16-bit r1,r0
- "mul %0, %1 \n\t"
- // Add i to r0, possibly setting the carry flag
- "add r0, %0 \n\t"
- // load the immediate 0 into i (note, this does _not_ touch any flags)
- "ldi %0, 0x00 \n\t"
- // walk and chew gum at the same time
- "adc %0, r1 \n\t"
- #else
- /* Multiply 8-bit i * 8-bit scale, giving 16-bit r1,r0 */
- "mul %0, %1 \n\t"
- /* Move the high 8-bits of the product (r1) back to i */
- "mov %0, r1 \n\t"
- #endif
- /* R1 IS LEFT DIRTY HERE; YOU MUST ZERO IT OUT YOURSELF */
- /* "clr __zero_reg__ \n\t" */
-
- : "+a" (i) /* writes to i */
- : "a" (scale) /* uses scale */
- : "r0", "r1" /* clobbers r0, r1 */ );
+#if (FASTLED_SCALE8_FIXED==1)
+ // Multiply 8-bit i * 8-bit scale, giving 16-bit r1,r0
+ "mul %0, %1 \n\t"
+ // Add i to r0, possibly setting the carry flag
+ "add r0, %0 \n\t"
+ // load the immediate 0 into i (note, this does _not_ touch any flags)
+ "ldi %0, 0x00 \n\t"
+ // walk and chew gum at the same time
+ "adc %0, r1 \n\t"
+#else
+ /* Multiply 8-bit i * 8-bit scale, giving 16-bit r1,r0 */
+ "mul %0, %1 \n\t"
+ /* Move the high 8-bits of the product (r1) back to i */
+ "mov %0, r1 \n\t"
+#endif
+ /* R1 IS LEFT DIRTY HERE; YOU MUST ZERO IT OUT YOURSELF */
+ /* "clr __zero_reg__ \n\t" */
+
+ : "+a" (i) /* writes to i */
+ : "a" (scale) /* uses scale */
+ : "r0", "r1" /* clobbers r0, r1 */
+ );
#else
#error "No implementation for nscale8_LEAVING_R1_DIRTY available."
#endif
@@ -246,8 +244,8 @@ LIB8STATIC_ALWAYS_INLINE uint8_t scale8_video_LEAVING_R1_DIRTY( uint8_t i, fract
"L_%=: \n\t"
: [j] "+a" (j)
: [i] "a" (i), [scale] "a" (scale)
- : "r0", "r1");
-
+ : "r0", "r1"
+ );
return j;
// uint8_t nonzeroscale = (scale != 0) ? 1 : 0;
// asm volatile(
@@ -258,11 +256,9 @@ LIB8STATIC_ALWAYS_INLINE uint8_t scale8_video_LEAVING_R1_DIRTY( uint8_t i, fract
// " add %0, %2 \n"
// " clr __zero_reg__ \n"
// "L_%=: \n"
-
// : "+a" (i)
// : "a" (scale), "a" (nonzeroscale)
// : "r0", "r1");
-
// // Return the result
// return i;
#else
@@ -289,7 +285,8 @@ LIB8STATIC_ALWAYS_INLINE void nscale8_video_LEAVING_R1_DIRTY( uint8_t & i, fract
"L_%=: \n\t"
: [i] "+a" (i)
: [scale] "a" (scale)
- : "r0", "r1");
+ : "r0", "r1"
+ );
#else
#error "No implementation for scale8_video_LEAVING_R1_DIRTY available."
#endif
@@ -427,50 +424,50 @@ LIB8STATIC_ALWAYS_INLINE uint16_t scale16by8( uint16_t i, fract8 scale )
#if FASTLED_SCALE8_FIXED == 1
uint16_t result = 0;
asm volatile(
- // result.A = HighByte( (i.A x scale) + i.A )
- " mul %A[i], %[scale] \n\t"
- " add r0, %A[i] \n\t"
- // " adc r1, [zero] \n\t"
- // " mov %A[result], r1 \n\t"
- " adc %A[result], r1 \n\t"
-
- // result.A-B += i.B x scale
- " mul %B[i], %[scale] \n\t"
- " add %A[result], r0 \n\t"
- " adc %B[result], r1 \n\t"
-
- // cleanup r1
- " clr __zero_reg__ \n\t"
-
- // result.A-B += i.B
- " add %A[result], %B[i] \n\t"
- " adc %B[result], __zero_reg__ \n\t"
-
- : [result] "+r" (result)
- : [i] "r" (i), [scale] "r" (scale)
- : "r0", "r1"
- );
+ // result.A = HighByte( (i.A x scale) + i.A )
+ " mul %A[i], %[scale] \n\t"
+ " add r0, %A[i] \n\t"
+ // " adc r1, [zero] \n\t"
+ // " mov %A[result], r1 \n\t"
+ " adc %A[result], r1 \n\t"
+
+ // result.A-B += i.B x scale
+ " mul %B[i], %[scale] \n\t"
+ " add %A[result], r0 \n\t"
+ " adc %B[result], r1 \n\t"
+
+ // cleanup r1
+ " clr __zero_reg__ \n\t"
+
+ // result.A-B += i.B
+ " add %A[result], %B[i] \n\t"
+ " adc %B[result], __zero_reg__ \n\t"
+
+ : [result] "+r" (result)
+ : [i] "r" (i), [scale] "r" (scale)
+ : "r0", "r1"
+ );
return result;
#else
uint16_t result = 0;
asm volatile(
- // result.A = HighByte(i.A x j )
- " mul %A[i], %[scale] \n\t"
- " mov %A[result], r1 \n\t"
- //" clr %B[result] \n\t"
-
- // result.A-B += i.B x j
- " mul %B[i], %[scale] \n\t"
- " add %A[result], r0 \n\t"
- " adc %B[result], r1 \n\t"
-
- // cleanup r1
- " clr __zero_reg__ \n\t"
-
- : [result] "+r" (result)
- : [i] "r" (i), [scale] "r" (scale)
- : "r0", "r1"
- );
+ // result.A = HighByte(i.A x j )
+ " mul %A[i], %[scale] \n\t"
+ " mov %A[result], r1 \n\t"
+ //" clr %B[result] \n\t"
+
+ // result.A-B += i.B x j
+ " mul %B[i], %[scale] \n\t"
+ " add %A[result], r0 \n\t"
+ " adc %B[result], r1 \n\t"
+
+ // cleanup r1
+ " clr __zero_reg__ \n\t"
+
+ : [result] "+r" (result)
+ : [i] "r" (i), [scale] "r" (scale)
+ : "r0", "r1"
+ );
return result;
#endif
#else
@@ -503,137 +500,137 @@ LIB8STATIC uint16_t scale16( uint16_t i, fract16 scale )
// will be zero, which is not what we want.
uint32_t result;
asm volatile(
- // result.A-B = i.A x scale.A
- " mul %A[i], %A[scale] \n\t"
- // save results...
- // basic idea:
- //" mov %A[result], r0 \n\t"
- //" mov %B[result], r1 \n\t"
- // which can be written as...
- " movw %A[result], r0 \n\t"
- // Because we're going to add i.A-B to
- // result.A-D, we DO need to keep both
- // the r0 and r1 portions of the product
- // UNlike in the 'unfixed scale8' version.
- // So the movw here is needed.
- : [result] "=r" (result)
- : [i] "r" (i),
- [scale] "r" (scale)
- : "r0", "r1"
- );
-
- asm volatile(
- // result.C-D = i.B x scale.B
- " mul %B[i], %B[scale] \n\t"
- //" mov %C[result], r0 \n\t"
- //" mov %D[result], r1 \n\t"
- " movw %C[result], r0 \n\t"
- : [result] "+r" (result)
- : [i] "r" (i),
- [scale] "r" (scale)
- : "r0", "r1"
- );
+ // result.A-B = i.A x scale.A
+ " mul %A[i], %A[scale] \n\t"
+ // save results...
+ // basic idea:
+ //" mov %A[result], r0 \n\t"
+ //" mov %B[result], r1 \n\t"
+ // which can be written as...
+ " movw %A[result], r0 \n\t"
+ // Because we're going to add i.A-B to
+ // result.A-D, we DO need to keep both
+ // the r0 and r1 portions of the product
+ // UNlike in the 'unfixed scale8' version.
+ // So the movw here is needed.
+ : [result] "=r" (result)
+ : [i] "r" (i),
+ [scale] "r" (scale)
+ : "r0", "r1"
+ );
- const uint8_t zero = 0;
asm volatile(
- // result.B-D += i.B x scale.A
- " mul %B[i], %A[scale] \n\t"
-
- " add %B[result], r0 \n\t"
- " adc %C[result], r1 \n\t"
- " adc %D[result], %[zero] \n\t"
-
- // result.B-D += i.A x scale.B
- " mul %A[i], %B[scale] \n\t"
-
- " add %B[result], r0 \n\t"
- " adc %C[result], r1 \n\t"
- " adc %D[result], %[zero] \n\t"
-
- // cleanup r1
- " clr r1 \n\t"
-
- : [result] "+r" (result)
- : [i] "r" (i),
- [scale] "r" (scale),
- [zero] "r" (zero)
- : "r0", "r1"
- );
+ // result.C-D = i.B x scale.B
+ " mul %B[i], %B[scale] \n\t"
+ //" mov %C[result], r0 \n\t"
+ //" mov %D[result], r1 \n\t"
+ " movw %C[result], r0 \n\t"
+ : [result] "+r" (result)
+ : [i] "r" (i),
+ [scale] "r" (scale)
+ : "r0", "r1"
+);
+
+const uint8_t zero = 0;
+asm volatile(
+ // result.B-D += i.B x scale.A
+ " mul %B[i], %A[scale] \n\t"
+
+ " add %B[result], r0 \n\t"
+ " adc %C[result], r1 \n\t"
+ " adc %D[result], %[zero] \n\t"
+
+ // result.B-D += i.A x scale.B
+ " mul %A[i], %B[scale] \n\t"
+
+ " add %B[result], r0 \n\t"
+ " adc %C[result], r1 \n\t"
+ " adc %D[result], %[zero] \n\t"
+
+ // cleanup r1
+ " clr r1 \n\t"
+
+ : [result] "+r" (result)
+ : [i] "r" (i),
+ [scale] "r" (scale),
+ [zero] "r" (zero)
+ : "r0", "r1"
+ );
asm volatile(
- // result.A-D += i.A-B
- " add %A[result], %A[i] \n\t"
- " adc %B[result], %B[i] \n\t"
- " adc %C[result], %[zero] \n\t"
- " adc %D[result], %[zero] \n\t"
- : [result] "+r" (result)
- : [i] "r" (i),
- [zero] "r" (zero)
- );
+ // result.A-D += i.A-B
+ " add %A[result], %A[i] \n\t"
+ " adc %B[result], %B[i] \n\t"
+ " adc %C[result], %[zero] \n\t"
+ " adc %D[result], %[zero] \n\t"
+ : [result] "+r" (result)
+ : [i] "r" (i),
+ [zero] "r" (zero)
+ );
result = result >> 16;
return result;
#else
uint32_t result;
asm volatile(
- // result.A-B = i.A x scale.A
- " mul %A[i], %A[scale] \n\t"
- // save results...
- // basic idea:
- //" mov %A[result], r0 \n\t"
- //" mov %B[result], r1 \n\t"
- // which can be written as...
- " movw %A[result], r0 \n\t"
- // We actually don't need to do anything with r0,
- // as result.A is never used again here, so we
- // could just move the high byte, but movw is
- // one clock cycle, just like mov, so might as
- // well, in case we want to use this code for
- // a generic 16x16 multiply somewhere.
-
- : [result] "=r" (result)
- : [i] "r" (i),
- [scale] "r" (scale)
- : "r0", "r1"
- );
+ // result.A-B = i.A x scale.A
+ " mul %A[i], %A[scale] \n\t"
+ // save results...
+ // basic idea:
+ //" mov %A[result], r0 \n\t"
+ //" mov %B[result], r1 \n\t"
+ // which can be written as...
+ " movw %A[result], r0 \n\t"
+ // We actually don't need to do anything with r0,
+ // as result.A is never used again here, so we
+ // could just move the high byte, but movw is
+ // one clock cycle, just like mov, so might as
+ // well, in case we want to use this code for
+ // a generic 16x16 multiply somewhere.
+
+ : [result] "=r" (result)
+ : [i] "r" (i),
+ [scale] "r" (scale)
+ : "r0", "r1"
+ );
asm volatile(
- // result.C-D = i.B x scale.B
- " mul %B[i], %B[scale] \n\t"
- //" mov %C[result], r0 \n\t"
- //" mov %D[result], r1 \n\t"
- " movw %C[result], r0 \n\t"
- : [result] "+r" (result)
- : [i] "r" (i),
- [scale] "r" (scale)
- : "r0", "r1"
- );
+ // result.C-D = i.B x scale.B
+ " mul %B[i], %B[scale] \n\t"
+ //" mov %C[result], r0 \n\t"
+ //" mov %D[result], r1 \n\t"
+ " movw %C[result], r0 \n\t"
+ : [result] "+r" (result)
+ : [i] "r" (i),
+ [scale] "r" (scale)
+ : "r0", "r1"
+ );
const uint8_t zero = 0;
asm volatile(
- // result.B-D += i.B x scale.A
- " mul %B[i], %A[scale] \n\t"
+ // result.B-D += i.B x scale.A
+ " mul %B[i], %A[scale] \n\t"
- " add %B[result], r0 \n\t"
- " adc %C[result], r1 \n\t"
- " adc %D[result], %[zero] \n\t"
+ " add %B[result], r0 \n\t"
+ " adc %C[result], r1 \n\t"
+ " adc %D[result], %[zero] \n\t"
- // result.B-D += i.A x scale.B
- " mul %A[i], %B[scale] \n\t"
+ // result.B-D += i.A x scale.B
+ " mul %A[i], %B[scale] \n\t"
- " add %B[result], r0 \n\t"
- " adc %C[result], r1 \n\t"
- " adc %D[result], %[zero] \n\t"
+ " add %B[result], r0 \n\t"
+ " adc %C[result], r1 \n\t"
+ " adc %D[result], %[zero] \n\t"
- // cleanup r1
- " clr r1 \n\t"
+ // cleanup r1
+ " clr r1 \n\t"
- : [result] "+r" (result)
- : [i] "r" (i),
- [scale] "r" (scale),
- [zero] "r" (zero)
- : "r0", "r1"
- );
+ : [result] "+r" (result)
+ : [i] "r" (i),
+ [scale] "r" (scale),
+ [zero] "r" (zero)
+ : "r0", "r1"
+ );
result = result >> 16;
return result;
diff --git a/lib8tion/trig8.h b/lib8tion/trig8.h
index 4907c6ff..6e084075 100644
--- a/lib8tion/trig8.h
+++ b/lib8tion/trig8.h
@@ -161,10 +161,10 @@ LIB8STATIC uint8_t sin8_avr( uint8_t theta)
uint8_t offset = theta;
asm volatile(
- "sbrc %[theta],6 \n\t"
- "com %[offset] \n\t"
- : [theta] "+r" (theta), [offset] "+r" (offset)
- );
+ "sbrc %[theta],6 \n\t"
+ "com %[offset] \n\t"
+ : [theta] "+r" (theta), [offset] "+r" (offset)
+ );
offset &= 0x3F; // 0..63
@@ -185,18 +185,18 @@ LIB8STATIC uint8_t sin8_avr( uint8_t theta)
uint8_t mx;
uint8_t xr1;
asm volatile(
- "mul %[m16],%[secoffset] \n\t"
- "mov %[mx],r0 \n\t"
- "mov %[xr1],r1 \n\t"
- "eor r1, r1 \n\t"
- "swap %[mx] \n\t"
- "andi %[mx],0x0F \n\t"
- "swap %[xr1] \n\t"
- "andi %[xr1], 0xF0 \n\t"
- "or %[mx], %[xr1] \n\t"
- : [mx] "=d" (mx), [xr1] "=d" (xr1)
- : [m16] "d" (m16), [secoffset] "d" (secoffset)
- );
+ "mul %[m16],%[secoffset] \n\t"
+ "mov %[mx],r0 \n\t"
+ "mov %[xr1],r1 \n\t"
+ "eor r1, r1 \n\t"
+ "swap %[mx] \n\t"
+ "andi %[mx],0x0F \n\t"
+ "swap %[xr1] \n\t"
+ "andi %[xr1], 0xF0 \n\t"
+ "or %[mx], %[xr1] \n\t"
+ : [mx] "=d" (mx), [xr1] "=d" (xr1)
+ : [m16] "d" (m16), [secoffset] "d" (secoffset)
+ );
int8_t y = mx + b;
if( theta & 0x80 ) y = -y;
diff --git a/noise.cpp b/noise.cpp
index 7d42d64d..2963c4a4 100644
--- a/noise.cpp
+++ b/noise.cpp
@@ -6,21 +6,24 @@ FASTLED_NAMESPACE_BEGIN
#define P(x) FL_PGM_READ_BYTE_NEAR(p + x)
-FL_PROGMEM static uint8_t const p[] = { 151,160,137,91,90,15,
- 131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,99,37,240,21,10,23,
- 190, 6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,11,32,57,177,33,
- 88,237,149,56,87,174,20,125,136,171,168, 68,175,74,165,71,134,139,48,27,166,
- 77,146,158,231,83,111,229,122,60,211,133,230,220,105,92,41,55,46,245,40,244,
- 102,143,54, 65,25,63,161, 1,216,80,73,209,76,132,187,208, 89,18,169,200,196,
- 135,130,116,188,159,86,164,100,109,198,173,186, 3,64,52,217,226,250,124,123,
- 5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182,189,28,42,
- 223,183,170,213,119,248,152, 2,44,154,163, 70,221,153,101,155,167, 43,172,9,
- 129,22,39,253, 19,98,108,110,79,113,224,232,178,185, 112,104,218,246,97,228,
- 251,34,242,193,238,210,144,12,191,179,162,241, 81,51,145,235,249,14,239,107,
- 49,192,214, 31,181,199,106,157,184, 84,204,176,115,121,50,45,127, 4,150,254,
- 138,236,205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180,151
- };
-
+FL_PROGMEM static uint8_t const p[] = {
+ 151, 160, 137, 91, 90, 15, 131, 13, 201, 95, 96, 53, 194, 233, 7, 225,
+ 140, 36, 103, 30, 69, 142, 8, 99, 37, 240, 21, 10, 23, 190, 6, 148,
+ 247, 120, 234, 75, 0, 26, 197, 62, 94, 252, 219, 203, 117, 35, 11, 32,
+ 57, 177, 33, 88, 237, 149, 56, 87, 174, 20, 125, 136, 171, 168, 68, 175,
+ 74, 165, 71, 134, 139, 48, 27, 166, 77, 146, 158, 231, 83, 111, 229, 122,
+ 60, 211, 133, 230, 220, 105, 92, 41, 55, 46, 245, 40, 244, 102, 143, 54,
+ 65, 25, 63, 161, 1, 216, 80, 73, 209, 76, 132, 187, 208, 89, 18, 169,
+ 200, 196, 135, 130, 116, 188, 159, 86, 164, 100, 109, 198, 173, 186, 3, 64,
+ 52, 217, 226, 250, 124, 123, 5, 202, 38, 147, 118, 126, 255, 82, 85, 212,
+ 207, 206, 59, 227, 47, 16, 58, 17, 182, 189, 28, 42, 223, 183, 170, 213,
+ 119, 248, 152, 2, 44, 154, 163, 70, 221, 153, 101, 155, 167, 43, 172, 9,
+ 129, 22, 39, 253, 19, 98, 108, 110, 79, 113, 224, 232, 178, 185, 112, 104,
+ 218, 246, 97, 228, 251, 34, 242, 193, 238, 210, 144, 12, 191, 179, 162, 241,
+ 81, 51, 145, 235, 249, 14, 239, 107, 49, 192, 214, 31, 181, 199, 106, 157,
+ 184, 84, 204, 176, 115, 121, 50, 45, 127, 4, 150, 254, 138, 236, 205, 93,
+ 222, 114, 67, 29, 24, 72, 243, 141, 128, 195, 78, 66, 215, 61, 156, 180,
+ 151};
#if FASTLED_NOISE_ALLOW_AVERAGE_TO_OVERFLOW == 1
#define AVG15(U,V) (((U)+(V)) >> 1)
@@ -74,55 +77,55 @@ static int16_t inline __attribute__((always_inline)) avg15_inline_avr_mul( int1
#endif
static int16_t inline __attribute__((always_inline)) grad16(uint8_t hash, int16_t x, int16_t y, int16_t z) {
#if 0
- switch(hash & 0xF) {
- case 0: return (( x) + ( y))>>1;
- case 1: return ((-x) + ( y))>>1;
- case 2: return (( x) + (-y))>>1;
- case 3: return ((-x) + (-y))>>1;
- case 4: return (( x) + ( z))>>1;
- case 5: return ((-x) + ( z))>>1;
- case 6: return (( x) + (-z))>>1;
- case 7: return ((-x) + (-z))>>1;
- case 8: return (( y) + ( z))>>1;
- case 9: return ((-y) + ( z))>>1;
- case 10: return (( y) + (-z))>>1;
- case 11: return ((-y) + (-z))>>1;
- case 12: return (( y) + ( x))>>1;
- case 13: return ((-y) + ( z))>>1;
- case 14: return (( y) + (-x))>>1;
- case 15: return ((-y) + (-z))>>1;
- }
+ switch(hash & 0xF) {
+ case 0: return (( x) + ( y))>>1;
+ case 1: return ((-x) + ( y))>>1;
+ case 2: return (( x) + (-y))>>1;
+ case 3: return ((-x) + (-y))>>1;
+ case 4: return (( x) + ( z))>>1;
+ case 5: return ((-x) + ( z))>>1;
+ case 6: return (( x) + (-z))>>1;
+ case 7: return ((-x) + (-z))>>1;
+ case 8: return (( y) + ( z))>>1;
+ case 9: return ((-y) + ( z))>>1;
+ case 10: return (( y) + (-z))>>1;
+ case 11: return ((-y) + (-z))>>1;
+ case 12: return (( y) + ( x))>>1;
+ case 13: return ((-y) + ( z))>>1;
+ case 14: return (( y) + (-x))>>1;
+ case 15: return ((-y) + (-z))>>1;
+ }
#else
- hash = hash&15;
- int16_t u = hash<8?x:y;
- int16_t v = hash<4?y:hash==12||hash==14?x:z;
- if(hash&1) { u = -u; }
- if(hash&2) { v = -v; }
+ hash = hash&15;
+ int16_t u = hash<8?x:y;
+ int16_t v = hash<4?y:hash==12||hash==14?x:z;
+ if(hash&1) { u = -u; }
+ if(hash&2) { v = -v; }
- return AVG15(u,v);
+ return AVG15(u,v);
#endif
}
static int16_t inline __attribute__((always_inline)) grad16(uint8_t hash, int16_t x, int16_t y) {
- hash = hash & 7;
- int16_t u,v;
- if(hash < 4) { u = x; v = y; } else { u = y; v = x; }
- if(hash&1) { u = -u; }
- if(hash&2) { v = -v; }
+ hash = hash & 7;
+ int16_t u,v;
+ if(hash < 4) { u = x; v = y; } else { u = y; v = x; }
+ if(hash&1) { u = -u; }
+ if(hash&2) { v = -v; }
- return AVG15(u,v);
+ return AVG15(u,v);
}
static int16_t inline __attribute__((always_inline)) grad16(uint8_t hash, int16_t x) {
- hash = hash & 15;
- int16_t u,v;
- if(hash > 8) { u=x;v=x; }
- else if(hash < 4) { u=x;v=1; }
- else { u=1;v=x; }
- if(hash&1) { u = -u; }
- if(hash&2) { v = -v; }
+ hash = hash & 15;
+ int16_t u,v;
+ if(hash > 8) { u=x;v=x; }
+ else if(hash < 4) { u=x;v=1; }
+ else { u=1;v=x; }
+ if(hash&1) { u = -u; }
+ if(hash&2) { v = -v; }
- return AVG15(u,v);
+ return AVG15(u,v);
}
// selectBasedOnHashBit performs this:
@@ -150,115 +153,115 @@ static int8_t inline __attribute__((always_inline)) selectBasedOnHashBit(uint8_t
static int8_t inline __attribute__((always_inline)) grad8(uint8_t hash, int8_t x, int8_t y, int8_t z) {
#if 0
- switch(hash & 0xF) {
- case 0: return (( x) + ( y))>>1;
- case 1: return ((-x) + ( y))>>1;
- case 2: return (( x) + (-y))>>1;
- case 3: return ((-x) + (-y))>>1;
- case 4: return (( x) + ( z))>>1;
- case 5: return ((-x) + ( z))>>1;
- case 6: return (( x) + (-z))>>1;
- case 7: return ((-x) + (-z))>>1;
- case 8: return (( y) + ( z))>>1;
- case 9: return ((-y) + ( z))>>1;
- case 10: return (( y) + (-z))>>1;
- case 11: return ((-y) + (-z))>>1;
- case 12: return (( y) + ( x))>>1;
- case 13: return ((-y) + ( z))>>1;
- case 14: return (( y) + (-x))>>1;
- case 15: return ((-y) + (-z))>>1;
- }
+ switch(hash & 0xF) {
+ case 0: return (( x) + ( y))>>1;
+ case 1: return ((-x) + ( y))>>1;
+ case 2: return (( x) + (-y))>>1;
+ case 3: return ((-x) + (-y))>>1;
+ case 4: return (( x) + ( z))>>1;
+ case 5: return ((-x) + ( z))>>1;
+ case 6: return (( x) + (-z))>>1;
+ case 7: return ((-x) + (-z))>>1;
+ case 8: return (( y) + ( z))>>1;
+ case 9: return ((-y) + ( z))>>1;
+ case 10: return (( y) + (-z))>>1;
+ case 11: return ((-y) + (-z))>>1;
+ case 12: return (( y) + ( x))>>1;
+ case 13: return ((-y) + ( z))>>1;
+ case 14: return (( y) + (-x))>>1;
+ case 15: return ((-y) + (-z))>>1;
+ }
#else
- hash &= 0xF;
+ hash &= 0xF;
- int8_t u, v;
- //u = (hash&8)?y:x;
- u = selectBasedOnHashBit( hash, 3, y, x);
+ int8_t u, v;
+ //u = (hash&8)?y:x;
+ u = selectBasedOnHashBit( hash, 3, y, x);
#if 1
- v = hash<4?y:hash==12||hash==14?x:z;
+ v = hash<4?y:hash==12||hash==14?x:z;
#else
- // Verbose version for analysis; generates idenitical code.
- if( hash < 4) { // 00 01 02 03
- v = y;
- } else {
- if( hash==12 || hash==14) { // 0C 0E
- v = x;
- } else {
- v = z; // 04 05 06 07 08 09 0A 0B 0D 0F
- }
- }
+ // Verbose version for analysis; generates idenitical code.
+ if( hash < 4) { // 00 01 02 03
+ v = y;
+ } else {
+ if( hash==12 || hash==14) { // 0C 0E
+ v = x;
+ } else {
+ v = z; // 04 05 06 07 08 09 0A 0B 0D 0F
+ }
+ }
#endif
- if(hash&1) { u = -u; }
- if(hash&2) { v = -v; }
+ if(hash&1) { u = -u; }
+ if(hash&2) { v = -v; }
- return avg7(u,v);
+ return avg7(u,v);
#endif
}
static int8_t inline __attribute__((always_inline)) grad8(uint8_t hash, int8_t x, int8_t y)
{
- // since the tests below can be done bit-wise on the bottom
- // three bits, there's no need to mask off the higher bits
- // hash = hash & 7;
+ // since the tests below can be done bit-wise on the bottom
+ // three bits, there's no need to mask off the higher bits
+ // hash = hash & 7;
- int8_t u,v;
- if( hash & 4) {
- u = y; v = x;
- } else {
- u = x; v = y;
- }
+ int8_t u,v;
+ if( hash & 4) {
+ u = y; v = x;
+ } else {
+ u = x; v = y;
+ }
- if(hash&1) { u = -u; }
- if(hash&2) { v = -v; }
+ if(hash&1) { u = -u; }
+ if(hash&2) { v = -v; }
- return avg7(u,v);
+ return avg7(u,v);
}
static int8_t inline __attribute__((always_inline)) grad8(uint8_t hash, int8_t x)
{
- // since the tests below can be done bit-wise on the bottom
- // four bits, there's no need to mask off the higher bits
- // hash = hash & 15;
+ // since the tests below can be done bit-wise on the bottom
+ // four bits, there's no need to mask off the higher bits
+ // hash = hash & 15;
- int8_t u,v;
- if(hash & 8) {
- u=x; v=x;
- } else {
- if(hash & 4) {
- u=1; v=x;
- } else {
- u=x; v=1;
- }
- }
+ int8_t u,v;
+ if(hash & 8) {
+ u=x; v=x;
+ } else {
+ if(hash & 4) {
+ u=1; v=x;
+ } else {
+ u=x; v=1;
+ }
+ }
- if(hash&1) { u = -u; }
- if(hash&2) { v = -v; }
+ if(hash&1) { u = -u; }
+ if(hash&2) { v = -v; }
- return avg7(u,v);
+ return avg7(u,v);
}
#ifdef FADE_12
uint16_t logfade12(uint16_t val) {
- return scale16(val,val)>>4;
+ return scale16(val,val)>>4;
}
static int16_t inline __attribute__((always_inline)) lerp15by12( int16_t a, int16_t b, fract16 frac)
{
- //if(1) return (lerp(frac,a,b));
+ //if(1) return (lerp(frac,a,b));
int16_t result;
if( b > a) {
uint16_t delta = b - a;
uint16_t scaled = scale16(delta,frac<<4);
result = a + scaled;
- } else {
+ } else {
uint16_t delta = a - b;
uint16_t scaled = scale16(delta,frac<<4);
- result = a - scaled;
- }
+ result = a - scaled;
+ }
return result;
}
#endif
@@ -285,183 +288,183 @@ static int8_t inline __attribute__((always_inline)) lerp7by8( int8_t a, int8_t b
int16_t inoise16_raw(uint32_t x, uint32_t y, uint32_t z)
{
- // Find the unit cube containing the point
- uint8_t X = (x>>16)&0xFF;
- uint8_t Y = (y>>16)&0xFF;
- uint8_t Z = (z>>16)&0xFF;
-
- // Hash cube corner coordinates
- uint8_t A = P(X)+Y;
- uint8_t AA = P(A)+Z;
- uint8_t AB = P(A+1)+Z;
- uint8_t B = P(X+1)+Y;
- uint8_t BA = P(B) + Z;
- uint8_t BB = P(B+1)+Z;
-
- // Get the relative position of the point in the cube
- uint16_t u = x & 0xFFFF;
- uint16_t v = y & 0xFFFF;
- uint16_t w = z & 0xFFFF;
-
- // Get a signed version of the above for the grad function
- int16_t xx = (u >> 1) & 0x7FFF;
- int16_t yy = (v >> 1) & 0x7FFF;
- int16_t zz = (w >> 1) & 0x7FFF;
- uint16_t N = 0x8000L;
-
- u = EASE16(u); v = EASE16(v); w = EASE16(w);
-
- // skip the log fade adjustment for the moment, otherwise here we would
- // adjust fade values for u,v,w
- int16_t X1 = LERP(grad16(P(AA), xx, yy, zz), grad16(P(BA), xx - N, yy, zz), u);
- int16_t X2 = LERP(grad16(P(AB), xx, yy-N, zz), grad16(P(BB), xx - N, yy - N, zz), u);
- int16_t X3 = LERP(grad16(P(AA+1), xx, yy, zz-N), grad16(P(BA+1), xx - N, yy, zz-N), u);
- int16_t X4 = LERP(grad16(P(AB+1), xx, yy-N, zz-N), grad16(P(BB+1), xx - N, yy - N, zz - N), u);
-
- int16_t Y1 = LERP(X1,X2,v);
- int16_t Y2 = LERP(X3,X4,v);
+ // Find the unit cube containing the point
+ uint8_t X = (x>>16)&0xFF;
+ uint8_t Y = (y>>16)&0xFF;
+ uint8_t Z = (z>>16)&0xFF;
+
+ // Hash cube corner coordinates
+ uint8_t A = P(X)+Y;
+ uint8_t AA = P(A)+Z;
+ uint8_t AB = P(A+1)+Z;
+ uint8_t B = P(X+1)+Y;
+ uint8_t BA = P(B) + Z;
+ uint8_t BB = P(B+1)+Z;
+
+ // Get the relative position of the point in the cube
+ uint16_t u = x & 0xFFFF;
+ uint16_t v = y & 0xFFFF;
+ uint16_t w = z & 0xFFFF;
+
+ // Get a signed version of the above for the grad function
+ int16_t xx = (u >> 1) & 0x7FFF;
+ int16_t yy = (v >> 1) & 0x7FFF;
+ int16_t zz = (w >> 1) & 0x7FFF;
+ uint16_t N = 0x8000L;
+
+ u = EASE16(u); v = EASE16(v); w = EASE16(w);
+
+ // skip the log fade adjustment for the moment, otherwise here we would
+ // adjust fade values for u,v,w
+ int16_t X1 = LERP(grad16(P(AA), xx, yy, zz), grad16(P(BA), xx - N, yy, zz), u);
+ int16_t X2 = LERP(grad16(P(AB), xx, yy-N, zz), grad16(P(BB), xx - N, yy - N, zz), u);
+ int16_t X3 = LERP(grad16(P(AA+1), xx, yy, zz-N), grad16(P(BA+1), xx - N, yy, zz-N), u);
+ int16_t X4 = LERP(grad16(P(AB+1), xx, yy-N, zz-N), grad16(P(BB+1), xx - N, yy - N, zz - N), u);
+
+ int16_t Y1 = LERP(X1,X2,v);
+ int16_t Y2 = LERP(X3,X4,v);
+
+ int16_t ans = LERP(Y1,Y2,w);
- int16_t ans = LERP(Y1,Y2,w);
-
- return ans;
+ return ans;
}
uint16_t inoise16(uint32_t x, uint32_t y, uint32_t z) {
- int32_t ans = inoise16_raw(x,y,z);
- ans = ans + 19052L;
- uint32_t pan = ans;
- // pan = (ans * 220L) >> 7. That's the same as:
- // pan = (ans * 440L) >> 8. And this way avoids a 7X four-byte shift-loop on AVR.
- // Identical math, except for the highest bit, which we don't care about anyway,
- // since we're returning the 'middle' 16 out of a 32-bit value anyway.
- pan *= 440L;
- return (pan>>8);
+ int32_t ans = inoise16_raw(x,y,z);
+ ans = ans + 19052L;
+ uint32_t pan = ans;
+ // pan = (ans * 220L) >> 7. That's the same as:
+ // pan = (ans * 440L) >> 8. And this way avoids a 7X four-byte shift-loop on AVR.
+ // Identical math, except for the highest bit, which we don't care about anyway,
+ // since we're returning the 'middle' 16 out of a 32-bit value anyway.
+ pan *= 440L;
+ return (pan>>8);
- // // return scale16by8(pan,220)<<1;
- // return ((inoise16_raw(x,y,z)+19052)*220)>>7;
- // return scale16by8(inoise16_raw(x,y,z)+19052,220)<<1;
+ // // return scale16by8(pan,220)<<1;
+ // return ((inoise16_raw(x,y,z)+19052)*220)>>7;
+ // return scale16by8(inoise16_raw(x,y,z)+19052,220)<<1;
}
int16_t inoise16_raw(uint32_t x, uint32_t y)
{
- // Find the unit cube containing the point
- uint8_t X = x>>16;
- uint8_t Y = y>>16;
+ // Find the unit cube containing the point
+ uint8_t X = x>>16;
+ uint8_t Y = y>>16;
- // Hash cube corner coordinates
- uint8_t A = P(X)+Y;
- uint8_t AA = P(A);
- uint8_t AB = P(A+1);
- uint8_t B = P(X+1)+Y;
- uint8_t BA = P(B);
- uint8_t BB = P(B+1);
+ // Hash cube corner coordinates
+ uint8_t A = P(X)+Y;
+ uint8_t AA = P(A);
+ uint8_t AB = P(A+1);
+ uint8_t B = P(X+1)+Y;
+ uint8_t BA = P(B);
+ uint8_t BB = P(B+1);
- // Get the relative position of the point in the cube
- uint16_t u = x & 0xFFFF;
- uint16_t v = y & 0xFFFF;
+ // Get the relative position of the point in the cube
+ uint16_t u = x & 0xFFFF;
+ uint16_t v = y & 0xFFFF;
- // Get a signed version of the above for the grad function
- int16_t xx = (u >> 1) & 0x7FFF;
- int16_t yy = (v >> 1) & 0x7FFF;
- uint16_t N = 0x8000L;
+ // Get a signed version of the above for the grad function
+ int16_t xx = (u >> 1) & 0x7FFF;
+ int16_t yy = (v >> 1) & 0x7FFF;
+ uint16_t N = 0x8000L;
- u = EASE16(u); v = EASE16(v);
+ u = EASE16(u); v = EASE16(v);
- int16_t X1 = LERP(grad16(P(AA), xx, yy), grad16(P(BA), xx - N, yy), u);
- int16_t X2 = LERP(grad16(P(AB), xx, yy-N), grad16(P(BB), xx - N, yy - N), u);
+ int16_t X1 = LERP(grad16(P(AA), xx, yy), grad16(P(BA), xx - N, yy), u);
+ int16_t X2 = LERP(grad16(P(AB), xx, yy-N), grad16(P(BB), xx - N, yy - N), u);
- int16_t ans = LERP(X1,X2,v);
+ int16_t ans = LERP(X1,X2,v);
- return ans;
+ return ans;
}
uint16_t inoise16(uint32_t x, uint32_t y) {
- int32_t ans = inoise16_raw(x,y);
- ans = ans + 17308L;
- uint32_t pan = ans;
- // pan = (ans * 242L) >> 7. That's the same as:
- // pan = (ans * 484L) >> 8. And this way avoids a 7X four-byte shift-loop on AVR.
- // Identical math, except for the highest bit, which we don't care about anyway,
- // since we're returning the 'middle' 16 out of a 32-bit value anyway.
- pan *= 484L;
- return (pan>>8);
-
- // return (uint32_t)(((int32_t)inoise16_raw(x,y)+(uint32_t)17308)*242)>>7;
- // return scale16by8(inoise16_raw(x,y)+17308,242)<<1;
+ int32_t ans = inoise16_raw(x,y);
+ ans = ans + 17308L;
+ uint32_t pan = ans;
+ // pan = (ans * 242L) >> 7. That's the same as:
+ // pan = (ans * 484L) >> 8. And this way avoids a 7X four-byte shift-loop on AVR.
+ // Identical math, except for the highest bit, which we don't care about anyway,
+ // since we're returning the 'middle' 16 out of a 32-bit value anyway.
+ pan *= 484L;
+ return (pan>>8);
+
+ // return (uint32_t)(((int32_t)inoise16_raw(x,y)+(uint32_t)17308)*242)>>7;
+ // return scale16by8(inoise16_raw(x,y)+17308,242)<<1;
}
int16_t inoise16_raw(uint32_t x)
{
- // Find the unit cube containing the point
- uint8_t X = x>>16;
+ // Find the unit cube containing the point
+ uint8_t X = x>>16;
- // Hash cube corner coordinates
- uint8_t A = P(X);
- uint8_t AA = P(A);
- uint8_t B = P(X+1);
- uint8_t BA = P(B);
+ // Hash cube corner coordinates
+ uint8_t A = P(X);
+ uint8_t AA = P(A);
+ uint8_t B = P(X+1);
+ uint8_t BA = P(B);
- // Get the relative position of the point in the cube
- uint16_t u = x & 0xFFFF;
+ // Get the relative position of the point in the cube
+ uint16_t u = x & 0xFFFF;
- // Get a signed version of the above for the grad function
- int16_t xx = (u >> 1) & 0x7FFF;
- uint16_t N = 0x8000L;
+ // Get a signed version of the above for the grad function
+ int16_t xx = (u >> 1) & 0x7FFF;
+ uint16_t N = 0x8000L;
- u = EASE16(u);
+ u = EASE16(u);
- int16_t ans = LERP(grad16(P(AA), xx), grad16(P(BA), xx - N), u);
+ int16_t ans = LERP(grad16(P(AA), xx), grad16(P(BA), xx - N), u);
- return ans;
+ return ans;
}
uint16_t inoise16(uint32_t x) {
- return ((uint32_t)((int32_t)inoise16_raw(x) + 17308L)) << 1;
+ return ((uint32_t)((int32_t)inoise16_raw(x) + 17308L)) << 1;
}
int8_t inoise8_raw(uint16_t x, uint16_t y, uint16_t z)
{
- // Find the unit cube containing the point
- uint8_t X = x>>8;
- uint8_t Y = y>>8;
- uint8_t Z = z>>8;
-
- // Hash cube corner coordinates
- uint8_t A = P(X)+Y;
- uint8_t AA = P(A)+Z;
- uint8_t AB = P(A+1)+Z;
- uint8_t B = P(X+1)+Y;
- uint8_t BA = P(B) + Z;
- uint8_t BB = P(B+1)+Z;
-
- // Get the relative position of the point in the cube
- uint8_t u = x;
- uint8_t v = y;
- uint8_t w = z;
-
- // Get a signed version of the above for the grad function
- int8_t xx = ((uint8_t)(x)>>1) & 0x7F;
- int8_t yy = ((uint8_t)(y)>>1) & 0x7F;
- int8_t zz = ((uint8_t)(z)>>1) & 0x7F;
- uint8_t N = 0x80;
-
- u = EASE8(u); v = EASE8(v); w = EASE8(w);
-
- int8_t X1 = lerp7by8(grad8(P(AA), xx, yy, zz), grad8(P(BA), xx - N, yy, zz), u);
- int8_t X2 = lerp7by8(grad8(P(AB), xx, yy-N, zz), grad8(P(BB), xx - N, yy - N, zz), u);
- int8_t X3 = lerp7by8(grad8(P(AA+1), xx, yy, zz-N), grad8(P(BA+1), xx - N, yy, zz-N), u);
- int8_t X4 = lerp7by8(grad8(P(AB+1), xx, yy-N, zz-N), grad8(P(BB+1), xx - N, yy - N, zz - N), u);
+ // Find the unit cube containing the point
+ uint8_t X = x>>8;
+ uint8_t Y = y>>8;
+ uint8_t Z = z>>8;
+
+ // Hash cube corner coordinates
+ uint8_t A = P(X)+Y;
+ uint8_t AA = P(A)+Z;
+ uint8_t AB = P(A+1)+Z;
+ uint8_t B = P(X+1)+Y;
+ uint8_t BA = P(B) + Z;
+ uint8_t BB = P(B+1)+Z;
+
+ // Get the relative position of the point in the cube
+ uint8_t u = x;
+ uint8_t v = y;
+ uint8_t w = z;
+
+ // Get a signed version of the above for the grad function
+ int8_t xx = ((uint8_t)(x)>>1) & 0x7F;
+ int8_t yy = ((uint8_t)(y)>>1) & 0x7F;
+ int8_t zz = ((uint8_t)(z)>>1) & 0x7F;
+ uint8_t N = 0x80;
+
+ u = EASE8(u); v = EASE8(v); w = EASE8(w);
+
+ int8_t X1 = lerp7by8(grad8(P(AA), xx, yy, zz), grad8(P(BA), xx - N, yy, zz), u);
+ int8_t X2 = lerp7by8(grad8(P(AB), xx, yy-N, zz), grad8(P(BB), xx - N, yy - N, zz), u);
+ int8_t X3 = lerp7by8(grad8(P(AA+1), xx, yy, zz-N), grad8(P(BA+1), xx - N, yy, zz-N), u);
+ int8_t X4 = lerp7by8(grad8(P(AB+1), xx, yy-N, zz-N), grad8(P(BB+1), xx - N, yy - N, zz - N), u);
+
+ int8_t Y1 = lerp7by8(X1,X2,v);
+ int8_t Y2 = lerp7by8(X3,X4,v);
+
+ int8_t ans = lerp7by8(Y1,Y2,w);
- int8_t Y1 = lerp7by8(X1,X2,v);
- int8_t Y2 = lerp7by8(X3,X4,v);
-
- int8_t ans = lerp7by8(Y1,Y2,w);
-
- return ans;
+ return ans;
}
uint8_t inoise8(uint16_t x, uint16_t y, uint16_t z) {
-// return scale8(76+(inoise8_raw(x,y,z)),215)<<1;
+ //return scale8(76+(inoise8_raw(x,y,z)),215)<<1;
int8_t n = inoise8_raw( x, y, z); // -64..+64
n+= 64; // 0..128
uint8_t ans = qadd8( n, n); // 0..255
@@ -470,36 +473,36 @@ uint8_t inoise8(uint16_t x, uint16_t y, uint16_t z) {
int8_t inoise8_raw(uint16_t x, uint16_t y)
{
- // Find the unit cube containing the point
- uint8_t X = x>>8;
- uint8_t Y = y>>8;
+ // Find the unit cube containing the point
+ uint8_t X = x>>8;
+ uint8_t Y = y>>8;
- // Hash cube corner coordinates
- uint8_t A = P(X)+Y;
- uint8_t AA = P(A);
- uint8_t AB = P(A+1);
- uint8_t B = P(X+1)+Y;
- uint8_t BA = P(B);
- uint8_t BB = P(B+1);
+ // Hash cube corner coordinates
+ uint8_t A = P(X)+Y;
+ uint8_t AA = P(A);
+ uint8_t AB = P(A+1);
+ uint8_t B = P(X+1)+Y;
+ uint8_t BA = P(B);
+ uint8_t BB = P(B+1);
- // Get the relative position of the point in the cube
- uint8_t u = x;
- uint8_t v = y;
+ // Get the relative position of the point in the cube
+ uint8_t u = x;
+ uint8_t v = y;
- // Get a signed version of the above for the grad function
- int8_t xx = ((uint8_t)(x)>>1) & 0x7F;
- int8_t yy = ((uint8_t)(y)>>1) & 0x7F;
- uint8_t N = 0x80;
+ // Get a signed version of the above for the grad function
+ int8_t xx = ((uint8_t)(x)>>1) & 0x7F;
+ int8_t yy = ((uint8_t)(y)>>1) & 0x7F;
+ uint8_t N = 0x80;
- u = EASE8(u); v = EASE8(v);
-
- int8_t X1 = lerp7by8(grad8(P(AA), xx, yy), grad8(P(BA), xx - N, yy), u);
- int8_t X2 = lerp7by8(grad8(P(AB), xx, yy-N), grad8(P(BB), xx - N, yy - N), u);
+ u = EASE8(u); v = EASE8(v);
- int8_t ans = lerp7by8(X1,X2,v);
+ int8_t X1 = lerp7by8(grad8(P(AA), xx, yy), grad8(P(BA), xx - N, yy), u);
+ int8_t X2 = lerp7by8(grad8(P(AB), xx, yy-N), grad8(P(BB), xx - N, yy - N), u);
- return ans;
- // return scale8((70+(ans)),234)<<1;
+ int8_t ans = lerp7by8(X1,X2,v);
+
+ return ans;
+ // return scale8((70+(ans)),234)<<1;
}
diff --git a/pixelset.h b/pixelset.h
index c9272ef2..b8488c2c 100644
--- a/pixelset.h
+++ b/pixelset.h
@@ -13,279 +13,279 @@
template<class PIXEL_TYPE>
class CPixelView {
public:
- const int8_t dir;
- const int len;
- PIXEL_TYPE * const leds;
- PIXEL_TYPE * const end_pos;
+ const int8_t dir;
+ const int len;
+ PIXEL_TYPE * const leds;
+ PIXEL_TYPE * const end_pos;
public:
+ /// PixelSet copy constructor
+ inline CPixelView(const CPixelView & other) : dir(other.dir), len(other.len), leds(other.leds), end_pos(other.end_pos) {}
+
+ /// pixelset constructor for a pixel set starting at the given PIXEL_TYPE* and going for _len leds. Note that the length
+ /// can be backwards, creating a PixelSet that walks backwards over the data
+ /// @param leds point to the raw led data
+ /// @param len how many leds in this set
+ inline CPixelView(PIXEL_TYPE *_leds, int _len) : dir(_len < 0 ? -1 : 1), len(_len), leds(_leds), end_pos(_leds + _len) {}
+
+ /// PixelSet constructor for the given set of leds, with start and end boundaries. Note that start can be after
+ /// end, resulting in a set that will iterate backwards
+ /// @param leds point to the raw led data
+ /// @param start the start index of the leds for this array
+ /// @param end the end index of the leds for this array
+ inline CPixelView(PIXEL_TYPE *_leds, int _start, int _end) : dir(((_end-_start)<0) ? -1 : 1), len((_end - _start) + dir), leds(_leds + _start), end_pos(_leds + _start + len) {}
+
+ /// Get the size of this set
+ /// @return the size of the set
+ int size() { return abs(len); }
+
+ /// Whether or not this set goes backwards
+ /// @return whether or not the set is backwards
+ bool reversed() { return len < 0; }
+
+ /// do these sets point to the same thing (note, this is different from the contents of the set being the same)
+ bool operator==(const CPixelView & rhs) const { return leds == rhs.leds && len == rhs.len && dir == rhs.dir; }
+
+ /// do these sets point to the different things (note, this is different from the contents of the set being the same)
+ bool operator!=(const CPixelView & rhs) const { return leds != rhs.leds || len != rhs.len || dir != rhs.dir; }
+
+ /// access a single element in this set, just like an array operator
+ inline PIXEL_TYPE & operator[](int x) const { if(dir & 0x80) { return leds[-x]; } else { return leds[x]; } }
+
+ /// Access an inclusive subset of the leds in this set. Note that start can be greater than end, which will
+ /// result in a reverse ordering for many functions (useful for mirroring)
+ /// @param start the first element from this set for the new subset
+ /// @param end the last element for the new subset
+ inline CPixelView operator()(int start, int end) { return CPixelView(leds, start, end); }
+
+ /// Access an inclusive subset of the leds in this set, starting from the first.
+ /// @param end the last element for the new subset
+ /// Not sure i want this? inline CPixelView operator()(int end) { return CPixelView(leds, 0, end); }
+
+ /// Return the reverse ordering of this set
+ inline CPixelView operator-() { return CPixelView(leds, len - dir, 0); }
+
+ /// Return a pointer to the first element in this set
+ inline operator PIXEL_TYPE* () const { return leds; }
+
+ /// Assign the passed in color to all elements in this set
+ /// @param color the new color for the elements in the set
+ inline CPixelView & operator=(const PIXEL_TYPE & color) {
+ for(iterator pixel = begin(), _end = end(); pixel != _end; ++pixel) { (*pixel) = color; }
+ return *this;
+ }
+
+
+ void dump() const {
+ /**
+ Serial.print("len: "); Serial.print(len); Serial.print(", dir:"); Serial.print((int)dir);
+ Serial.print(", range:"); Serial.print((uint32_t)leds); Serial.print("-"); Serial.print((uint32_t)end_pos);
+ Serial.print(", diff:"); Serial.print((int32_t)(end_pos - leds));
+ Serial.println("");
+ **/
+ }
- /// PixelSet copy constructor
- inline CPixelView(const CPixelView & other) : dir(other.dir), len(other.len), leds(other.leds), end_pos(other.end_pos) {}
-
- /// pixelset constructor for a pixel set starting at the given PIXEL_TYPE* and going for _len leds. Note that the length
- /// can be backwards, creating a PixelSet that walks backwards over the data
- /// @param leds point to the raw led data
- /// @param len how many leds in this set
- inline CPixelView(PIXEL_TYPE *_leds, int _len) : dir(_len < 0 ? -1 : 1), len(_len), leds(_leds), end_pos(_leds + _len) {}
-
- /// PixelSet constructor for the given set of leds, with start and end boundaries. Note that start can be after
- /// end, resulting in a set that will iterate backwards
- /// @param leds point to the raw led data
- /// @param start the start index of the leds for this array
- /// @param end the end index of the leds for this array
- inline CPixelView(PIXEL_TYPE *_leds, int _start, int _end) : dir(((_end-_start)<0) ? -1 : 1), len((_end - _start) + dir), leds(_leds + _start), end_pos(_leds + _start + len) {}
-
- /// Get the size of this set
- /// @return the size of the set
- int size() { return abs(len); }
-
- /// Whether or not this set goes backwards
- /// @return whether or not the set is backwards
- bool reversed() { return len < 0; }
-
- /// do these sets point to the same thing (note, this is different from the contents of the set being the same)
- bool operator==(const CPixelView & rhs) const { return leds == rhs.leds && len == rhs.len && dir == rhs.dir; }
-
- /// do these sets point to the different things (note, this is different from the contents of the set being the same)
- bool operator!=(const CPixelView & rhs) const { return leds != rhs.leds || len != rhs.len || dir != rhs.dir; }
-
- /// access a single element in this set, just like an array operator
- inline PIXEL_TYPE & operator[](int x) const { if(dir & 0x80) { return leds[-x]; } else { return leds[x]; } }
-
- /// Access an inclusive subset of the leds in this set. Note that start can be greater than end, which will
- /// result in a reverse ordering for many functions (useful for mirroring)
- /// @param start the first element from this set for the new subset
- /// @param end the last element for the new subset
- inline CPixelView operator()(int start, int end) { return CPixelView(leds, start, end); }
-
- /// Access an inclusive subset of the leds in this set, starting from the first.
- /// @param end the last element for the new subset
- /// Not sure i want this? inline CPixelView operator()(int end) { return CPixelView(leds, 0, end); }
-
- /// Return the reverse ordering of this set
- inline CPixelView operator-() { return CPixelView(leds, len - dir, 0); }
-
- /// Return a pointer to the first element in this set
- inline operator PIXEL_TYPE* () const { return leds; }
-
- /// Assign the passed in color to all elements in this set
- /// @param color the new color for the elements in the set
- inline CPixelView & operator=(const PIXEL_TYPE & color) {
- for(iterator pixel = begin(), _end = end(); pixel != _end; ++pixel) { (*pixel) = color; }
- return *this;
- }
-
-
- void dump() const {
-/**
- Serial.print("len: "); Serial.print(len); Serial.print(", dir:"); Serial.print((int)dir);
- Serial.print(", range:"); Serial.print((uint32_t)leds); Serial.print("-"); Serial.print((uint32_t)end_pos);
- Serial.print(", diff:"); Serial.print((int32_t)(end_pos - leds));
- Serial.println("");
- **/
- }
-
- /// Copy the contents of the passed in set to our set. Note if one set is smaller than the other, only the
- /// smallest number of items will be copied over.
- inline CPixelView & operator=(const CPixelView & rhs) {
- for(iterator pixel = begin(), rhspixel = rhs.begin(), _end = end(), rhs_end = rhs.end(); (pixel != _end) && (rhspixel != rhs_end); ++pixel, ++rhspixel) {
- (*pixel) = (*rhspixel);
+ /// Copy the contents of the passed in set to our set. Note if one set is smaller than the other, only the
+ /// smallest number of items will be copied over.
+ inline CPixelView & operator=(const CPixelView & rhs) {
+ for(iterator pixel = begin(), rhspixel = rhs.begin(), _end = end(), rhs_end = rhs.end(); (pixel != _end) && (rhspixel != rhs_end); ++pixel, ++rhspixel) {
+ (*pixel) = (*rhspixel);
+ }
+ return *this;
}
- return *this;
- }
-
- /// @name modification/scaling operators
- //@{
- /// Add the passed in value to r,g, b for all the pixels in this set
- inline CPixelView & addToRGB(uint8_t inc) { for(iterator pixel = begin(), _end = end(); pixel != _end; ++pixel) { (*pixel) += inc; } return *this; }
- /// Add every pixel in the other set to this set
- inline CPixelView & operator+=(CPixelView & rhs) { for(iterator pixel = begin(), rhspixel = rhs.begin(), _end = end(), rhs_end = rhs.end(); (pixel != _end) && (rhspixel != rhs_end); ++pixel, ++rhspixel) { (*pixel) += (*rhspixel); } return *this; }
-
- /// Subtract the passed in value from r,g,b for all pixels in this set
- inline CPixelView & subFromRGB(uint8_t inc) { for(iterator pixel = begin(), _end = end(); pixel != _end; ++pixel) { (*pixel) -= inc; } return *this; }
- /// Subtract every pixel in the other set from this set
- inline CPixelView & operator-=(CPixelView & rhs) { for(iterator pixel = begin(), rhspixel = rhs.begin(), _end = end(), rhs_end = rhs.end(); (pixel != _end) && (rhspixel != rhs_end); ++pixel, ++rhspixel) { (*pixel) -= (*rhspixel); } return *this; }
-
- /// Increment every pixel value in this set
- inline CPixelView & operator++() { for(iterator pixel = begin(), _end = end(); pixel != _end; ++pixel) { (*pixel)++; } return *this; }
- /// Increment every pixel value in this set
- inline CPixelView & operator++(int DUMMY_ARG) { for(iterator pixel = begin(), _end = end(); pixel != _end; ++pixel) { (*pixel)++; } return *this; }
-
- /// Decrement every pixel value in this set
- inline CPixelView & operator--() { for(iterator pixel = begin(), _end = end(); pixel != _end; ++pixel) { (*pixel)--; } return *this; }
- /// Decrement every pixel value in this set
- inline CPixelView & operator--(int DUMMY_ARG) { for(iterator pixel = begin(), _end = end(); pixel != _end; ++pixel) { (*pixel)--; } return *this; }
-
- /// Divide every led by the given value
- inline CPixelView & operator/=(uint8_t d) { for(iterator pixel = begin(), _end = end(); pixel != _end; ++pixel) { (*pixel) /= d; } return *this; }
- /// Shift every led in this set right by the given number of bits
- inline CPixelView & operator>>=(uint8_t d) { for(iterator pixel = begin(), _end = end(); pixel != _end; ++pixel) { (*pixel) >>= d; } return *this; }
- /// Multiply every led in this set by the given value
- inline CPixelView & operator*=(uint8_t d) { for(iterator pixel = begin(), _end = end(); pixel != _end; ++pixel) { (*pixel) *= d; } return *this; }
-
- /// Scale every led by the given scale
- inline CPixelView & nscale8_video(uint8_t scaledown) { for(iterator pixel = begin(), _end = end(); pixel != _end; ++pixel) { (*pixel).nscale8_video(scaledown); } return *this;}
- /// Scale down every led by the given scale
- inline CPixelView & operator%=(uint8_t scaledown) { for(iterator pixel = begin(), _end = end(); pixel != _end; ++pixel) { (*pixel).nscale8_video(scaledown); } return *this; }
- /// Fade every led down by the given scale
- inline CPixelView & fadeLightBy(uint8_t fadefactor) { return nscale8_video(255 - fadefactor); }
-
- /// Scale every led by the given scale
- inline CPixelView & nscale8(uint8_t scaledown) { for(iterator pixel = begin(), _end = end(); pixel != _end; ++pixel) { (*pixel).nscale8(scaledown); } return *this; }
- /// Scale every led by the given scale
- inline CPixelView & nscale8(PIXEL_TYPE & scaledown) { for(iterator pixel = begin(), _end = end(); pixel != _end; ++pixel) { (*pixel).nscale8(scaledown); } return *this; }
- /// Scale every led in this set by every led in the other set
- inline CPixelView & nscale8(CPixelView & rhs) { for(iterator pixel = begin(), rhspixel = rhs.begin(), _end = end(), rhs_end = rhs.end(); (pixel != _end) && (rhspixel != rhs_end); ++pixel, ++rhspixel) { (*pixel).nscale8((*rhspixel)); } return *this; }
-
- /// Fade every led down by the given scale
- inline CPixelView & fadeToBlackBy(uint8_t fade) { return nscale8(255 - fade); }
-
- /// Apply the PIXEL_TYPE |= operator to every pixel in this set with the given PIXEL_TYPE value (bringing each channel to the higher of the two values)
- inline CPixelView & operator|=(const PIXEL_TYPE & rhs) { for(iterator pixel = begin(), _end = end(); pixel != _end; ++pixel) { (*pixel) |= rhs; } return *this; }
- /// Apply the PIXEL_TYPE |= operator to every pixel in this set with every pixel in the passed in set
- inline CPixelView & operator|=(const CPixelView & rhs) { for(iterator pixel = begin(), rhspixel = rhs.begin(), _end = end(), rhs_end = rhs.end(); (pixel != _end) && (rhspixel != rhs_end); ++pixel, ++rhspixel) { (*pixel) |= (*rhspixel); } return *this; }
- /// Apply the PIXEL_TYPE |= operator to every pixel in this set
- inline CPixelView & operator|=(uint8_t d) { for(iterator pixel = begin(), _end = end(); pixel != _end; ++pixel) { (*pixel) |= d; } return *this; }
-
- /// Apply the PIXEL_TYPE &= operator to every pixel in this set with the given PIXEL_TYPE value (bringing each channel down to the lower of the two values)
- inline CPixelView & operator&=(const PIXEL_TYPE & rhs) { for(iterator pixel = begin(), _end = end(); pixel != _end; ++pixel) { (*pixel) &= rhs; } return *this; }
- /// Apply the PIXEL_TYPE &= operator to every pixel in this set with every pixel in the passed in set
- inline CPixelView & operator&=(const CPixelView & rhs) { for(iterator pixel = begin(), rhspixel = rhs.begin(), _end = end(), rhs_end = rhs.end(); (pixel != _end) && (rhspixel != rhs_end); ++pixel, ++rhspixel) { (*pixel) &= (*rhspixel); } return *this; }
- /// APply the PIXEL_TYPE &= operator to every pixel in this set with the passed in value
- inline CPixelView & operator&=(uint8_t d) { for(iterator pixel = begin(), _end = end(); pixel != _end; ++pixel) { (*pixel) &= d; } return *this; }
- //@}
-
- /// Returns whether or not any leds in this set are non-zero
- inline operator bool() { for(iterator pixel = begin(), _end = end(); pixel != _end; ++pixel) { if((*pixel)) return true; } return false; }
-
- // Color util functions
- inline CPixelView & fill_solid(const PIXEL_TYPE & color) { *this = color; return *this; }
- inline CPixelView & fill_solid(const CHSV & color) { if(dir>0) { *this = color; return *this; } }
-
- inline CPixelView & fill_rainbow(uint8_t initialhue, uint8_t deltahue=5) {
- if(dir >= 0) {
- ::fill_rainbow(leds,len,initialhue,deltahue);
- } else {
- ::fill_rainbow(leds+len+1,-len,initialhue,deltahue);
+
+ /// @name modification/scaling operators
+ //@{
+ /// Add the passed in value to r,g, b for all the pixels in this set
+ inline CPixelView & addToRGB(uint8_t inc) { for(iterator pixel = begin(), _end = end(); pixel != _end; ++pixel) { (*pixel) += inc; } return *this; }
+ /// Add every pixel in the other set to this set
+ inline CPixelView & operator+=(CPixelView & rhs) { for(iterator pixel = begin(), rhspixel = rhs.begin(), _end = end(), rhs_end = rhs.end(); (pixel != _end) && (rhspixel != rhs_end); ++pixel, ++rhspixel) { (*pixel) += (*rhspixel); } return *this; }
+
+ /// Subtract the passed in value from r,g,b for all pixels in this set
+ inline CPixelView & subFromRGB(uint8_t inc) { for(iterator pixel = begin(), _end = end(); pixel != _end; ++pixel) { (*pixel) -= inc; } return *this; }
+ /// Subtract every pixel in the other set from this set
+ inline CPixelView & operator-=(CPixelView & rhs) { for(iterator pixel = begin(), rhspixel = rhs.begin(), _end = end(), rhs_end = rhs.end(); (pixel != _end) && (rhspixel != rhs_end); ++pixel, ++rhspixel) { (*pixel) -= (*rhspixel); } return *this; }
+
+ /// Increment every pixel value in this set
+ inline CPixelView & operator++() { for(iterator pixel = begin(), _end = end(); pixel != _end; ++pixel) { (*pixel)++; } return *this; }
+ /// Increment every pixel value in this set
+ inline CPixelView & operator++(int DUMMY_ARG) { for(iterator pixel = begin(), _end = end(); pixel != _end; ++pixel) { (*pixel)++; } return *this; }
+
+ /// Decrement every pixel value in this set
+ inline CPixelView & operator--() { for(iterator pixel = begin(), _end = end(); pixel != _end; ++pixel) { (*pixel)--; } return *this; }
+ /// Decrement every pixel value in this set
+ inline CPixelView & operator--(int DUMMY_ARG) { for(iterator pixel = begin(), _end = end(); pixel != _end; ++pixel) { (*pixel)--; } return *this; }
+
+ /// Divide every led by the given value
+ inline CPixelView & operator/=(uint8_t d) { for(iterator pixel = begin(), _end = end(); pixel != _end; ++pixel) { (*pixel) /= d; } return *this; }
+ /// Shift every led in this set right by the given number of bits
+ inline CPixelView & operator>>=(uint8_t d) { for(iterator pixel = begin(), _end = end(); pixel != _end; ++pixel) { (*pixel) >>= d; } return *this; }
+ /// Multiply every led in this set by the given value
+ inline CPixelView & operator*=(uint8_t d) { for(iterator pixel = begin(), _end = end(); pixel != _end; ++pixel) { (*pixel) *= d; } return *this; }
+
+ /// Scale every led by the given scale
+ inline CPixelView & nscale8_video(uint8_t scaledown) { for(iterator pixel = begin(), _end = end(); pixel != _end; ++pixel) { (*pixel).nscale8_video(scaledown); } return *this;}
+ /// Scale down every led by the given scale
+ inline CPixelView & operator%=(uint8_t scaledown) { for(iterator pixel = begin(), _end = end(); pixel != _end; ++pixel) { (*pixel).nscale8_video(scaledown); } return *this; }
+ /// Fade every led down by the given scale
+ inline CPixelView & fadeLightBy(uint8_t fadefactor) { return nscale8_video(255 - fadefactor); }
+
+ /// Scale every led by the given scale
+ inline CPixelView & nscale8(uint8_t scaledown) { for(iterator pixel = begin(), _end = end(); pixel != _end; ++pixel) { (*pixel).nscale8(scaledown); } return *this; }
+ /// Scale every led by the given scale
+ inline CPixelView & nscale8(PIXEL_TYPE & scaledown) { for(iterator pixel = begin(), _end = end(); pixel != _end; ++pixel) { (*pixel).nscale8(scaledown); } return *this; }
+ /// Scale every led in this set by every led in the other set
+ inline CPixelView & nscale8(CPixelView & rhs) { for(iterator pixel = begin(), rhspixel = rhs.begin(), _end = end(), rhs_end = rhs.end(); (pixel != _end) && (rhspixel != rhs_end); ++pixel, ++rhspixel) { (*pixel).nscale8((*rhspixel)); } return *this; }
+
+ /// Fade every led down by the given scale
+ inline CPixelView & fadeToBlackBy(uint8_t fade) { return nscale8(255 - fade); }
+
+ /// Apply the PIXEL_TYPE |= operator to every pixel in this set with the given PIXEL_TYPE value (bringing each channel to the higher of the two values)
+ inline CPixelView & operator|=(const PIXEL_TYPE & rhs) { for(iterator pixel = begin(), _end = end(); pixel != _end; ++pixel) { (*pixel) |= rhs; } return *this; }
+ /// Apply the PIXEL_TYPE |= operator to every pixel in this set with every pixel in the passed in set
+ inline CPixelView & operator|=(const CPixelView & rhs) { for(iterator pixel = begin(), rhspixel = rhs.begin(), _end = end(), rhs_end = rhs.end(); (pixel != _end) && (rhspixel != rhs_end); ++pixel, ++rhspixel) { (*pixel) |= (*rhspixel); } return *this; }
+ /// Apply the PIXEL_TYPE |= operator to every pixel in this set
+ inline CPixelView & operator|=(uint8_t d) { for(iterator pixel = begin(), _end = end(); pixel != _end; ++pixel) { (*pixel) |= d; } return *this; }
+
+ /// Apply the PIXEL_TYPE &= operator to every pixel in this set with the given PIXEL_TYPE value (bringing each channel down to the lower of the two values)
+ inline CPixelView & operator&=(const PIXEL_TYPE & rhs) { for(iterator pixel = begin(), _end = end(); pixel != _end; ++pixel) { (*pixel) &= rhs; } return *this; }
+ /// Apply the PIXEL_TYPE &= operator to every pixel in this set with every pixel in the passed in set
+ inline CPixelView & operator&=(const CPixelView & rhs) { for(iterator pixel = begin(), rhspixel = rhs.begin(), _end = end(), rhs_end = rhs.end(); (pixel != _end) && (rhspixel != rhs_end); ++pixel, ++rhspixel) { (*pixel) &= (*rhspixel); } return *this; }
+ /// APply the PIXEL_TYPE &= operator to every pixel in this set with the passed in value
+ inline CPixelView & operator&=(uint8_t d) { for(iterator pixel = begin(), _end = end(); pixel != _end; ++pixel) { (*pixel) &= d; } return *this; }
+ //@}
+
+ /// Returns whether or not any leds in this set are non-zero
+ inline operator bool() { for(iterator pixel = begin(), _end = end(); pixel != _end; ++pixel) { if((*pixel)) return true; } return false; }
+
+ // Color util functions
+ inline CPixelView & fill_solid(const PIXEL_TYPE & color) { *this = color; return *this; }
+ inline CPixelView & fill_solid(const CHSV & color) { if(dir>0) { *this = color; return *this; } }
+
+ inline CPixelView & fill_rainbow(uint8_t initialhue, uint8_t deltahue=5) {
+ if(dir >= 0) {
+ ::fill_rainbow(leds,len,initialhue,deltahue);
+ } else {
+ ::fill_rainbow(leds+len+1,-len,initialhue,deltahue);
+ }
+ return *this;
}
- return *this;
- }
-
- inline CPixelView & fill_gradient(const CHSV & startcolor, const CHSV & endcolor, TGradientDirectionCode directionCode = SHORTEST_HUES) {
- if(dir >= 0) {
- ::fill_gradient(leds,len,startcolor, endcolor, directionCode);
- } else {
- ::fill_gradient(leds + len + 1, (-len), endcolor, startcolor, directionCode);
+
+ inline CPixelView & fill_gradient(const CHSV & startcolor, const CHSV & endcolor, TGradientDirectionCode directionCode = SHORTEST_HUES) {
+ if(dir >= 0) {
+ ::fill_gradient(leds,len,startcolor, endcolor, directionCode);
+ } else {
+ ::fill_gradient(leds + len + 1, (-len), endcolor, startcolor, directionCode);
+ }
+ return *this;
}
- return *this;
- }
-
- inline CPixelView & fill_gradient(const CHSV & c1, const CHSV & c2, const CHSV & c3, TGradientDirectionCode directionCode = SHORTEST_HUES) {
- if(dir >= 0) {
- ::fill_gradient(leds, len, c1, c2, c3, directionCode);
- } else {
- ::fill_gradient(leds + len + 1, -len, c3, c2, c1, directionCode);
+
+ inline CPixelView & fill_gradient(const CHSV & c1, const CHSV & c2, const CHSV & c3, TGradientDirectionCode directionCode = SHORTEST_HUES) {
+ if(dir >= 0) {
+ ::fill_gradient(leds, len, c1, c2, c3, directionCode);
+ } else {
+ ::fill_gradient(leds + len + 1, -len, c3, c2, c1, directionCode);
+ }
+ return *this;
}
- return *this;
- }
-
- inline CPixelView & fill_gradient(const CHSV & c1, const CHSV & c2, const CHSV & c3, const CHSV & c4, TGradientDirectionCode directionCode = SHORTEST_HUES) {
- if(dir >= 0) {
- ::fill_gradient(leds, len, c1, c2, c3, c4, directionCode);
- } else {
- ::fill_gradient(leds + len + 1, -len, c4, c3, c2, c1, directionCode);
+
+ inline CPixelView & fill_gradient(const CHSV & c1, const CHSV & c2, const CHSV & c3, const CHSV & c4, TGradientDirectionCode directionCode = SHORTEST_HUES) {
+ if(dir >= 0) {
+ ::fill_gradient(leds, len, c1, c2, c3, c4, directionCode);
+ } else {
+ ::fill_gradient(leds + len + 1, -len, c4, c3, c2, c1, directionCode);
+ }
+ return *this;
}
- return *this;
- }
-
- inline CPixelView & fill_gradient_RGB(const PIXEL_TYPE & startcolor, const PIXEL_TYPE & endcolor, TGradientDirectionCode directionCode = SHORTEST_HUES) {
- if(dir >= 0) {
- ::fill_gradient_RGB(leds,len,startcolor, endcolor);
- } else {
- ::fill_gradient_RGB(leds + len + 1, (-len), endcolor, startcolor);
+
+ inline CPixelView & fill_gradient_RGB(const PIXEL_TYPE & startcolor, const PIXEL_TYPE & endcolor, TGradientDirectionCode directionCode = SHORTEST_HUES) {
+ if(dir >= 0) {
+ ::fill_gradient_RGB(leds,len,startcolor, endcolor);
+ } else {
+ ::fill_gradient_RGB(leds + len + 1, (-len), endcolor, startcolor);
+ }
+ return *this;
}
- return *this;
- }
-
- inline CPixelView & fill_gradient_RGB(const PIXEL_TYPE & c1, const PIXEL_TYPE & c2, const PIXEL_TYPE & c3) {
- if(dir >= 0) {
- ::fill_gradient_RGB(leds, len, c1, c2, c3);
- } else {
- ::fill_gradient_RGB(leds + len + 1, -len, c3, c2, c1);
+
+ inline CPixelView & fill_gradient_RGB(const PIXEL_TYPE & c1, const PIXEL_TYPE & c2, const PIXEL_TYPE & c3) {
+ if(dir >= 0) {
+ ::fill_gradient_RGB(leds, len, c1, c2, c3);
+ } else {
+ ::fill_gradient_RGB(leds + len + 1, -len, c3, c2, c1);
+ }
+ return *this;
}
- return *this;
- }
-
- inline CPixelView & fill_gradient_RGB(const PIXEL_TYPE & c1, const PIXEL_TYPE & c2, const PIXEL_TYPE & c3, const PIXEL_TYPE & c4) {
- if(dir >= 0) {
- ::fill_gradient_RGB(leds, len, c1, c2, c3, c4);
- } else {
- ::fill_gradient_RGB(leds + len + 1, -len, c4, c3, c2, c1);
+
+ inline CPixelView & fill_gradient_RGB(const PIXEL_TYPE & c1, const PIXEL_TYPE & c2, const PIXEL_TYPE & c3, const PIXEL_TYPE & c4) {
+ if(dir >= 0) {
+ ::fill_gradient_RGB(leds, len, c1, c2, c3, c4);
+ } else {
+ ::fill_gradient_RGB(leds + len + 1, -len, c4, c3, c2, c1);
+ }
+ return *this;
}
- return *this;
- }
-
- inline CPixelView & nblend(const PIXEL_TYPE & overlay, fract8 amountOfOverlay) { for(iterator pixel = begin(), _end = end(); pixel != _end; ++pixel) { ::nblend((*pixel), overlay, amountOfOverlay); } return *this; }
- inline CPixelView & nblend(const CPixelView & rhs, fract8 amountOfOverlay) { for(iterator pixel = begin(), rhspixel = rhs.begin(), _end = end(), rhs_end = rhs.end(); (pixel != _end) && (rhspixel != rhs_end); ++pixel, ++rhspixel) { ::nblend((*pixel), (*rhspixel), amountOfOverlay); } return *this; }
-
- // Note: only bringing in a 1d blur, not sure 2d blur makes sense when looking at sub arrays
- inline CPixelView & blur1d(fract8 blur_amount) {
- if(dir >= 0) {
- ::blur1d(leds, len, blur_amount);
- } else {
- ::blur1d(leds + len + 1, -len, blur_amount);
+
+ inline CPixelView & nblend(const PIXEL_TYPE & overlay, fract8 amountOfOverlay) { for(iterator pixel = begin(), _end = end(); pixel != _end; ++pixel) { ::nblend((*pixel), overlay, amountOfOverlay); } return *this; }
+ inline CPixelView & nblend(const CPixelView & rhs, fract8 amountOfOverlay) { for(iterator pixel = begin(), rhspixel = rhs.begin(), _end = end(), rhs_end = rhs.end(); (pixel != _end) && (rhspixel != rhs_end); ++pixel, ++rhspixel) { ::nblend((*pixel), (*rhspixel), amountOfOverlay); } return *this; }
+
+ // Note: only bringing in a 1d blur, not sure 2d blur makes sense when looking at sub arrays
+ inline CPixelView & blur1d(fract8 blur_amount) {
+ if(dir >= 0) {
+ ::blur1d(leds, len, blur_amount);
+ } else {
+ ::blur1d(leds + len + 1, -len, blur_amount);
+ }
+ return *this;
}
- return *this;
- }
-
- inline CPixelView & napplyGamma_video(float gamma) {
- if(dir >= 0) {
- ::napplyGamma_video(leds, len, gamma);
- } else {
- ::napplyGamma_video(leds + len + 1, -len, gamma);
+
+ inline CPixelView & napplyGamma_video(float gamma) {
+ if(dir >= 0) {
+ ::napplyGamma_video(leds, len, gamma);
+ } else {
+ ::napplyGamma_video(leds + len + 1, -len, gamma);
+ }
+ return *this;
}
- return *this;
- }
-
- inline CPixelView & napplyGamma_video(float gammaR, float gammaG, float gammaB) {
- if(dir >= 0) {
- ::napplyGamma_video(leds, len, gammaR, gammaG, gammaB);
- } else {
- ::napplyGamma_video(leds + len + 1, -len, gammaR, gammaG, gammaB);
+
+ inline CPixelView & napplyGamma_video(float gammaR, float gammaG, float gammaB) {
+ if(dir >= 0) {
+ ::napplyGamma_video(leds, len, gammaR, gammaG, gammaB);
+ } else {
+ ::napplyGamma_video(leds + len + 1, -len, gammaR, gammaG, gammaB);
+ }
+ return *this;
}
- return *this;
- }
- // TODO: Make this a fully specified/proper iterator
- template <class T>
- class pixelset_iterator_base {
- T * leds;
- const int8_t dir;
- public:
- __attribute__((always_inline)) inline pixelset_iterator_base(const pixelset_iterator_base & rhs) : leds(rhs.leds), dir(rhs.dir) {}
- __attribute__((always_inline)) inline pixelset_iterator_base(T * _leds, const char _dir) : leds(_leds), dir(_dir) {}
+ // TODO: Make this a fully specified/proper iterator
+ template <class T>
+ class pixelset_iterator_base {
+ T * leds;
+ const int8_t dir;
- __attribute__((always_inline)) inline pixelset_iterator_base& operator++() { leds += dir; return *this; }
- __attribute__((always_inline)) inline pixelset_iterator_base operator++(int) { pixelset_iterator_base tmp(*this); leds += dir; return tmp; }
+ public:
+ __attribute__((always_inline)) inline pixelset_iterator_base(const pixelset_iterator_base & rhs) : leds(rhs.leds), dir(rhs.dir) {}
+ __attribute__((always_inline)) inline pixelset_iterator_base(T * _leds, const char _dir) : leds(_leds), dir(_dir) {}
- __attribute__((always_inline)) inline bool operator==(pixelset_iterator_base & other) const { return leds == other.leds; } // && set==other.set; }
- __attribute__((always_inline)) inline bool operator!=(pixelset_iterator_base & other) const { return leds != other.leds; } // || set != other.set; }
+ __attribute__((always_inline)) inline pixelset_iterator_base& operator++() { leds += dir; return *this; }
+ __attribute__((always_inline)) inline pixelset_iterator_base operator++(int) { pixelset_iterator_base tmp(*this); leds += dir; return tmp; }
- __attribute__((always_inline)) inline PIXEL_TYPE& operator*() const { return *leds; }
- };
+ __attribute__((always_inline)) inline bool operator==(pixelset_iterator_base & other) const { return leds == other.leds; } // && set==other.set; }
+ __attribute__((always_inline)) inline bool operator!=(pixelset_iterator_base & other) const { return leds != other.leds; } // || set != other.set; }
- typedef pixelset_iterator_base<PIXEL_TYPE> iterator;
- typedef pixelset_iterator_base<const PIXEL_TYPE> const_iterator;
+ __attribute__((always_inline)) inline PIXEL_TYPE& operator*() const { return *leds; }
+ };
- iterator begin() { return iterator(leds, dir); }
- iterator end() { return iterator(end_pos, dir); }
+ typedef pixelset_iterator_base<PIXEL_TYPE> iterator;
+ typedef pixelset_iterator_base<const PIXEL_TYPE> const_iterator;
- iterator begin() const { return iterator(leds, dir); }
- iterator end() const { return iterator(end_pos, dir); }
+ iterator begin() { return iterator(leds, dir); }
+ iterator end() { return iterator(end_pos, dir); }
- const_iterator cbegin() const { return const_iterator(leds, dir); }
- const_iterator cend() const { return const_iterator(end_pos, dir); }
+ iterator begin() const { return iterator(leds, dir); }
+ iterator end() const { return iterator(end_pos, dir); }
+
+ const_iterator cbegin() const { return const_iterator(leds, dir); }
+ const_iterator cend() const { return const_iterator(end_pos, dir); }
};
typedef CPixelView<CRGB> CRGBSet;
@@ -296,10 +296,11 @@ inline CRGB *operator+(const CRGBSet & pixels, int offset) { return (CRGB*)pixel
template<int SIZE>
class CRGBArray : public CPixelView<CRGB> {
- CRGB rawleds[SIZE];
+ CRGB rawleds[SIZE];
+
public:
- CRGBArray() : CPixelView<CRGB>(rawleds, SIZE) {}
- using CPixelView::operator=;
+ CRGBArray() : CPixelView<CRGB>(rawleds, SIZE) {}
+ using CPixelView::operator=;
};
#endif
diff --git a/pixeltypes.h b/pixeltypes.h
index f4e57061..b3a3ff69 100644
--- a/pixeltypes.h
+++ b/pixeltypes.h
@@ -317,10 +317,10 @@ struct CRGB {
/// right shift each of the channels by a constant
inline CRGB& operator>>= (uint8_t d)
{
- r >>= d;
- g >>= d;
- b >>= d;
- return *this;
+ r >>= d;
+ g >>= d;
+ b >>= d;
+ return *this;
}
/// multiply each of the channels by a constant,
@@ -450,11 +450,11 @@ struct CRGB {
#if (defined SmartMatrix_h || defined SmartMatrix3_h)
operator rgb24() const {
- rgb24 ret;
- ret.red = r;
- ret.green = g;
- ret.blue = b;
- return ret;
+ rgb24 ret;
+ ret.red = r;
+ ret.green = g;
+ ret.blue = b;
+ return ret;
}
#endif
@@ -503,25 +503,25 @@ struct CRGB {
/// return a new CRGB object after performing a linear interpolation between this object and the passed in object
inline CRGB lerp8( const CRGB& other, fract8 frac) const
{
- CRGB ret;
+ CRGB ret;
- ret.r = lerp8by8(r,other.r,frac);
- ret.g = lerp8by8(g,other.g,frac);
- ret.b = lerp8by8(b,other.b,frac);
+ ret.r = lerp8by8(r,other.r,frac);
+ ret.g = lerp8by8(g,other.g,frac);
+ ret.b = lerp8by8(b,other.b,frac);
- return ret;
+ return ret;
}
/// return a new CRGB object after performing a linear interpolation between this object and the passed in object
inline CRGB lerp16( const CRGB& other, fract16 frac) const
{
- CRGB ret;
+ CRGB ret;
- ret.r = lerp16by16(r<<8,other.r<<8,frac)>>8;
- ret.g = lerp16by16(g<<8,other.g<<8,frac)>>8;
- ret.b = lerp16by16(b<<8,other.b<<8,frac)>>8;
+ ret.r = lerp16by16(r<<8,other.r<<8,frac)>>8;
+ ret.g = lerp16by16(g<<8,other.g<<8,frac)>>8;
+ ret.b = lerp16by16(b<<8,other.b<<8,frac)>>8;
- return ret;
+ return ret;
}
/// getParity returns 0 or 1, depending on the
diff --git a/platforms/apollo3/clockless_apollo3.h b/platforms/apollo3/clockless_apollo3.h
index d881eee4..fa487c2f 100644
--- a/platforms/apollo3/clockless_apollo3.h
+++ b/platforms/apollo3/clockless_apollo3.h
@@ -31,7 +31,7 @@ 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;
- CMinWait<WAIT_TIME> mWait;
+ CMinWait<WAIT_TIME> mWait;
public:
virtual void init() {
@@ -39,86 +39,85 @@ public:
// Configure DATA_PIN for FastGPIO (settings are in fastpin_apollo3.h)
FastPin<DATA_PIN>::setOutput();
- FastPin<DATA_PIN>::lo();
+ FastPin<DATA_PIN>::lo();
// Make sure the system clock is running at the full 48MHz
- am_hal_clkgen_control(AM_HAL_CLKGEN_CONTROL_SYSCLK_MAX, 0);
+ am_hal_clkgen_control(AM_HAL_CLKGEN_CONTROL_SYSCLK_MAX, 0);
// Make sure interrupts are enabled
- //am_hal_interrupt_master_enable();
+ //am_hal_interrupt_master_enable();
- // Enable SysTick Interrupts in the NVIC
- //NVIC_EnableIRQ(SysTick_IRQn);
+ // Enable SysTick Interrupts in the NVIC
+ //NVIC_EnableIRQ(SysTick_IRQn);
// SysTick is 24-bit and counts down (not up)
- // Stop the SysTick (just in case it is already running).
- // This clears the ENABLE bit in the SysTick Control and Status Register (SYST_CSR).
- // In Ambiq naming convention, the control register is SysTick->CTRL
- am_hal_systick_stop();
-
- // Call SysTick_Config
- // This is defined in core_cm4.h
- // It loads the specified LOAD value into the SysTick Reload Value Register (SYST_RVR)
- // In Ambiq naming convention, the reload register is SysTick->LOAD
- // It sets the SysTick interrupt priority
- // It clears the SysTick Current Value Register (SYST_CVR)
- // In Ambiq naming convention, the current value register is SysTick->VAL
- // Finally it sets these bits in the SysTick Control and Status Register (SYST_CSR):
- // CLKSOURCE: SysTick uses the processor clock
- // TICKINT: When the count reaches zero, the SysTick exception (interrupt) is changed to pending
- // ENABLE: Enables the counter
- // SysTick_Config returns 0 if successful. 1 indicates a failure (the LOAD value was invalid).
- SysTick_Config(0xFFFFFFUL); // The LOAD value needs to be 24-bit
+ // Stop the SysTick (just in case it is already running).
+ // This clears the ENABLE bit in the SysTick Control and Status Register (SYST_CSR).
+ // In Ambiq naming convention, the control register is SysTick->CTRL
+ am_hal_systick_stop();
+
+ // Call SysTick_Config
+ // This is defined in core_cm4.h
+ // It loads the specified LOAD value into the SysTick Reload Value Register (SYST_RVR)
+ // In Ambiq naming convention, the reload register is SysTick->LOAD
+ // It sets the SysTick interrupt priority
+ // It clears the SysTick Current Value Register (SYST_CVR)
+ // In Ambiq naming convention, the current value register is SysTick->VAL
+ // Finally it sets these bits in the SysTick Control and Status Register (SYST_CSR):
+ // CLKSOURCE: SysTick uses the processor clock
+ // TICKINT: When the count reaches zero, the SysTick exception (interrupt) is changed to pending
+ // ENABLE: Enables the counter
+ // SysTick_Config returns 0 if successful. 1 indicates a failure (the LOAD value was invalid).
+ SysTick_Config(0xFFFFFFUL); // The LOAD value needs to be 24-bit
}
virtual uint16_t getMaxRefreshRate() const { return 400; }
protected:
-
virtual void showPixels(PixelController<RGB_ORDER> & pixels) {
- mWait.wait();
+ mWait.wait();
if(!showRGBInternal(pixels)) {
- sei(); delayMicroseconds(WAIT_TIME); cli();
- showRGBInternal(pixels);
- }
- mWait.mark();
- }
+ sei(); delayMicroseconds(WAIT_TIME); cli();
+ showRGBInternal(pixels);
+ }
+ mWait.mark();
+ }
template<int BITS> __attribute__ ((always_inline)) inline static void writeBits(register uint32_t & next_mark, register uint8_t & b) {
// SysTick counts down (not up) and is 24-bit
for(register uint32_t i = BITS-1; i > 0; i--) { // We could speed this up by using Bit Banding
- while(__am_hal_systick_count() > next_mark) { ; } // Wait for the remainder of this cycle to complete
- // Calculate next_mark (the time of the next DATA_PIN transition) by subtracting T1+T2+T3
- // SysTick counts down (not up) and is 24-bit
- next_mark = (__am_hal_systick_count() - (T1+T2+T3)) & 0xFFFFFFUL;
- FastPin<DATA_PIN>::hi();
- if(b&0x80) {
- // "1 code" = longer pulse width
- while((__am_hal_systick_count() - next_mark) > (T3+(3*(F_CPU/24000000)))) { ; }
- FastPin<DATA_PIN>::lo();
- } else {
- // "0 code" = shorter pulse width
- while((__am_hal_systick_count() - next_mark) > (T2+T3+(4*(F_CPU/24000000)))) { ; }
- FastPin<DATA_PIN>::lo();
- }
- b <<= 1;
+ while(__am_hal_systick_count() > next_mark) { ; } // Wait for the remainder of this cycle to complete
+ // Calculate next_mark (the time of the next DATA_PIN transition) by subtracting T1+T2+T3
+ // SysTick counts down (not up) and is 24-bit
+ next_mark = (__am_hal_systick_count() - (T1+T2+T3)) & 0xFFFFFFUL;
+ FastPin<DATA_PIN>::hi();
+ if(b&0x80) {
+ // "1 code" = longer pulse width
+ while((__am_hal_systick_count() - next_mark) > (T3+(3*(F_CPU/24000000)))) { ; }
+ FastPin<DATA_PIN>::lo();
+ } else {
+ // "0 code" = shorter pulse width
+ while((__am_hal_systick_count() - next_mark) > (T2+T3+(4*(F_CPU/24000000)))) { ; }
+ FastPin<DATA_PIN>::lo();
+ }
+ b <<= 1;
}
- while(__am_hal_systick_count() > next_mark) { ; }// Wait for the remainder of this cycle to complete
+ while(__am_hal_systick_count() > next_mark) { ; }// Wait for the remainder of this cycle to complete
// Calculate next_mark (the time of the next DATA_PIN transition) by subtracting T1+T2+T3
// SysTick counts down (not up) and is 24-bit
next_mark = (__am_hal_systick_count() - (T1+T2+T3)) & 0xFFFFFFUL;
FastPin<DATA_PIN>::hi();
- if(b&0x80) {
+ if(b&0x80) {
// "1 code" = longer pulse width
- while((__am_hal_systick_count() - next_mark) > (T3+(2*(F_CPU/24000000)))) { ; }
- FastPin<DATA_PIN>::lo();
- } else {
+ while((__am_hal_systick_count() - next_mark) > (T3+(2*(F_CPU/24000000)))) { ; }
+ FastPin<DATA_PIN>::lo();
+ } else {
// "0 code" = shorter pulse width
- while((__am_hal_systick_count() - next_mark) > (T2+T3+(4*(F_CPU/24000000)))) { ; }
- FastPin<DATA_PIN>::lo();
- }
+ while((__am_hal_systick_count() - next_mark) > (T2+T3+(4*(F_CPU/24000000)))) { ; }
+ FastPin<DATA_PIN>::lo();
+ }
}
// This method is made static to force making register Y available to use for data on AVR - if the method is non-static, then
diff --git a/platforms/apollo3/fastpin_apollo3.h b/platforms/apollo3/fastpin_apollo3.h
index eb9e4537..28e5b967 100644
--- a/platforms/apollo3/fastpin_apollo3.h
+++ b/platforms/apollo3/fastpin_apollo3.h
@@ -11,30 +11,29 @@ FASTLED_NAMESPACE_BEGIN
#else
template<uint8_t PIN, uint8_t PAD> class _APOLLO3PIN {
-
public:
- typedef volatile uint32_t * port_ptr_t;
- typedef uint32_t port_t;
+ typedef volatile uint32_t * port_ptr_t;
+ typedef uint32_t port_t;
- inline static void setOutput() { pinMode(PIN, OUTPUT); am_hal_gpio_fastgpio_enable(PAD); }
- inline static void setInput() { am_hal_gpio_fastgpio_disable(PAD); pinMode(PIN, INPUT); }
+ inline static void setOutput() { pinMode(PIN, OUTPUT); am_hal_gpio_fastgpio_enable(PAD); }
+ inline static void setInput() { am_hal_gpio_fastgpio_disable(PAD); pinMode(PIN, INPUT); }
- inline static void hi() __attribute__ ((always_inline)) { am_hal_gpio_fastgpio_set(PAD); }
- inline static void lo() __attribute__ ((always_inline)) { am_hal_gpio_fastgpio_clr(PAD); }
- inline static void set(register port_t val) __attribute__ ((always_inline)) { if(val) { am_hal_gpio_fastgpio_set(PAD); } else { am_hal_gpio_fastgpio_clr(PAD); } }
+ inline static void hi() __attribute__ ((always_inline)) { am_hal_gpio_fastgpio_set(PAD); }
+ inline static void lo() __attribute__ ((always_inline)) { am_hal_gpio_fastgpio_clr(PAD); }
+ inline static void set(register port_t val) __attribute__ ((always_inline)) { if(val) { am_hal_gpio_fastgpio_set(PAD); } else { am_hal_gpio_fastgpio_clr(PAD); } }
- inline static void strobe() __attribute__ ((always_inline)) { toggle(); toggle(); }
+ inline static void strobe() __attribute__ ((always_inline)) { toggle(); toggle(); }
- inline static void toggle() __attribute__ ((always_inline)) { if( am_hal_gpio_fastgpio_read(PAD)) { lo(); } else { hi(); } }
+ inline static void toggle() __attribute__ ((always_inline)) { if( am_hal_gpio_fastgpio_read(PAD)) { lo(); } else { hi(); } }
- inline static void hi(register port_ptr_t port) __attribute__ ((always_inline)) { hi(); }
- inline static void lo(register port_ptr_t port) __attribute__ ((always_inline)) { lo(); }
- inline static void fastset(register port_ptr_t port, register port_t val) __attribute__ ((always_inline)) { set(val); }
+ inline static void hi(register port_ptr_t port) __attribute__ ((always_inline)) { hi(); }
+ inline static void lo(register port_ptr_t port) __attribute__ ((always_inline)) { lo(); }
+ inline static void fastset(register port_ptr_t port, register port_t val) __attribute__ ((always_inline)) { set(val); }
- inline static port_t hival() __attribute__ ((always_inline)) { return 0; }
- inline static port_t loval() __attribute__ ((always_inline)) { return 0; }
- inline static port_ptr_t port() __attribute__ ((always_inline)) { return NULL; }
- inline static port_t mask() __attribute__ ((always_inline)) { return 0; }
+ inline static port_t hival() __attribute__ ((always_inline)) { return 0; }
+ inline static port_t loval() __attribute__ ((always_inline)) { return 0; }
+ inline static port_ptr_t port() __attribute__ ((always_inline)) { return NULL; }
+ inline static port_t mask() __attribute__ ((always_inline)) { return 0; }
};
// For the Apollo3 we need to define both the pin number and the associated pad
diff --git a/platforms/arm/common/m0clockless.h b/platforms/arm/common/m0clockless.h
index d5a0cf6f..b9ed2ba5 100644
--- a/platforms/arm/common/m0clockless.h
+++ b/platforms/arm/common/m0clockless.h
@@ -2,182 +2,182 @@
#define __INC_M0_CLOCKLESS_H
struct M0ClocklessData {
- uint8_t d[3];
- uint8_t e[3];
- uint8_t adj;
- uint8_t pad;
- uint32_t s[3];
+ uint8_t d[3];
+ uint8_t e[3];
+ uint8_t adj;
+ uint8_t pad;
+ uint32_t s[3];
};
template<int HI_OFFSET, int LO_OFFSET, int T1, int T2, int T3, EOrder RGB_ORDER, int WAIT_TIME>int
showLedData(volatile uint32_t *_port, uint32_t _bitmask, const uint8_t *_leds, uint32_t num_leds, struct M0ClocklessData *pData) {
- // Lo register variables
- register uint32_t scratch=0;
- register struct M0ClocklessData *base = pData;
- register volatile uint32_t *port = _port;
- register uint32_t d=0;
- register uint32_t counter=num_leds;
- register uint32_t bn=0;
- register uint32_t b=0;
- register uint32_t bitmask = _bitmask;
-
- // high register variable
- register const uint8_t *leds = _leds;
+ // Lo register variables
+ register uint32_t scratch=0;
+ register struct M0ClocklessData *base = pData;
+ register volatile uint32_t *port = _port;
+ register uint32_t d=0;
+ register uint32_t counter=num_leds;
+ register uint32_t bn=0;
+ register uint32_t b=0;
+ register uint32_t bitmask = _bitmask;
+
+ // high register variable
+ register const uint8_t *leds = _leds;
#if (FASTLED_SCALE8_FIXED == 1)
- pData->s[0]++;
- pData->s[1]++;
- pData->s[2]++;
+ pData->s[0]++;
+ pData->s[1]++;
+ pData->s[2]++;
#endif
- asm __volatile__ (
- ///////////////////////////////////////////////////////////////////////////
- //
- // asm macro definitions - used to assemble the clockless output
- //
- ".ifnotdef fl_delay_def;"
+ asm __volatile__ (
+ ///////////////////////////////////////////////////////////////////////////
+ //
+ // asm macro definitions - used to assemble the clockless output
+ //
+ ".ifnotdef fl_delay_def;"
#ifdef FASTLED_ARM_M0_PLUS
- " .set fl_is_m0p, 1;"
- " .macro m0pad;"
- " nop;"
- " .endm;"
+ " .set fl_is_m0p, 1;"
+ " .macro m0pad;"
+ " nop;"
+ " .endm;"
#else
- " .set fl_is_m0p, 0;"
- " .macro m0pad;"
- " .endm;"
+ " .set fl_is_m0p, 0;"
+ " .macro m0pad;"
+ " .endm;"
#endif
- " .set fl_delay_def, 1;"
- " .set fl_delay_mod, 4;"
- " .if fl_is_m0p == 1;"
- " .set fl_delay_mod, 3;"
- " .endif;"
- " .macro fl_delay dtime, reg=r0;"
- " .if (\\dtime > 0);"
- " .set dcycle, (\\dtime / fl_delay_mod);"
- " .set dwork, (dcycle * fl_delay_mod);"
- " .set drem, (\\dtime - dwork);"
- " .rept (drem);"
- " nop;"
- " .endr;"
- " .if dcycle > 0;"
- " mov \\reg, #dcycle;"
- " delayloop_\\@:;"
- " sub \\reg, #1;"
- " bne delayloop_\\@;"
- " .if fl_is_m0p == 0;"
- " nop;"
- " .endif;"
- " .endif;"
- " .endif;"
- " .endm;"
-
- " .macro mod_delay dtime,b1,b2,reg;"
- " .set adj, (\\b1 + \\b2);"
- " .if adj < \\dtime;"
- " .set dtime2, (\\dtime - adj);"
- " fl_delay dtime2, \\reg;"
- " .endif;"
- " .endm;"
-
- // check the bit and drop the line low if it isn't set
- " .macro qlo4 b,bitmask,port,loff ;"
- " lsl \\b, #1 ;"
- " bcs skip_\\@ ;"
- " str \\bitmask, [\\port, \\loff] ;"
- " skip_\\@: ;"
- " m0pad;"
- " .endm ;"
-
- // set the pin hi or low (determined by the offset passed in )
- " .macro qset2 bitmask,port,loff;"
- " str \\bitmask, [\\port, \\loff];"
- " m0pad;"
- " .endm;"
-
- // Load up the next led byte to work with, put it in bn
- " .macro loadleds3 leds, bn, rled, scratch;"
- " mov \\scratch, \\leds;"
- " ldrb \\bn, [\\scratch, \\rled];"
- " .endm;"
-
- // check whether or not we should dither
- " .macro loaddither7 bn,d,base,rdither;"
- " ldrb \\d, [\\base, \\rdither];"
- " lsl \\d, #24;" //; shift high for the qadd w/bn
- " lsl \\bn, #24;" //; shift high for the qadd w/d
- " bne chkskip_\\@;" //; if bn==0, clear d;"
- " eor \\d, \\d;" //; clear d;"
- " m0pad;"
- " chkskip_\\@:;"
- " .endm;"
-
- // Do the qadd8 for dithering -- there's two versions of this. The m0 version
- // takes advantage of the 3 cycle branch to do two things after the branch,
- // while keeping timing constant. The m0+, however, branches in 2 cycles, so
- // we have to work around that a bit more. This is one of the few times
- // where the m0 will actually be _more_ efficient than the m0+
- " .macro dither5 bn,d;"
- " .syntax unified;"
- " .if fl_is_m0p == 0;"
- " adds \\bn, \\d;" // do the add
- " bcc dither5_1_\\@;"
- " mvns \\bn, \\bn;" // set the low 24bits ot 1's
- " lsls \\bn, \\bn, #24;" // move low 8 bits to the high bits
- " dither5_1_\\@:;"
- " nop;" // nop to keep timing in line
- " .else;"
- " adds \\bn, \\d;" // do the add"
- " bcc dither5_2_\\@;"
- " mvns \\bn, \\bn;" // set the low 24bits ot 1's
- " dither5_2_\\@:;"
- " bcc dither5_3_\\@;"
- " lsls \\bn, \\bn, #24;" // move low 8 bits to the high bits
- " dither5_3_\\@:;"
- " .endif;"
- " .syntax divided;"
- " .endm;"
-
- // Do our scaling
- " .macro scale4 bn, base, scale, scratch;"
- " ldr \\scratch, [\\base, \\scale];"
- " lsr \\bn, \\bn, #24;" // bring bn back down to its low 8 bits
- " mul \\bn, \\scratch;" // do the multiply
- " .endm;"
-
- // swap bn into b
- " .macro swapbbn1 b,bn;"
- " lsl \\b, \\bn, #16;" // put the 8 bits we want for output high
- " .endm;"
-
- // adjust the dithering value for the next time around (load e from memory
- // to do the math)
- " .macro adjdither7 base,d,rled,eoffset,scratch;"
- " ldrb \\d, [\\base, \\rled];"
- " ldrb \\scratch,[\\base,\\eoffset];" // load e
- " .syntax unified;"
- " subs \\d, \\scratch, \\d;" // d=e-d
- " .syntax divided;"
- " strb \\d, [\\base, \\rled];" // save d
- " .endm;"
-
- // increment the led pointer (base+6 has what we're incrementing by)
- " .macro incleds3 leds, base, scratch;"
- " ldrb \\scratch, [\\base, #6];" // load incremen
- " add \\leds, \\leds, \\scratch;" // update leds pointer
- " .endm;"
-
- // compare and loop
- " .macro cmploop5 counter,label;"
- " .syntax unified;"
- " subs \\counter, #1;"
- " .syntax divided;"
- " beq done_\\@;"
- " m0pad;"
- " b \\label;"
- " done_\\@:;"
- " .endm;"
-
- " .endif;"
- );
+ " .set fl_delay_def, 1;"
+ " .set fl_delay_mod, 4;"
+ " .if fl_is_m0p == 1;"
+ " .set fl_delay_mod, 3;"
+ " .endif;"
+ " .macro fl_delay dtime, reg=r0;"
+ " .if (\\dtime > 0);"
+ " .set dcycle, (\\dtime / fl_delay_mod);"
+ " .set dwork, (dcycle * fl_delay_mod);"
+ " .set drem, (\\dtime - dwork);"
+ " .rept (drem);"
+ " nop;"
+ " .endr;"
+ " .if dcycle > 0;"
+ " mov \\reg, #dcycle;"
+ " delayloop_\\@:;"
+ " sub \\reg, #1;"
+ " bne delayloop_\\@;"
+ " .if fl_is_m0p == 0;"
+ " nop;"
+ " .endif;"
+ " .endif;"
+ " .endif;"
+ " .endm;"
+
+ " .macro mod_delay dtime,b1,b2,reg;"
+ " .set adj, (\\b1 + \\b2);"
+ " .if adj < \\dtime;"
+ " .set dtime2, (\\dtime - adj);"
+ " fl_delay dtime2, \\reg;"
+ " .endif;"
+ " .endm;"
+
+ // check the bit and drop the line low if it isn't set
+ " .macro qlo4 b,bitmask,port,loff ;"
+ " lsl \\b, #1 ;"
+ " bcs skip_\\@ ;"
+ " str \\bitmask, [\\port, \\loff] ;"
+ " skip_\\@: ;"
+ " m0pad;"
+ " .endm ;"
+
+ // set the pin hi or low (determined by the offset passed in )
+ " .macro qset2 bitmask,port,loff;"
+ " str \\bitmask, [\\port, \\loff];"
+ " m0pad;"
+ " .endm;"
+
+ // Load up the next led byte to work with, put it in bn
+ " .macro loadleds3 leds, bn, rled, scratch;"
+ " mov \\scratch, \\leds;"
+ " ldrb \\bn, [\\scratch, \\rled];"
+ " .endm;"
+
+ // check whether or not we should dither
+ " .macro loaddither7 bn,d,base,rdither;"
+ " ldrb \\d, [\\base, \\rdither];"
+ " lsl \\d, #24;" //; shift high for the qadd w/bn
+ " lsl \\bn, #24;" //; shift high for the qadd w/d
+ " bne chkskip_\\@;" //; if bn==0, clear d;"
+ " eor \\d, \\d;" //; clear d;"
+ " m0pad;"
+ " chkskip_\\@:;"
+ " .endm;"
+
+ // Do the qadd8 for dithering -- there's two versions of this. The m0 version
+ // takes advantage of the 3 cycle branch to do two things after the branch,
+ // while keeping timing constant. The m0+, however, branches in 2 cycles, so
+ // we have to work around that a bit more. This is one of the few times
+ // where the m0 will actually be _more_ efficient than the m0+
+ " .macro dither5 bn,d;"
+ " .syntax unified;"
+ " .if fl_is_m0p == 0;"
+ " adds \\bn, \\d;" // do the add
+ " bcc dither5_1_\\@;"
+ " mvns \\bn, \\bn;" // set the low 24bits ot 1's
+ " lsls \\bn, \\bn, #24;" // move low 8 bits to the high bits
+ " dither5_1_\\@:;"
+ " nop;" // nop to keep timing in line
+ " .else;"
+ " adds \\bn, \\d;" // do the add"
+ " bcc dither5_2_\\@;"
+ " mvns \\bn, \\bn;" // set the low 24bits ot 1's
+ " dither5_2_\\@:;"
+ " bcc dither5_3_\\@;"
+ " lsls \\bn, \\bn, #24;" // move low 8 bits to the high bits
+ " dither5_3_\\@:;"
+ " .endif;"
+ " .syntax divided;"
+ " .endm;"
+
+ // Do our scaling
+ " .macro scale4 bn, base, scale, scratch;"
+ " ldr \\scratch, [\\base, \\scale];"
+ " lsr \\bn, \\bn, #24;" // bring bn back down to its low 8 bits
+ " mul \\bn, \\scratch;" // do the multiply
+ " .endm;"
+
+ // swap bn into b
+ " .macro swapbbn1 b,bn;"
+ " lsl \\b, \\bn, #16;" // put the 8 bits we want for output high
+ " .endm;"
+
+ // adjust the dithering value for the next time around (load e from memory
+ // to do the math)
+ " .macro adjdither7 base,d,rled,eoffset,scratch;"
+ " ldrb \\d, [\\base, \\rled];"
+ " ldrb \\scratch,[\\base,\\eoffset];" // load e
+ " .syntax unified;"
+ " subs \\d, \\scratch, \\d;" // d=e-d
+ " .syntax divided;"
+ " strb \\d, [\\base, \\rled];" // save d
+ " .endm;"
+
+ // increment the led pointer (base+6 has what we're incrementing by)
+ " .macro incleds3 leds, base, scratch;"
+ " ldrb \\scratch, [\\base, #6];" // load incremen
+ " add \\leds, \\leds, \\scratch;" // update leds pointer
+ " .endm;"
+
+ // compare and loop
+ " .macro cmploop5 counter,label;"
+ " .syntax unified;"
+ " subs \\counter, #1;"
+ " .syntax divided;"
+ " beq done_\\@;"
+ " m0pad;"
+ " b \\label;"
+ " done_\\@:;"
+ " .endm;"
+
+ " .endif;"
+ );
#define M0_ASM_ARGS : \
[leds] "+h" (leds), \
@@ -198,9 +198,9 @@ showLedData(volatile uint32_t *_port, uint32_t _bitmask, const uint8_t *_leds, u
[e0] "I" (3+RO(0)), \
[e1] "I" (3+RO(1)), \
[e2] "I" (3+RO(2)), \
- [scale0] "I" (4*(2+RO(0))), \
- [scale1] "I" (4*(2+RO(1))), \
- [scale2] "I" (4*(2+RO(2))), \
+ [scale0] "I" (4*(2+RO(0))), \
+ [scale1] "I" (4*(2+RO(1))), \
+ [scale2] "I" (4*(2+RO(2))), \
[T1] "I" (T1), \
[T2] "I" (T2), \
[T3] "I" (T3) \
@@ -230,157 +230,157 @@ showLedData(volatile uint32_t *_port, uint32_t _bitmask, const uint8_t *_leds, u
// track the loop outside the asm code, to allow inserting the interrupt
// overrun checks.
asm __volatile__ (
- // pre-load byte 0
- LOADLEDS3(0) LOADDITHER7(0) DITHER5 SCALE4(0) ADJDITHER7(0) SWAPBBN1
- M0_ASM_ARGS);
+ // pre-load byte 0
+ LOADLEDS3(0) LOADDITHER7(0) DITHER5 SCALE4(0) ADJDITHER7(0) SWAPBBN1
+ M0_ASM_ARGS);
do {
- asm __volatile__ (
- // Write out byte 0, prepping byte 1
- HI2 _D1 QLO4 NOTHING _D2(0) LO2 _D3(0)
- HI2 _D1 QLO4 LOADLEDS3(1) _D2(3) LO2 _D3(0)
- HI2 _D1 QLO4 LOADDITHER7(1) _D2(7) LO2 _D3(0)
- HI2 _D1 QLO4 DITHER5 _D2(5) LO2 _D3(0)
- HI2 _D1 QLO4 SCALE4(1) _D2(4) LO2 _D3(0)
- HI2 _D1 QLO4 ADJDITHER7(1) _D2(7) LO2 _D3(0)
- HI2 _D1 QLO4 NOTHING _D2(0) LO2 _D3(0)
- HI2 _D1 QLO4 SWAPBBN1 _D2(1) LO2 _D3(0)
-
- // Write out byte 1, prepping byte 2
- HI2 _D1 QLO4 NOTHING _D2(0) LO2 _D3(0)
- HI2 _D1 QLO4 LOADLEDS3(2) _D2(3) LO2 _D3(0)
- HI2 _D1 QLO4 LOADDITHER7(2) _D2(7) LO2 _D3(0)
- HI2 _D1 QLO4 DITHER5 _D2(5) LO2 _D3(0)
- HI2 _D1 QLO4 SCALE4(2) _D2(4) LO2 _D3(0)
- HI2 _D1 QLO4 ADJDITHER7(2) _D2(7) LO2 _D3(0)
- HI2 _D1 QLO4 NOTHING _D2(0) LO2 _D3(0)
- HI2 _D1 QLO4 SWAPBBN1 _D2(1) LO2 _D3(0)
-
- // Write out byte 2, prepping byte 0
- HI2 _D1 QLO4 INCLEDS3 _D2(3) LO2 _D3(0)
- HI2 _D1 QLO4 LOADLEDS3(0) _D2(3) LO2 _D3(0)
- HI2 _D1 QLO4 LOADDITHER7(0) _D2(7) LO2 _D3(0)
- HI2 _D1 QLO4 DITHER5 _D2(5) LO2 _D3(0)
- HI2 _D1 QLO4 SCALE4(0) _D2(4) LO2 _D3(0)
- HI2 _D1 QLO4 ADJDITHER7(0) _D2(7) LO2 _D3(0)
- HI2 _D1 QLO4 NOTHING _D2(0) LO2 _D3(0)
- HI2 _D1 QLO4 SWAPBBN1 _D2(1) LO2 _D3(5)
-
- M0_ASM_ARGS
- );
- SEI_CHK; INNER_SEI; --counter; CLI_CHK;
+ asm __volatile__ (
+ // Write out byte 0, prepping byte 1
+ HI2 _D1 QLO4 NOTHING _D2(0) LO2 _D3(0)
+ HI2 _D1 QLO4 LOADLEDS3(1) _D2(3) LO2 _D3(0)
+ HI2 _D1 QLO4 LOADDITHER7(1) _D2(7) LO2 _D3(0)
+ HI2 _D1 QLO4 DITHER5 _D2(5) LO2 _D3(0)
+ HI2 _D1 QLO4 SCALE4(1) _D2(4) LO2 _D3(0)
+ HI2 _D1 QLO4 ADJDITHER7(1) _D2(7) LO2 _D3(0)
+ HI2 _D1 QLO4 NOTHING _D2(0) LO2 _D3(0)
+ HI2 _D1 QLO4 SWAPBBN1 _D2(1) LO2 _D3(0)
+
+ // Write out byte 1, prepping byte 2
+ HI2 _D1 QLO4 NOTHING _D2(0) LO2 _D3(0)
+ HI2 _D1 QLO4 LOADLEDS3(2) _D2(3) LO2 _D3(0)
+ HI2 _D1 QLO4 LOADDITHER7(2) _D2(7) LO2 _D3(0)
+ HI2 _D1 QLO4 DITHER5 _D2(5) LO2 _D3(0)
+ HI2 _D1 QLO4 SCALE4(2) _D2(4) LO2 _D3(0)
+ HI2 _D1 QLO4 ADJDITHER7(2) _D2(7) LO2 _D3(0)
+ HI2 _D1 QLO4 NOTHING _D2(0) LO2 _D3(0)
+ HI2 _D1 QLO4 SWAPBBN1 _D2(1) LO2 _D3(0)
+
+ // Write out byte 2, prepping byte 0
+ HI2 _D1 QLO4 INCLEDS3 _D2(3) LO2 _D3(0)
+ HI2 _D1 QLO4 LOADLEDS3(0) _D2(3) LO2 _D3(0)
+ HI2 _D1 QLO4 LOADDITHER7(0) _D2(7) LO2 _D3(0)
+ HI2 _D1 QLO4 DITHER5 _D2(5) LO2 _D3(0)
+ HI2 _D1 QLO4 SCALE4(0) _D2(4) LO2 _D3(0)
+ HI2 _D1 QLO4 ADJDITHER7(0) _D2(7) LO2 _D3(0)
+ HI2 _D1 QLO4 NOTHING _D2(0) LO2 _D3(0)
+ HI2 _D1 QLO4 SWAPBBN1 _D2(1) LO2 _D3(5)
+
+ M0_ASM_ARGS
+ );
+ SEI_CHK; INNER_SEI; --counter; CLI_CHK;
} while(counter);
#elif (FASTLED_ALLOW_INTERRUPTS == 1)
// We're allowing interrupts - track the loop outside the asm code, and
// re-enable interrupts in between each iteration.
asm __volatile__ (
- // pre-load byte 0
- LOADLEDS3(0) LOADDITHER7(0) DITHER5 SCALE4(0) ADJDITHER7(0) SWAPBBN1
- M0_ASM_ARGS);
+ // pre-load byte 0
+ LOADLEDS3(0) LOADDITHER7(0) DITHER5 SCALE4(0) ADJDITHER7(0) SWAPBBN1
+ M0_ASM_ARGS);
do {
- asm __volatile__ (
- // Write out byte 0, prepping byte 1
- HI2 _D1 QLO4 NOTHING _D2(0) LO2 _D3(0)
- HI2 _D1 QLO4 LOADLEDS3(1) _D2(3) LO2 _D3(0)
- HI2 _D1 QLO4 LOADDITHER7(1) _D2(7) LO2 _D3(0)
- HI2 _D1 QLO4 DITHER5 _D2(5) LO2 _D3(0)
- HI2 _D1 QLO4 SCALE4(1) _D2(4) LO2 _D3(0)
- HI2 _D1 QLO4 ADJDITHER7(1) _D2(7) LO2 _D3(0)
- HI2 _D1 QLO4 NOTHING _D2(0) LO2 _D3(0)
- HI2 _D1 QLO4 SWAPBBN1 _D2(1) LO2 _D3(0)
-
- // Write out byte 1, prepping byte 2
- HI2 _D1 QLO4 NOTHING _D2(0) LO2 _D3(0)
- HI2 _D1 QLO4 LOADLEDS3(2) _D2(3) LO2 _D3(0)
- HI2 _D1 QLO4 LOADDITHER7(2) _D2(7) LO2 _D3(0)
- HI2 _D1 QLO4 DITHER5 _D2(5) LO2 _D3(0)
- HI2 _D1 QLO4 SCALE4(2) _D2(4) LO2 _D3(0)
- HI2 _D1 QLO4 ADJDITHER7(2) _D2(7) LO2 _D3(0)
- HI2 _D1 QLO4 INCLEDS3 _D2(3) LO2 _D3(0)
- HI2 _D1 QLO4 SWAPBBN1 _D2(1) LO2 _D3(0)
-
- // Write out byte 2, prepping byte 0
- HI2 _D1 QLO4 NOTHING _D2(0) LO2 _D3(0)
- HI2 _D1 QLO4 LOADLEDS3(0) _D2(3) LO2 _D3(0)
- HI2 _D1 QLO4 LOADDITHER7(0) _D2(7) LO2 _D3(0)
- HI2 _D1 QLO4 DITHER5 _D2(5) LO2 _D3(0)
- HI2 _D1 QLO4 SCALE4(0) _D2(4) LO2 _D3(0)
- HI2 _D1 QLO4 ADJDITHER7(0) _D2(7) LO2 _D3(0)
- HI2 _D1 QLO4 NOTHING _D2(0) LO2 _D3(0)
- HI2 _D1 QLO4 SWAPBBN1 _D2(1) LO2 _D3(5)
-
- M0_ASM_ARGS
- );
-
- uint32_t ticksBeforeInterrupts = SysTick->VAL;
- sei();
- --counter;
- cli();
-
- // If more than 45 uSecs have elapsed, give up on this frame and start over.
- // Note: this isn't completely correct. It's possible that more than one
- // millisecond will elapse, and so SysTick->VAL will lap
- // ticksBeforeInterrupts.
- // Note: ticksBeforeInterrupts DECREASES
- const uint32_t kTicksPerMs = VARIANT_MCK / 1000;
- const uint32_t kTicksPerUs = kTicksPerMs / 1000;
- const uint32_t kTicksIn45us = kTicksPerUs * 45;
-
- const uint32_t currentTicks = SysTick->VAL;
-
- if (ticksBeforeInterrupts < currentTicks) {
- // Timer started over
- if ((ticksBeforeInterrupts + (kTicksPerMs - currentTicks)) > kTicksIn45us) {
- return 0;
- }
- } else {
- if ((ticksBeforeInterrupts - currentTicks) > kTicksIn45us) {
- return 0;
+ asm __volatile__ (
+ // Write out byte 0, prepping byte 1
+ HI2 _D1 QLO4 NOTHING _D2(0) LO2 _D3(0)
+ HI2 _D1 QLO4 LOADLEDS3(1) _D2(3) LO2 _D3(0)
+ HI2 _D1 QLO4 LOADDITHER7(1) _D2(7) LO2 _D3(0)
+ HI2 _D1 QLO4 DITHER5 _D2(5) LO2 _D3(0)
+ HI2 _D1 QLO4 SCALE4(1) _D2(4) LO2 _D3(0)
+ HI2 _D1 QLO4 ADJDITHER7(1) _D2(7) LO2 _D3(0)
+ HI2 _D1 QLO4 NOTHING _D2(0) LO2 _D3(0)
+ HI2 _D1 QLO4 SWAPBBN1 _D2(1) LO2 _D3(0)
+
+ // Write out byte 1, prepping byte 2
+ HI2 _D1 QLO4 NOTHING _D2(0) LO2 _D3(0)
+ HI2 _D1 QLO4 LOADLEDS3(2) _D2(3) LO2 _D3(0)
+ HI2 _D1 QLO4 LOADDITHER7(2) _D2(7) LO2 _D3(0)
+ HI2 _D1 QLO4 DITHER5 _D2(5) LO2 _D3(0)
+ HI2 _D1 QLO4 SCALE4(2) _D2(4) LO2 _D3(0)
+ HI2 _D1 QLO4 ADJDITHER7(2) _D2(7) LO2 _D3(0)
+ HI2 _D1 QLO4 INCLEDS3 _D2(3) LO2 _D3(0)
+ HI2 _D1 QLO4 SWAPBBN1 _D2(1) LO2 _D3(0)
+
+ // Write out byte 2, prepping byte 0
+ HI2 _D1 QLO4 NOTHING _D2(0) LO2 _D3(0)
+ HI2 _D1 QLO4 LOADLEDS3(0) _D2(3) LO2 _D3(0)
+ HI2 _D1 QLO4 LOADDITHER7(0) _D2(7) LO2 _D3(0)
+ HI2 _D1 QLO4 DITHER5 _D2(5) LO2 _D3(0)
+ HI2 _D1 QLO4 SCALE4(0) _D2(4) LO2 _D3(0)
+ HI2 _D1 QLO4 ADJDITHER7(0) _D2(7) LO2 _D3(0)
+ HI2 _D1 QLO4 NOTHING _D2(0) LO2 _D3(0)
+ HI2 _D1 QLO4 SWAPBBN1 _D2(1) LO2 _D3(5)
+
+ M0_ASM_ARGS
+ );
+
+ uint32_t ticksBeforeInterrupts = SysTick->VAL;
+ sei();
+ --counter;
+ cli();
+
+ // If more than 45 uSecs have elapsed, give up on this frame and start over.
+ // Note: this isn't completely correct. It's possible that more than one
+ // millisecond will elapse, and so SysTick->VAL will lap
+ // ticksBeforeInterrupts.
+ // Note: ticksBeforeInterrupts DECREASES
+ const uint32_t kTicksPerMs = VARIANT_MCK / 1000;
+ const uint32_t kTicksPerUs = kTicksPerMs / 1000;
+ const uint32_t kTicksIn45us = kTicksPerUs * 45;
+
+ const uint32_t currentTicks = SysTick->VAL;
+
+ if (ticksBeforeInterrupts < currentTicks) {
+ // Timer started over
+ if ((ticksBeforeInterrupts + (kTicksPerMs - currentTicks)) > kTicksIn45us) {
+ return 0;
+ }
+ } else {
+ if ((ticksBeforeInterrupts - currentTicks) > kTicksIn45us) {
+ return 0;
+ }
}
- }
} while(counter);
#else
// We're not allowing interrupts - run the entire loop in asm to keep things
// as tight as possible. In an ideal world, we should be pushing out ws281x
// leds (or other 3-wire leds) with zero gaps between pixels.
asm __volatile__ (
- // pre-load byte 0
- LOADLEDS3(0) LOADDITHER7(0) DITHER5 SCALE4(0) ADJDITHER7(0) SWAPBBN1
-
- // loop over writing out the data
- LOOP
- // Write out byte 0, prepping byte 1
- HI2 _D1 QLO4 NOTHING _D2(0) LO2 _D3(0)
- HI2 _D1 QLO4 LOADLEDS3(1) _D2(3) LO2 _D3(0)
- HI2 _D1 QLO4 LOADDITHER7(1) _D2(7) LO2 _D3(0)
- HI2 _D1 QLO4 DITHER5 _D2(5) LO2 _D3(0)
- HI2 _D1 QLO4 SCALE4(1) _D2(4) LO2 _D3(0)
- HI2 _D1 QLO4 ADJDITHER7(1) _D2(7) LO2 _D3(0)
- HI2 _D1 QLO4 NOTHING _D2(0) LO2 _D3(0)
- HI2 _D1 QLO4 SWAPBBN1 _D2(1) LO2 _D3(0)
-
- // Write out byte 1, prepping byte 2
- HI2 _D1 QLO4 NOTHING _D2(0) LO2 _D3(0)
- HI2 _D1 QLO4 LOADLEDS3(2) _D2(3) LO2 _D3(0)
- HI2 _D1 QLO4 LOADDITHER7(2) _D2(7) LO2 _D3(0)
- HI2 _D1 QLO4 DITHER5 _D2(5) LO2 _D3(0)
- HI2 _D1 QLO4 SCALE4(2) _D2(4) LO2 _D3(0)
- HI2 _D1 QLO4 ADJDITHER7(2) _D2(7) LO2 _D3(0)
- HI2 _D1 QLO4 INCLEDS3 _D2(3) LO2 _D3(0)
- HI2 _D1 QLO4 SWAPBBN1 _D2(1) LO2 _D3(0)
-
- // Write out byte 2, prepping byte 0
- HI2 _D1 QLO4 NOTHING _D2(0) LO2 _D3(0)
- HI2 _D1 QLO4 LOADLEDS3(0) _D2(3) LO2 _D3(0)
- HI2 _D1 QLO4 LOADDITHER7(0) _D2(7) LO2 _D3(0)
- HI2 _D1 QLO4 DITHER5 _D2(5) LO2 _D3(0)
- HI2 _D1 QLO4 SCALE4(0) _D2(4) LO2 _D3(0)
- HI2 _D1 QLO4 ADJDITHER7(0) _D2(7) LO2 _D3(0)
- HI2 _D1 QLO4 NOTHING _D2(0) LO2 _D3(0)
- HI2 _D1 QLO4 SWAPBBN1 _D2(1) LO2 _D3(5) CMPLOOP5
-
- M0_ASM_ARGS
+ // pre-load byte 0
+ LOADLEDS3(0) LOADDITHER7(0) DITHER5 SCALE4(0) ADJDITHER7(0) SWAPBBN1
+
+ // loop over writing out the data
+ LOOP
+ // Write out byte 0, prepping byte 1
+ HI2 _D1 QLO4 NOTHING _D2(0) LO2 _D3(0)
+ HI2 _D1 QLO4 LOADLEDS3(1) _D2(3) LO2 _D3(0)
+ HI2 _D1 QLO4 LOADDITHER7(1) _D2(7) LO2 _D3(0)
+ HI2 _D1 QLO4 DITHER5 _D2(5) LO2 _D3(0)
+ HI2 _D1 QLO4 SCALE4(1) _D2(4) LO2 _D3(0)
+ HI2 _D1 QLO4 ADJDITHER7(1) _D2(7) LO2 _D3(0)
+ HI2 _D1 QLO4 NOTHING _D2(0) LO2 _D3(0)
+ HI2 _D1 QLO4 SWAPBBN1 _D2(1) LO2 _D3(0)
+
+ // Write out byte 1, prepping byte 2
+ HI2 _D1 QLO4 NOTHING _D2(0) LO2 _D3(0)
+ HI2 _D1 QLO4 LOADLEDS3(2) _D2(3) LO2 _D3(0)
+ HI2 _D1 QLO4 LOADDITHER7(2) _D2(7) LO2 _D3(0)
+ HI2 _D1 QLO4 DITHER5 _D2(5) LO2 _D3(0)
+ HI2 _D1 QLO4 SCALE4(2) _D2(4) LO2 _D3(0)
+ HI2 _D1 QLO4 ADJDITHER7(2) _D2(7) LO2 _D3(0)
+ HI2 _D1 QLO4 INCLEDS3 _D2(3) LO2 _D3(0)
+ HI2 _D1 QLO4 SWAPBBN1 _D2(1) LO2 _D3(0)
+
+ // Write out byte 2, prepping byte 0
+ HI2 _D1 QLO4 NOTHING _D2(0) LO2 _D3(0)
+ HI2 _D1 QLO4 LOADLEDS3(0) _D2(3) LO2 _D3(0)
+ HI2 _D1 QLO4 LOADDITHER7(0) _D2(7) LO2 _D3(0)
+ HI2 _D1 QLO4 DITHER5 _D2(5) LO2 _D3(0)
+ HI2 _D1 QLO4 SCALE4(0) _D2(4) LO2 _D3(0)
+ HI2 _D1 QLO4 ADJDITHER7(0) _D2(7) LO2 _D3(0)
+ HI2 _D1 QLO4 NOTHING _D2(0) LO2 _D3(0)
+ HI2 _D1 QLO4 SWAPBBN1 _D2(1) LO2 _D3(5) CMPLOOP5
+
+ M0_ASM_ARGS
);
#endif
return num_leds;
diff --git a/platforms/arm/d21/clockless_arm_d21.h b/platforms/arm/d21/clockless_arm_d21.h
index 366a6bde..16526ed6 100644
--- a/platforms/arm/d21/clockless_arm_d21.h
+++ b/platforms/arm/d21/clockless_arm_d21.h
@@ -7,51 +7,51 @@ FASTLED_NAMESPACE_BEGIN
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 CPixelLEDController<RGB_ORDER> {
- typedef typename FastPinBB<DATA_PIN>::port_ptr_t data_ptr_t;
- typedef typename FastPinBB<DATA_PIN>::port_t data_t;
+ typedef typename FastPinBB<DATA_PIN>::port_ptr_t data_ptr_t;
+ typedef typename FastPinBB<DATA_PIN>::port_t data_t;
+
+ data_t mPinMask;
+ data_ptr_t mPort;
+ CMinWait<WAIT_TIME> mWait;
- data_t mPinMask;
- data_ptr_t mPort;
- CMinWait<WAIT_TIME> mWait;
public:
- virtual void init() {
- FastPinBB<DATA_PIN>::setOutput();
- mPinMask = FastPinBB<DATA_PIN>::mask();
- mPort = FastPinBB<DATA_PIN>::port();
- }
-
- virtual uint16_t getMaxRefreshRate() const { return 400; }
-
- virtual void showPixels(PixelController<RGB_ORDER> & pixels) {
- mWait.wait();
- cli();
- if(!showRGBInternal(pixels)) {
- sei(); delayMicroseconds(WAIT_TIME); cli();
- showRGBInternal(pixels);
+ virtual void init() {
+ FastPinBB<DATA_PIN>::setOutput();
+ mPinMask = FastPinBB<DATA_PIN>::mask();
+ mPort = FastPinBB<DATA_PIN>::port();
+ }
+
+ virtual uint16_t getMaxRefreshRate() const { return 400; }
+
+ virtual void showPixels(PixelController<RGB_ORDER> & pixels) {
+ mWait.wait();
+ cli();
+ if(!showRGBInternal(pixels)) {
+ sei(); delayMicroseconds(WAIT_TIME); cli();
+ showRGBInternal(pixels);
+ }
+ sei();
+ mWait.mark();
}
- 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> pixels) {
- struct M0ClocklessData data;
- data.d[0] = pixels.d[0];
- data.d[1] = pixels.d[1];
- data.d[2] = pixels.d[2];
- data.s[0] = pixels.mScale[0];
- data.s[1] = pixels.mScale[1];
- data.s[2] = pixels.mScale[2];
- data.e[0] = pixels.e[0];
- data.e[1] = pixels.e[1];
- data.e[2] = pixels.e[2];
- data.adj = pixels.mAdvance;
-
- typename FastPin<DATA_PIN>::port_ptr_t portBase = FastPin<DATA_PIN>::port();
- return showLedData<8,4,T1,T2,T3,RGB_ORDER, WAIT_TIME>(portBase, FastPin<DATA_PIN>::mask(), pixels.mData, pixels.mLen, &data);
- }
+ // 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) {
+ struct M0ClocklessData data;
+ data.d[0] = pixels.d[0];
+ data.d[1] = pixels.d[1];
+ data.d[2] = pixels.d[2];
+ data.s[0] = pixels.mScale[0];
+ data.s[1] = pixels.mScale[1];
+ data.s[2] = pixels.mScale[2];
+ data.e[0] = pixels.e[0];
+ data.e[1] = pixels.e[1];
+ data.e[2] = pixels.e[2];
+ data.adj = pixels.mAdvance;
+
+ typename FastPin<DATA_PIN>::port_ptr_t portBase = FastPin<DATA_PIN>::port();
+ return showLedData<8,4,T1,T2,T3,RGB_ORDER, WAIT_TIME>(portBase, FastPin<DATA_PIN>::mask(), pixels.mData, pixels.mLen, &data);
+ }
};
diff --git a/platforms/arm/d21/fastpin_arm_d21.h b/platforms/arm/d21/fastpin_arm_d21.h
index cbfe5dbb..9f9ef869 100644
--- a/platforms/arm/d21/fastpin_arm_d21.h
+++ b/platforms/arm/d21/fastpin_arm_d21.h
@@ -17,41 +17,41 @@ FASTLED_NAMESPACE_BEGIN
template<uint8_t PIN, uint8_t _BIT, uint32_t _MASK, int _GRP> class _ARMPIN {
public:
- typedef volatile uint32_t * port_ptr_t;
- typedef uint32_t port_t;
-
- #if 0
- inline static void setOutput() {
- if(_BIT<8) {
- _CRL::r() = (_CRL::r() & (0xF << (_BIT*4)) | (0x1 << (_BIT*4));
- } else {
- _CRH::r() = (_CRH::r() & (0xF << ((_BIT-8)*4))) | (0x1 << ((_BIT-8)*4));
+ typedef volatile uint32_t * port_ptr_t;
+ typedef uint32_t port_t;
+
+ #if 0
+ inline static void setOutput() {
+ if(_BIT<8) {
+ _CRL::r() = (_CRL::r() & (0xF << (_BIT*4)) | (0x1 << (_BIT*4));
+ } else {
+ _CRH::r() = (_CRH::r() & (0xF << ((_BIT-8)*4))) | (0x1 << ((_BIT-8)*4));
+ }
}
- }
- inline static void setInput() { /* TODO */ } // TODO: preform MUX config { _PDDR::r() &= ~_MASK; }
- #endif
+ inline static void setInput() { /* TODO */ } // TODO: preform MUX config { _PDDR::r() &= ~_MASK; }
+ #endif
- inline static void setOutput() { pinMode(PIN, OUTPUT); } // TODO: perform MUX config { _PDDR::r() |= _MASK; }
- inline static void setInput() { pinMode(PIN, INPUT); } // TODO: preform MUX config { _PDDR::r() &= ~_MASK; }
+ inline static void setOutput() { pinMode(PIN, OUTPUT); } // TODO: perform MUX config { _PDDR::r() |= _MASK; }
+ inline static void setInput() { pinMode(PIN, INPUT); } // TODO: preform MUX config { _PDDR::r() &= ~_MASK; }
- inline static void hi() __attribute__ ((always_inline)) { PORT_IOBUS->Group[_GRP].OUTSET.reg = _MASK; }
- inline static void lo() __attribute__ ((always_inline)) { PORT_IOBUS->Group[_GRP].OUTCLR.reg = _MASK; }
- inline static void set(register port_t val) __attribute__ ((always_inline)) { PORT_IOBUS->Group[_GRP].OUT.reg = val; }
+ inline static void hi() __attribute__ ((always_inline)) { PORT_IOBUS->Group[_GRP].OUTSET.reg = _MASK; }
+ inline static void lo() __attribute__ ((always_inline)) { PORT_IOBUS->Group[_GRP].OUTCLR.reg = _MASK; }
+ inline static void set(register port_t val) __attribute__ ((always_inline)) { PORT_IOBUS->Group[_GRP].OUT.reg = val; }
- inline static void strobe() __attribute__ ((always_inline)) { toggle(); toggle(); }
+ inline static void strobe() __attribute__ ((always_inline)) { toggle(); toggle(); }
- inline static void toggle() __attribute__ ((always_inline)) { PORT_IOBUS->Group[_GRP].OUTTGL.reg = _MASK; }
+ inline static void toggle() __attribute__ ((always_inline)) { PORT_IOBUS->Group[_GRP].OUTTGL.reg = _MASK; }
- inline static void hi(register port_ptr_t port) __attribute__ ((always_inline)) { hi(); }
- inline static void lo(register port_ptr_t port) __attribute__ ((always_inline)) { lo(); }
- inline static void fastset(register port_ptr_t port, register port_t val) __attribute__ ((always_inline)) { *port = val; }
+ inline static void hi(register port_ptr_t port) __attribute__ ((always_inline)) { hi(); }
+ inline static void lo(register port_ptr_t port) __attribute__ ((always_inline)) { lo(); }
+ inline static void fastset(register port_ptr_t port, register port_t val) __attribute__ ((always_inline)) { *port = val; }
- inline static port_t hival() __attribute__ ((always_inline)) { return PORT_IOBUS->Group[_GRP].OUT.reg | _MASK; }
- inline static port_t loval() __attribute__ ((always_inline)) { return PORT_IOBUS->Group[_GRP].OUT.reg & ~_MASK; }
- inline static port_ptr_t port() __attribute__ ((always_inline)) { return &PORT_IOBUS->Group[_GRP].OUT.reg; }
- inline static port_ptr_t sport() __attribute__ ((always_inline)) { return &PORT_IOBUS->Group[_GRP].OUTSET.reg; }
- inline static port_ptr_t cport() __attribute__ ((always_inline)) { return &PORT_IOBUS->Group[_GRP].OUTCLR.reg; }
- inline static port_t mask() __attribute__ ((always_inline)) { return _MASK; }
+ inline static port_t hival() __attribute__ ((always_inline)) { return PORT_IOBUS->Group[_GRP].OUT.reg | _MASK; }
+ inline static port_t loval() __attribute__ ((always_inline)) { return PORT_IOBUS->Group[_GRP].OUT.reg & ~_MASK; }
+ inline static port_ptr_t port() __attribute__ ((always_inline)) { return &PORT_IOBUS->Group[_GRP].OUT.reg; }
+ inline static port_ptr_t sport() __attribute__ ((always_inline)) { return &PORT_IOBUS->Group[_GRP].OUTSET.reg; }
+ inline static port_ptr_t cport() __attribute__ ((always_inline)) { return &PORT_IOBUS->Group[_GRP].OUTCLR.reg; }
+ inline static port_t mask() __attribute__ ((always_inline)) { return _MASK; }
};
#define _R(T) struct __gen_struct_ ## T
diff --git a/platforms/arm/d51/clockless_arm_d51.h b/platforms/arm/d51/clockless_arm_d51.h
index 0c3f6d4d..a5c7f680 100644
--- a/platforms/arm/d51/clockless_arm_d51.h
+++ b/platforms/arm/d51/clockless_arm_d51.h
@@ -22,6 +22,7 @@ class ClocklessController : public CPixelLEDController<RGB_ORDER> {
data_t mPinMask;
data_ptr_t mPort;
CMinWait<WAIT_TIME> mWait;
+
public:
virtual void init() {
FastPin<DATA_PIN>::setOutput();
@@ -32,15 +33,14 @@ public:
virtual uint16_t getMaxRefreshRate() const { return 400; }
protected:
-
virtual void showPixels(PixelController<RGB_ORDER> & pixels) {
- mWait.wait();
+ mWait.wait();
if(!showRGBInternal(pixels)) {
- sei(); delayMicroseconds(WAIT_TIME); cli();
- showRGBInternal(pixels);
- }
- mWait.mark();
- }
+ sei(); delayMicroseconds(WAIT_TIME); cli();
+ 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/d51/fastpin_arm_d51.h b/platforms/arm/d51/fastpin_arm_d51.h
index dd40dbfd..9d31cedb 100644
--- a/platforms/arm/d51/fastpin_arm_d51.h
+++ b/platforms/arm/d51/fastpin_arm_d51.h
@@ -17,41 +17,41 @@ FASTLED_NAMESPACE_BEGIN
template<uint8_t PIN, uint8_t _BIT, uint32_t _MASK, int _GRP> class _ARMPIN {
public:
- typedef volatile uint32_t * port_ptr_t;
- typedef uint32_t port_t;
-
- #if 0
- inline static void setOutput() {
- if(_BIT<8) {
- _CRL::r() = (_CRL::r() & (0xF << (_BIT*4)) | (0x1 << (_BIT*4));
- } else {
- _CRH::r() = (_CRH::r() & (0xF << ((_BIT-8)*4))) | (0x1 << ((_BIT-8)*4));
+ typedef volatile uint32_t * port_ptr_t;
+ typedef uint32_t port_t;
+
+ #if 0
+ inline static void setOutput() {
+ if(_BIT<8) {
+ _CRL::r() = (_CRL::r() & (0xF << (_BIT*4)) | (0x1 << (_BIT*4));
+ } else {
+ _CRH::r() = (_CRH::r() & (0xF << ((_BIT-8)*4))) | (0x1 << ((_BIT-8)*4));
+ }
}
- }
- inline static void setInput() { /* TODO */ } // TODO: preform MUX config { _PDDR::r() &= ~_MASK; }
- #endif
+ inline static void setInput() { /* TODO */ } // TODO: preform MUX config { _PDDR::r() &= ~_MASK; }
+ #endif
- inline static void setOutput() { pinMode(PIN, OUTPUT); } // TODO: perform MUX config { _PDDR::r() |= _MASK; }
- inline static void setInput() { pinMode(PIN, INPUT); } // TODO: preform MUX config { _PDDR::r() &= ~_MASK; }
+ inline static void setOutput() { pinMode(PIN, OUTPUT); } // TODO: perform MUX config { _PDDR::r() |= _MASK; }
+ inline static void setInput() { pinMode(PIN, INPUT); } // TODO: preform MUX config { _PDDR::r() &= ~_MASK; }
- inline static void hi() __attribute__ ((always_inline)) { PORT->Group[_GRP].OUTSET.reg = _MASK; }
- inline static void lo() __attribute__ ((always_inline)) { PORT->Group[_GRP].OUTCLR.reg = _MASK; }
- inline static void set(register port_t val) __attribute__ ((always_inline)) { PORT->Group[_GRP].OUT.reg = val; }
+ inline static void hi() __attribute__ ((always_inline)) { PORT->Group[_GRP].OUTSET.reg = _MASK; }
+ inline static void lo() __attribute__ ((always_inline)) { PORT->Group[_GRP].OUTCLR.reg = _MASK; }
+ inline static void set(register port_t val) __attribute__ ((always_inline)) { PORT->Group[_GRP].OUT.reg = val; }
- inline static void strobe() __attribute__ ((always_inline)) { toggle(); toggle(); }
+ inline static void strobe() __attribute__ ((always_inline)) { toggle(); toggle(); }
- inline static void toggle() __attribute__ ((always_inline)) { PORT->Group[_GRP].OUTTGL.reg = _MASK; }
+ inline static void toggle() __attribute__ ((always_inline)) { PORT->Group[_GRP].OUTTGL.reg = _MASK; }
- inline static void hi(register port_ptr_t port) __attribute__ ((always_inline)) { hi(); }
- inline static void lo(register port_ptr_t port) __attribute__ ((always_inline)) { lo(); }
- inline static void fastset(register port_ptr_t port, register port_t val) __attribute__ ((always_inline)) { *port = val; }
+ inline static void hi(register port_ptr_t port) __attribute__ ((always_inline)) { hi(); }
+ inline static void lo(register port_ptr_t port) __attribute__ ((always_inline)) { lo(); }
+ inline static void fastset(register port_ptr_t port, register port_t val) __attribute__ ((always_inline)) { *port = val; }
- inline static port_t hival() __attribute__ ((always_inline)) { return PORT->Group[_GRP].OUT.reg | _MASK; }
- inline static port_t loval() __attribute__ ((always_inline)) { return PORT->Group[_GRP].OUT.reg & ~_MASK; }
- inline static port_ptr_t port() __attribute__ ((always_inline)) { return &PORT->Group[_GRP].OUT.reg; }
- inline static port_ptr_t sport() __attribute__ ((always_inline)) { return &PORT->Group[_GRP].OUTSET.reg; }
- inline static port_ptr_t cport() __attribute__ ((always_inline)) { return &PORT->Group[_GRP].OUTCLR.reg; }
- inline static port_t mask() __attribute__ ((always_inline)) { return _MASK; }
+ inline static port_t hival() __attribute__ ((always_inline)) { return PORT->Group[_GRP].OUT.reg | _MASK; }
+ inline static port_t loval() __attribute__ ((always_inline)) { return PORT->Group[_GRP].OUT.reg & ~_MASK; }
+ inline static port_ptr_t port() __attribute__ ((always_inline)) { return &PORT->Group[_GRP].OUT.reg; }
+ inline static port_ptr_t sport() __attribute__ ((always_inline)) { return &PORT->Group[_GRP].OUTSET.reg; }
+ inline static port_ptr_t cport() __attribute__ ((always_inline)) { return &PORT->Group[_GRP].OUTCLR.reg; }
+ inline static port_t mask() __attribute__ ((always_inline)) { return _MASK; }
};
#define _R(T) struct __gen_struct_ ## T
@@ -130,7 +130,6 @@ _FL_DEFPIN(23, 22, 1); _FL_DEFPIN(24, 23, 1); _FL_DEFPIN(25, 17, 0);
#endif
-
#endif // FASTLED_FORCE_SOFTWARE_PINS
FASTLED_NAMESPACE_END
diff --git a/platforms/arm/k20/clockless_arm_k20.h b/platforms/arm/k20/clockless_arm_k20.h
index bc2090b3..87e86345 100644
--- a/platforms/arm/k20/clockless_arm_k20.h
+++ b/platforms/arm/k20/clockless_arm_k20.h
@@ -17,6 +17,7 @@ class ClocklessController : public CPixelLEDController<RGB_ORDER> {
data_t mPinMask;
data_ptr_t mPort;
CMinWait<WAIT_TIME> mWait;
+
public:
virtual void init() {
FastPin<DATA_PIN>::setOutput();
@@ -27,15 +28,14 @@ public:
virtual uint16_t getMaxRefreshRate() const { return 400; }
protected:
-
virtual void showPixels(PixelController<RGB_ORDER> & pixels) {
- mWait.wait();
+ mWait.wait();
if(!showRGBInternal(pixels)) {
- sei(); delayMicroseconds(WAIT_TIME); cli();
- showRGBInternal(pixels);
- }
- mWait.mark();
- }
+ sei(); delayMicroseconds(WAIT_TIME); cli();
+ 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 66c6191c..c0d838d2 100644
--- a/platforms/arm/k20/clockless_block_arm_k20.h
+++ b/platforms/arm/k20/clockless_block_arm_k20.h
@@ -27,6 +27,7 @@ class InlineBlockClocklessController : public CPixelLEDController<RGB_ORDER, LAN
data_t mPinMask;
data_ptr_t mPort;
CMinWait<WAIT_TIME> mWait;
+
public:
virtual int size() { return CLEDController::size() * LANES; }
@@ -197,6 +198,7 @@ class SixteenWayInlineBlockClocklessController : public CPixelLEDController<RGB_
data_t mPinMask;
data_ptr_t mPort;
CMinWait<WAIT_TIME> mWait;
+
public:
virtual void init() {
static_assert(LANES <= 16, "Maximum of 16 lanes for Teensy parallel controllers!");
diff --git a/platforms/arm/k20/fastspi_arm_k20.h b/platforms/arm/k20/fastspi_arm_k20.h
index 05123243..cbb72a9f 100644
--- a/platforms/arm/k20/fastspi_arm_k20.h
+++ b/platforms/arm/k20/fastspi_arm_k20.h
@@ -29,6 +29,7 @@ template<int VAL, int BIT> class BitWork {
public:
static int highestBit() __attribute__((always_inline)) { return (VAL & 1 << BIT) ? BIT : BitWork<VAL, BIT-1>::highestBit(); }
};
+
template<int VAL> class BitWork<VAL, 0> {
public:
static int highestBit() __attribute__((always_inline)) { return 0; }
@@ -246,7 +247,6 @@ public:
ARMHardwareSPIOutput(Selectable *pSelect) { m_pSelect = pSelect; }
void setSelect(Selectable *pSelect) { m_pSelect = pSelect; }
-
void init() {
// set the pins to output
FastPin<_DATA_PIN>::setOutput();
@@ -316,8 +316,8 @@ public:
if(WAIT_STATE == PRE) { wait(); }
cli();
SPIX.PUSHR = ((LAST_STATE == LAST) ? SPI_PUSHR_EOQ : 0) |
- ((CONT_STATE == CONT) ? SPI_PUSHR_CONT : 0) |
- SPI_PUSHR_CTAS(1) | (w & 0xFFFF);
+ ((CONT_STATE == CONT) ? SPI_PUSHR_CONT : 0) |
+ SPI_PUSHR_CTAS(1) | (w & 0xFFFF);
SPIX.SR |= SPI_SR_TCF;
sei();
if(WAIT_STATE == POST) { wait(); }
@@ -327,8 +327,8 @@ public:
if(WAIT_STATE == PRE) { wait(); }
cli();
SPIX.PUSHR = ((LAST_STATE == LAST) ? SPI_PUSHR_EOQ : 0) |
- ((CONT_STATE == CONT) ? SPI_PUSHR_CONT : 0) |
- SPI_PUSHR_CTAS(0) | (b & 0xFF);
+ ((CONT_STATE == CONT) ? SPI_PUSHR_CONT : 0) |
+ SPI_PUSHR_CTAS(0) | (b & 0xFF);
SPIX.SR |= SPI_SR_TCF;
sei();
if(WAIT_STATE == POST) { wait(); }
diff --git a/platforms/arm/k20/octows2811_controller.h b/platforms/arm/k20/octows2811_controller.h
index 84c28667..749e18e1 100644
--- a/platforms/arm/k20/octows2811_controller.h
+++ b/platforms/arm/k20/octows2811_controller.h
@@ -9,54 +9,54 @@ FASTLED_NAMESPACE_BEGIN
template<EOrder RGB_ORDER = GRB, uint8_t CHIP = WS2811_800kHz>
class COctoWS2811Controller : public CPixelLEDController<RGB_ORDER, 8, 0xFF> {
- OctoWS2811 *pocto;
- uint8_t *drawbuffer,*framebuffer;
+ OctoWS2811 *pocto;
+ uint8_t *drawbuffer,*framebuffer;
- void _init(int nLeds) {
- if(pocto == NULL) {
- drawbuffer = (uint8_t*)malloc(nLeds * 8 * 3);
- framebuffer = (uint8_t*)malloc(nLeds * 8 * 3);
+ void _init(int nLeds) {
+ if(pocto == NULL) {
+ drawbuffer = (uint8_t*)malloc(nLeds * 8 * 3);
+ framebuffer = (uint8_t*)malloc(nLeds * 8 * 3);
- // byte ordering is handled in show by the pixel controller
- int config = WS2811_RGB;
- config |= CHIP;
+ // byte ordering is handled in show by the pixel controller
+ int config = WS2811_RGB;
+ config |= CHIP;
- pocto = new OctoWS2811(nLeds, framebuffer, drawbuffer, config);
+ pocto = new OctoWS2811(nLeds, framebuffer, drawbuffer, config);
- pocto->begin();
+ pocto->begin();
+ }
}
- }
+
public:
- COctoWS2811Controller() { pocto = NULL; }
- virtual int size() { return CLEDController::size() * 8; }
-
- virtual void init() { /* do nothing yet */ }
-
- typedef union {
- uint8_t bytes[8];
- uint32_t raw[2];
- } Lines;
-
- virtual void showPixels(PixelController<RGB_ORDER, 8, 0xFF> & pixels) {
- _init(pixels.size());
-
- uint8_t *pData = drawbuffer;
- while(pixels.has(1)) {
- Lines b;
-
- for(int i = 0; i < 8; i++) { b.bytes[i] = pixels.loadAndScale0(i); }
- transpose8x1_MSB(b.bytes,pData); pData += 8;
- for(int i = 0; i < 8; i++) { b.bytes[i] = pixels.loadAndScale1(i); }
- transpose8x1_MSB(b.bytes,pData); pData += 8;
- for(int i = 0; i < 8; i++) { b.bytes[i] = pixels.loadAndScale2(i); }
- transpose8x1_MSB(b.bytes,pData); pData += 8;
- pixels.stepDithering();
- pixels.advanceData();
+ COctoWS2811Controller() { pocto = NULL; }
+ virtual int size() { return CLEDController::size() * 8; }
+
+ virtual void init() { /* do nothing yet */ }
+
+ typedef union {
+ uint8_t bytes[8];
+ uint32_t raw[2];
+ } Lines;
+
+ virtual void showPixels(PixelController<RGB_ORDER, 8, 0xFF> & pixels) {
+ _init(pixels.size());
+
+ uint8_t *pData = drawbuffer;
+ while(pixels.has(1)) {
+ Lines b;
+
+ for(int i = 0; i < 8; i++) { b.bytes[i] = pixels.loadAndScale0(i); }
+ transpose8x1_MSB(b.bytes,pData); pData += 8;
+ for(int i = 0; i < 8; i++) { b.bytes[i] = pixels.loadAndScale1(i); }
+ transpose8x1_MSB(b.bytes,pData); pData += 8;
+ for(int i = 0; i < 8; i++) { b.bytes[i] = pixels.loadAndScale2(i); }
+ transpose8x1_MSB(b.bytes,pData); pData += 8;
+ pixels.stepDithering();
+ pixels.advanceData();
+ }
+
+ pocto->show();
}
-
- pocto->show();
- }
-
};
FASTLED_NAMESPACE_END
diff --git a/platforms/arm/k20/smartmatrix_t3.h b/platforms/arm/k20/smartmatrix_t3.h
index 95af46cf..c9747f0b 100644
--- a/platforms/arm/k20/smartmatrix_t3.h
+++ b/platforms/arm/k20/smartmatrix_t3.h
@@ -10,42 +10,41 @@ extern SmartMatrix *pSmartMatrix;
// note - dmx simple must be included before FastSPI for this code to be enabled
class CSmartMatrixController : public CPixelLEDController<RGB_ORDER> {
- SmartMatrix matrix;
+ SmartMatrix matrix;
public:
- // initialize the LED controller
- virtual void init() {
- // Initialize 32x32 LED Matrix
- matrix.begin();
- matrix.setBrightness(255);
- matrix.setColorCorrection(ccNone);
-
- // Clear screen
- clearLeds(0);
- matrix.swapBuffers();
- pSmartMatrix = &matrix;
- }
-
- virtual void showPixels(PixelController<RGB_ORDER> & pixels) {
- if(SMART_MATRIX_CAN_TRIPLE_BUFFER) {
- rgb24 *md = matrix.getRealBackBuffer();
- } else {
- rgb24 *md = matrix.backBuffer();
+ // initialize the LED controller
+ virtual void init() {
+ // Initialize 32x32 LED Matrix
+ matrix.begin();
+ matrix.setBrightness(255);
+ matrix.setColorCorrection(ccNone);
+
+ // Clear screen
+ clearLeds(0);
+ matrix.swapBuffers();
+ pSmartMatrix = &matrix;
}
- while(pixels.has(1)) {
- md->red = pixels.loadAndScale0();
- md->green = pixels.loadAndScale1();
- md->blue = pixels.loadAndScale2();
- md++;
- pixels.advanceData();
- pixels.stepDithering();
- }
- matrix.swapBuffers();
- if(SMART_MATRIX_CAN_TRIPLE_BUFFER && pixels.advanceBy() > 0) {
- matrix.setBackBuffer(pixels.mData);
- }
- }
+ virtual void showPixels(PixelController<RGB_ORDER> & pixels) {
+ if(SMART_MATRIX_CAN_TRIPLE_BUFFER) {
+ rgb24 *md = matrix.getRealBackBuffer();
+ } else {
+ rgb24 *md = matrix.backBuffer();
+ }
+ while(pixels.has(1)) {
+ md->red = pixels.loadAndScale0();
+ md->green = pixels.loadAndScale1();
+ md->blue = pixels.loadAndScale2();
+ md++;
+ pixels.advanceData();
+ pixels.stepDithering();
+ }
+ matrix.swapBuffers();
+ if(SMART_MATRIX_CAN_TRIPLE_BUFFER && pixels.advanceBy() > 0) {
+ matrix.setBackBuffer(pixels.mData);
+ }
+ }
};
FASTLED_NAMESPACE_END
diff --git a/platforms/arm/k20/ws2812serial_controller.h b/platforms/arm/k20/ws2812serial_controller.h
index 0bca7d5e..a761dd49 100644
--- a/platforms/arm/k20/ws2812serial_controller.h
+++ b/platforms/arm/k20/ws2812serial_controller.h
@@ -7,36 +7,37 @@ FASTLED_NAMESPACE_BEGIN
template<int DATA_PIN, EOrder RGB_ORDER>
class CWS2812SerialController : public CPixelLEDController<RGB_ORDER, 8, 0xFF> {
- WS2812Serial *pserial;
- uint8_t *drawbuffer,*framebuffer;
-
- void _init(int nLeds) {
- if (pserial == NULL) {
- drawbuffer = (uint8_t*)malloc(nLeds * 3);
- framebuffer = (uint8_t*)malloc(nLeds * 12);
- pserial = new WS2812Serial(nLeds, framebuffer, drawbuffer, DATA_PIN, WS2812_RGB);
- pserial->begin();
+ WS2812Serial *pserial;
+ uint8_t *drawbuffer,*framebuffer;
+
+ void _init(int nLeds) {
+ if (pserial == NULL) {
+ drawbuffer = (uint8_t*)malloc(nLeds * 3);
+ framebuffer = (uint8_t*)malloc(nLeds * 12);
+ pserial = new WS2812Serial(nLeds, framebuffer, drawbuffer, DATA_PIN, WS2812_RGB);
+ pserial->begin();
+ }
}
- }
+
public:
- CWS2812SerialController() { pserial = NULL; }
+ CWS2812SerialController() { pserial = NULL; }
- virtual void init() { /* do nothing yet */ }
+ virtual void init() { /* do nothing yet */ }
- virtual void showPixels(PixelController<RGB_ORDER, 8, 0xFF> & pixels) {
- _init(pixels.size());
+ virtual void showPixels(PixelController<RGB_ORDER, 8, 0xFF> & pixels) {
+ _init(pixels.size());
- uint8_t *p = drawbuffer;
+ uint8_t *p = drawbuffer;
- while(pixels.has(1)) {
- *p++ = pixels.loadAndScale0();
- *p++ = pixels.loadAndScale1();
- *p++ = pixels.loadAndScale2();
- pixels.stepDithering();
- pixels.advanceData();
+ while(pixels.has(1)) {
+ *p++ = pixels.loadAndScale0();
+ *p++ = pixels.loadAndScale1();
+ *p++ = pixels.loadAndScale2();
+ pixels.stepDithering();
+ pixels.advanceData();
+ }
+ pserial->show();
}
- pserial->show();
- }
};
diff --git a/platforms/arm/k66/clockless_arm_k66.h b/platforms/arm/k66/clockless_arm_k66.h
index 61021057..ec4241f7 100644
--- a/platforms/arm/k66/clockless_arm_k66.h
+++ b/platforms/arm/k66/clockless_arm_k66.h
@@ -17,6 +17,7 @@ class ClocklessController : public CPixelLEDController<RGB_ORDER> {
data_t mPinMask;
data_ptr_t mPort;
CMinWait<WAIT_TIME> mWait;
+
public:
virtual void init() {
FastPin<DATA_PIN>::setOutput();
@@ -27,15 +28,14 @@ public:
virtual uint16_t getMaxRefreshRate() const { return 400; }
protected:
-
virtual void showPixels(PixelController<RGB_ORDER> & pixels) {
- mWait.wait();
+ mWait.wait();
if(!showRGBInternal(pixels)) {
- sei(); delayMicroseconds(WAIT_TIME); cli();
- showRGBInternal(pixels);
- }
- mWait.mark();
- }
+ sei(); delayMicroseconds(WAIT_TIME); cli();
+ 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/k66/clockless_block_arm_k66.h b/platforms/arm/k66/clockless_block_arm_k66.h
index 85a8cc71..c7eb9925 100644
--- a/platforms/arm/k66/clockless_block_arm_k66.h
+++ b/platforms/arm/k66/clockless_block_arm_k66.h
@@ -30,6 +30,7 @@ class InlineBlockClocklessController : public CPixelLEDController<RGB_ORDER, LAN
data_t mPinMask;
data_ptr_t mPort;
CMinWait<WAIT_TIME> mWait;
+
public:
virtual int size() { return CLEDController::size() * LANES; }
@@ -153,7 +154,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, LANES, LANE_MASK> &allpixels) {
+ static uint32_t showRGBInternal(PixelController<RGB_ORDER, LANES, LANE_MASK> &allpixels) {
// Get access to the clock
ARM_DEMCR |= ARM_DEMCR_TRCENA;
ARM_DWT_CTRL |= ARM_DWT_CTRL_CYCCNTENA;
@@ -211,6 +212,7 @@ class SixteenWayInlineBlockClocklessController : public CPixelLEDController<RGB_
data_t mPinMask;
data_ptr_t mPort;
CMinWait<WAIT_TIME> mWait;
+
public:
virtual void init() {
static_assert(LANES <= 16, "Maximum of 16 lanes for Teensy parallel controllers!");
@@ -242,11 +244,11 @@ public:
virtual void showPixels(PixelController<RGB_ORDER, LANES, PMASK> & pixels) {
mWait.wait();
uint32_t clocks = showRGBInternal(pixels);
- #if FASTLED_ALLOW_INTERRUPTS == 0
+ #if FASTLED_ALLOW_INTERRUPTS == 0
// Adjust the timer
long microsTaken = CLKS_TO_MICROS(clocks);
MS_COUNTER += (1 + (microsTaken / 1000));
- #endif
+ #endif
mWait.mark();
}
@@ -286,10 +288,9 @@ 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,LANES, PMASK> &allpixels) {
+ 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;
@@ -309,13 +310,15 @@ public:
while(allpixels.has(1)) {
allpixels.stepDithering();
- #if 0 && (FASTLED_ALLOW_INTERRUPTS == 1)
+ #if 0 && (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; }
+ if((ARM_DWT_CYCCNT-next_mark) > ((WAIT_TIME-INTERRUPT_THRESHOLD)*CLKS_PER_US)) {
+ sei();
+ return ARM_DWT_CYCCNT; }
}
- #endif
+ #endif
// Write first byte, read next byte
writeBits<8+XTRA0,1>(next_mark, b0, allpixels);
@@ -327,9 +330,9 @@ public:
// Write third byte
writeBits<8+XTRA0,0>(next_mark, b0, allpixels);
- #if 0 && (FASTLED_ALLOW_INTERRUPTS == 1)
+ #if 0 && (FASTLED_ALLOW_INTERRUPTS == 1)
sei();
- #endif
+ #endif
};
sei();
diff --git a/platforms/arm/k66/fastspi_arm_k66.h b/platforms/arm/k66/fastspi_arm_k66.h
index a40e5985..e0683fa2 100644
--- a/platforms/arm/k66/fastspi_arm_k66.h
+++ b/platforms/arm/k66/fastspi_arm_k66.h
@@ -37,6 +37,7 @@ template<int VAL, int BIT> class BitWork {
public:
static int highestBit() __attribute__((always_inline)) { return (VAL & 1 << BIT) ? BIT : BitWork<VAL, BIT-1>::highestBit(); }
};
+
template<int VAL> class BitWork<VAL, 0> {
public:
static int highestBit() __attribute__((always_inline)) { return 0; }
@@ -248,7 +249,6 @@ class ARMHardwareSPIOutput {
// CORE_PIN14_CONFIG = gState.pins[3];
}
-
public:
ARMHardwareSPIOutput() { m_pSelect = NULL; }
ARMHardwareSPIOutput(Selectable *pSelect) { m_pSelect = pSelect; }
@@ -323,8 +323,8 @@ public:
static void writeWord(uint16_t w) __attribute__((always_inline)) {
if(WAIT_STATE == PRE) { wait(); }
SPIX.PUSHR = ((LAST_STATE == LAST) ? SPI_PUSHR_EOQ : 0) |
- ((CONT_STATE == CONT) ? SPI_PUSHR_CONT : 0) |
- SPI_PUSHR_CTAS(1) | (w & 0xFFFF);
+ ((CONT_STATE == CONT) ? SPI_PUSHR_CONT : 0) |
+ SPI_PUSHR_CTAS(1) | (w & 0xFFFF);
SPIX.SR |= SPI_SR_TCF;
if(WAIT_STATE == POST) { wait(); }
}
@@ -332,8 +332,8 @@ public:
static void writeByte(uint8_t b) __attribute__((always_inline)) {
if(WAIT_STATE == PRE) { wait(); }
SPIX.PUSHR = ((LAST_STATE == LAST) ? SPI_PUSHR_EOQ : 0) |
- ((CONT_STATE == CONT) ? SPI_PUSHR_CONT : 0) |
- SPI_PUSHR_CTAS(0) | (b & 0xFF);
+ ((CONT_STATE == CONT) ? SPI_PUSHR_CONT : 0) |
+ SPI_PUSHR_CTAS(0) | (b & 0xFF);
SPIX.SR |= SPI_SR_TCF;
if(WAIT_STATE == POST) { wait(); }
}
diff --git a/platforms/arm/mxrt1062/block_clockless_arm_mxrt1062.h b/platforms/arm/mxrt1062/block_clockless_arm_mxrt1062.h
index 73f73de8..5c878c72 100644
--- a/platforms/arm/mxrt1062/block_clockless_arm_mxrt1062.h
+++ b/platforms/arm/mxrt1062/block_clockless_arm_mxrt1062.h
@@ -10,197 +10,193 @@ FASTLED_NAMESPACE_BEGIN
#define __FL_T4_MASK ((1<<(LANES))-1)
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 = 50>
class FlexibleInlineBlockClocklessController : public CPixelLEDController<RGB_ORDER, LANES, __FL_T4_MASK> {
+ uint8_t m_bitOffsets[16];
+ uint8_t m_nActualLanes;
+ uint8_t m_nLowBit;
+ uint8_t m_nHighBit;
+ uint32_t m_nWriteMask;
+ uint8_t m_nOutBlocks;
+ uint32_t m_offsets[3];
+ CMinWait<WAIT_TIME> mWait;
- uint8_t m_bitOffsets[16];
- uint8_t m_nActualLanes;
- uint8_t m_nLowBit;
- uint8_t m_nHighBit;
- uint32_t m_nWriteMask;
- uint8_t m_nOutBlocks;
- uint32_t m_offsets[3];
- CMinWait<WAIT_TIME> mWait;
public:
-
- virtual int size() { return CLEDController::size() * m_nActualLanes; }
-
-// For each pin, if we've hit our lane count, break, otherwise set the pin to output,
-// store the bit offset in our offset array, add this pin to the write mask, and if this
-// pin ends a block sequence, then break out of the switch as well
-#define _BLOCK_PIN(P) case P: { \
- if(m_nActualLanes == LANES) break; \
- FastPin<P>::setOutput(); \
- m_bitOffsets[m_nActualLanes++] = FastPin<P>::pinbit(); \
- m_nWriteMask |= FastPin<P>::mask(); \
- if( P == 27 || P == 7 || P == 30) break; \
-}
-
- virtual void init() {
- // pre-initialize
- memset(m_bitOffsets,0,16);
- m_nActualLanes = 0;
- m_nLowBit = 33;
- m_nHighBit = 0;
- m_nWriteMask = 0;
-
- // setup the bits and data tracking for parallel output
- switch(FIRST_PIN) {
- // GPIO6 block output
- _BLOCK_PIN( 1);
- _BLOCK_PIN( 0);
- _BLOCK_PIN(24);
- _BLOCK_PIN(25);
- _BLOCK_PIN(19);
- _BLOCK_PIN(18);
- _BLOCK_PIN(14);
- _BLOCK_PIN(15);
- _BLOCK_PIN(17);
- _BLOCK_PIN(16);
- _BLOCK_PIN(22);
- _BLOCK_PIN(23);
- _BLOCK_PIN(20);
- _BLOCK_PIN(21);
- _BLOCK_PIN(26);
- _BLOCK_PIN(27);
- // GPIO7 block output
- _BLOCK_PIN(10);
- _BLOCK_PIN(12);
- _BLOCK_PIN(11);
- _BLOCK_PIN(13);
- _BLOCK_PIN( 6);
- _BLOCK_PIN( 9);
- _BLOCK_PIN(32);
- _BLOCK_PIN( 8);
- _BLOCK_PIN( 7);
- // GPIO 37 block output
- _BLOCK_PIN(37);
- _BLOCK_PIN(36);
- _BLOCK_PIN(35);
- _BLOCK_PIN(34);
- _BLOCK_PIN(39);
- _BLOCK_PIN(38);
- _BLOCK_PIN(28);
- _BLOCK_PIN(31);
- _BLOCK_PIN(30);
+ virtual int size() { return CLEDController::size() * m_nActualLanes; }
+
+ // For each pin, if we've hit our lane count, break, otherwise set the pin to output,
+ // store the bit offset in our offset array, add this pin to the write mask, and if this
+ // pin ends a block sequence, then break out of the switch as well
+ #define _BLOCK_PIN(P) case P: { \
+ if(m_nActualLanes == LANES) break; \
+ FastPin<P>::setOutput(); \
+ m_bitOffsets[m_nActualLanes++] = FastPin<P>::pinbit(); \
+ m_nWriteMask |= FastPin<P>::mask(); \
+ if( P == 27 || P == 7 || P == 30) break; \
}
- for(int i = 0; i < m_nActualLanes; i++) {
- if(m_bitOffsets[i] < m_nLowBit) { m_nLowBit = m_bitOffsets[i]; }
- if(m_bitOffsets[i] > m_nHighBit) { m_nHighBit = m_bitOffsets[i]; }
- }
+ virtual void init() {
+ // pre-initialize
+ memset(m_bitOffsets,0,16);
+ m_nActualLanes = 0;
+ m_nLowBit = 33;
+ m_nHighBit = 0;
+ m_nWriteMask = 0;
+
+ // setup the bits and data tracking for parallel output
+ switch(FIRST_PIN) {
+ // GPIO6 block output
+ _BLOCK_PIN( 1);
+ _BLOCK_PIN( 0);
+ _BLOCK_PIN(24);
+ _BLOCK_PIN(25);
+ _BLOCK_PIN(19);
+ _BLOCK_PIN(18);
+ _BLOCK_PIN(14);
+ _BLOCK_PIN(15);
+ _BLOCK_PIN(17);
+ _BLOCK_PIN(16);
+ _BLOCK_PIN(22);
+ _BLOCK_PIN(23);
+ _BLOCK_PIN(20);
+ _BLOCK_PIN(21);
+ _BLOCK_PIN(26);
+ _BLOCK_PIN(27);
+ // GPIO7 block output
+ _BLOCK_PIN(10);
+ _BLOCK_PIN(12);
+ _BLOCK_PIN(11);
+ _BLOCK_PIN(13);
+ _BLOCK_PIN( 6);
+ _BLOCK_PIN( 9);
+ _BLOCK_PIN(32);
+ _BLOCK_PIN( 8);
+ _BLOCK_PIN( 7);
+ // GPIO 37 block output
+ _BLOCK_PIN(37);
+ _BLOCK_PIN(36);
+ _BLOCK_PIN(35);
+ _BLOCK_PIN(34);
+ _BLOCK_PIN(39);
+ _BLOCK_PIN(38);
+ _BLOCK_PIN(28);
+ _BLOCK_PIN(31);
+ _BLOCK_PIN(30);
+ }
- m_nOutBlocks = (m_nHighBit + 8)/8;
+ for(int i = 0; i < m_nActualLanes; i++) {
+ if(m_bitOffsets[i] < m_nLowBit) { m_nLowBit = m_bitOffsets[i]; }
+ if(m_bitOffsets[i] > m_nHighBit) { m_nHighBit = m_bitOffsets[i]; }
+ }
+
+ m_nOutBlocks = (m_nHighBit + 8)/8;
- }
+ }
- virtual uint16_t getMaxRefreshRate() const { return 400; }
+ virtual uint16_t getMaxRefreshRate() const { return 400; }
- virtual void showPixels(PixelController<RGB_ORDER, LANES, __FL_T4_MASK> & pixels) {
- mWait.wait();
+ virtual void showPixels(PixelController<RGB_ORDER, LANES, __FL_T4_MASK> & pixels) {
+ mWait.wait();
#if FASTLED_ALLOW_INTERRUPTS == 0
- uint32_t clocks = showRGBInternal(pixels);
- // Adjust the timer
- long microsTaken = CLKS_TO_MICROS(clocks);
- MS_COUNTER += (1 + (microsTaken / 1000));
- #else
- showRGBInternal(pixels);
+ uint32_t clocks = showRGBInternal(pixels);
+ // Adjust the timer
+ long microsTaken = CLKS_TO_MICROS(clocks);
+ MS_COUNTER += (1 + (microsTaken / 1000));
+ #else
+ showRGBInternal(pixels);
#endif
-
mWait.mark();
}
- typedef union {
- uint8_t bytes[32];
- uint8_t bg[4][8];
- uint16_t shorts[16];
- uint32_t raw[8];
- } _outlines;
-
-
- template<int BITS,int PX> __attribute__ ((always_inline)) inline void writeBits(register uint32_t & next_mark, register _outlines & b, PixelController<RGB_ORDER, LANES, __FL_T4_MASK> &pixels) {
- _outlines b2;
- transpose8x1(b.bg[3], b2.bg[3]);
- transpose8x1(b.bg[2], b2.bg[2]);
- transpose8x1(b.bg[1], b2.bg[1]);
- transpose8x1(b.bg[0], b2.bg[0]);
-
- register uint8_t d = pixels.template getd<PX>(pixels);
- register uint8_t scale = pixels.template getscale<PX>(pixels);
-
- int x = 0;
- for(uint32_t i = 8; i > 0;) {
- i--;
- while(ARM_DWT_CYCCNT < next_mark);
- *FastPin<FIRST_PIN>::sport() = m_nWriteMask;
- next_mark = ARM_DWT_CYCCNT + m_offsets[0];
-
- uint32_t out = (b2.bg[3][i] << 24) | (b2.bg[2][i] << 16) | (b2.bg[1][i] << 8) | b2.bg[0][i];
-
- out = ((~out) & m_nWriteMask);
- while((next_mark - ARM_DWT_CYCCNT) > m_offsets[1]);
- *FastPin<FIRST_PIN>::cport() = out;
-
- out = m_nWriteMask;
- while((next_mark - ARM_DWT_CYCCNT) > m_offsets[2]);
- *FastPin<FIRST_PIN>::cport() = out;
-
- // Read and store up to two bytes
- if (x < m_nActualLanes) {
- b.bytes[m_bitOffsets[x]] = pixels.template loadAndScale<PX>(pixels,x,d,scale);
- x++;
- if (x < m_nActualLanes) {
- b.bytes[m_bitOffsets[x]] = pixels.template loadAndScale<PX>(pixels,x,d,scale);
- x++;
+ typedef union {
+ uint8_t bytes[32];
+ uint8_t bg[4][8];
+ uint16_t shorts[16];
+ uint32_t raw[8];
+ } _outlines;
+
+ template<int BITS,int PX> __attribute__ ((always_inline)) inline void writeBits(register uint32_t & next_mark, register _outlines & b, PixelController<RGB_ORDER, LANES, __FL_T4_MASK> &pixels) {
+ _outlines b2;
+ transpose8x1(b.bg[3], b2.bg[3]);
+ transpose8x1(b.bg[2], b2.bg[2]);
+ transpose8x1(b.bg[1], b2.bg[1]);
+ transpose8x1(b.bg[0], b2.bg[0]);
+
+ register uint8_t d = pixels.template getd<PX>(pixels);
+ register uint8_t scale = pixels.template getscale<PX>(pixels);
+
+ int x = 0;
+ for(uint32_t i = 8; i > 0;) {
+ i--;
+ while(ARM_DWT_CYCCNT < next_mark);
+ *FastPin<FIRST_PIN>::sport() = m_nWriteMask;
+ next_mark = ARM_DWT_CYCCNT + m_offsets[0];
+
+ uint32_t out = (b2.bg[3][i] << 24) | (b2.bg[2][i] << 16) | (b2.bg[1][i] << 8) | b2.bg[0][i];
+
+ out = ((~out) & m_nWriteMask);
+ while((next_mark - ARM_DWT_CYCCNT) > m_offsets[1]);
+ *FastPin<FIRST_PIN>::cport() = out;
+
+ out = m_nWriteMask;
+ while((next_mark - ARM_DWT_CYCCNT) > m_offsets[2]);
+ *FastPin<FIRST_PIN>::cport() = out;
+
+ // Read and store up to two bytes
+ if (x < m_nActualLanes) {
+ b.bytes[m_bitOffsets[x]] = pixels.template loadAndScale<PX>(pixels,x,d,scale);
+ x++;
+ if (x < m_nActualLanes) {
+ b.bytes[m_bitOffsets[x]] = pixels.template loadAndScale<PX>(pixels,x,d,scale);
+ x++;
+ }
+ }
}
- }
}
- }
- uint32_t showRGBInternal(PixelController<RGB_ORDER,LANES, __FL_T4_MASK> &allpixels) {
- allpixels.preStepFirstByteDithering();
- _outlines b0;
- uint32_t start = ARM_DWT_CYCCNT;
+ uint32_t showRGBInternal(PixelController<RGB_ORDER,LANES, __FL_T4_MASK> &allpixels) {
+ allpixels.preStepFirstByteDithering();
+ _outlines b0;
+ uint32_t start = ARM_DWT_CYCCNT;
- for(int i = 0; i < m_nActualLanes; i++) {
- b0.bytes[m_bitOffsets[i]] = allpixels.loadAndScale0(i);
- }
+ for(int i = 0; i < m_nActualLanes; i++) {
+ b0.bytes[m_bitOffsets[i]] = allpixels.loadAndScale0(i);
+ }
- cli();
- m_offsets[0] = _FASTLED_NS_TO_DWT(T1+T2+T3);
- m_offsets[1] = _FASTLED_NS_TO_DWT(T2+T3);
- m_offsets[2] = _FASTLED_NS_TO_DWT(T3);
- uint32_t wait_off = _FASTLED_NS_TO_DWT((WAIT_TIME-INTERRUPT_THRESHOLD));
-
- uint32_t next_mark = ARM_DWT_CYCCNT + m_offsets[0];
-
- while(allpixels.has(1)) {
- 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_off) { sei(); return ARM_DWT_CYCCNT - start; }
- }
- #endif
-
- // Write first byte, read next byte
- writeBits<8+XTRA0,1>(next_mark, b0, allpixels);
-
- // Write second byte, read 3rd byte
- writeBits<8+XTRA0,2>(next_mark, b0, allpixels);
- allpixels.advanceData();
-
- // Write third byte
- writeBits<8+XTRA0,0>(next_mark, b0, allpixels);
-
- #if (FASTLED_ALLOW_INTERRUPTS == 1)
- sei();
- #endif
- }
+ cli();
+
+ m_offsets[0] = _FASTLED_NS_TO_DWT(T1+T2+T3);
+ m_offsets[1] = _FASTLED_NS_TO_DWT(T2+T3);
+ m_offsets[2] = _FASTLED_NS_TO_DWT(T3);
+ uint32_t wait_off = _FASTLED_NS_TO_DWT((WAIT_TIME-INTERRUPT_THRESHOLD));
+
+ uint32_t next_mark = ARM_DWT_CYCCNT + m_offsets[0];
+
+ while(allpixels.has(1)) {
+ 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_off) { sei(); return ARM_DWT_CYCCNT - start; }
+ }
+ #endif
+ // Write first byte, read next byte
+ writeBits<8+XTRA0,1>(next_mark, b0, allpixels);
+
+ // Write second byte, read 3rd byte
+ writeBits<8+XTRA0,2>(next_mark, b0, allpixels);
+ allpixels.advanceData();
+
+ // Write third byte
+ writeBits<8+XTRA0,0>(next_mark, b0, allpixels);
+ #if (FASTLED_ALLOW_INTERRUPTS == 1)
+ sei();
+ #endif
+ }
- sei();
+ sei();
- return ARM_DWT_CYCCNT - start;
- }
+ return ARM_DWT_CYCCNT - start;
+ }
};
template<template<uint8_t DATA_PIN, EOrder RGB_ORDER> class CHIPSET, uint8_t DATA_PIN, int NUM_LANES, EOrder RGB_ORDER=GRB>
diff --git a/platforms/arm/mxrt1062/clockless_arm_mxrt1062.h b/platforms/arm/mxrt1062/clockless_arm_mxrt1062.h
index ed72713a..dfb772ae 100644
--- a/platforms/arm/mxrt1062/clockless_arm_mxrt1062.h
+++ b/platforms/arm/mxrt1062/clockless_arm_mxrt1062.h
@@ -35,21 +35,20 @@ public:
FastPin<DATA_PIN>::setOutput();
mPinMask = FastPin<DATA_PIN>::mask();
mPort = FastPin<DATA_PIN>::port();
- FastPin<DATA_PIN>::lo();
+ FastPin<DATA_PIN>::lo();
}
- virtual uint16_t getMaxRefreshRate() const { return 400; }
+ virtual uint16_t getMaxRefreshRate() const { return 400; }
protected:
-
virtual void showPixels(PixelController<RGB_ORDER> & pixels) {
- mWait.wait();
+ mWait.wait();
if(!showRGBInternal(pixels)) {
- sei(); delayMicroseconds(WAIT_TIME); cli();
- showRGBInternal(pixels);
- }
- mWait.mark();
- }
+ sei(); delayMicroseconds(WAIT_TIME); cli();
+ showRGBInternal(pixels);
+ }
+ mWait.mark();
+ }
template<int BITS> __attribute__ ((always_inline)) inline void writeBits(register uint32_t & next_mark, register uint32_t & b) {
for(register uint32_t i = BITS-1; i > 0; i--) {
@@ -87,12 +86,14 @@ protected:
register uint32_t b = pixels.loadAndScale0();
cli();
- off[0] = _FASTLED_NS_TO_DWT(T1+T2+T3);
- off[1] = _FASTLED_NS_TO_DWT(T2+T3);
+
+ off[0] = _FASTLED_NS_TO_DWT(T1+T2+T3);
+ off[1] = _FASTLED_NS_TO_DWT(T2+T3);
off[2] = _FASTLED_NS_TO_DWT(T3);
- uint32_t wait_off = _FASTLED_NS_TO_DWT((WAIT_TIME-INTERRUPT_THRESHOLD));
- uint32_t next_mark = ARM_DWT_CYCCNT + off[0];
+ uint32_t wait_off = _FASTLED_NS_TO_DWT((WAIT_TIME-INTERRUPT_THRESHOLD));
+
+ uint32_t next_mark = ARM_DWT_CYCCNT + off[0];
while(pixels.has(1)) {
pixels.stepDithering();
diff --git a/platforms/arm/mxrt1062/fastpin_arm_mxrt1062.h b/platforms/arm/mxrt1062/fastpin_arm_mxrt1062.h
index 38c88410..8960a8c9 100644
--- a/platforms/arm/mxrt1062/fastpin_arm_mxrt1062.h
+++ b/platforms/arm/mxrt1062/fastpin_arm_mxrt1062.h
@@ -39,7 +39,7 @@ public:
inline static port_ptr_t sport() __attribute__ ((always_inline)) { return &_GPIO_DR_SET::r(); }
inline static port_ptr_t cport() __attribute__ ((always_inline)) { return &_GPIO_DR_CLEAR::r(); }
inline static port_t mask() __attribute__ ((always_inline)) { return _MASK; }
- inline static uint32_t pinbit() __attribute__ ((always_inline)) { return _BIT; }
+ inline static uint32_t pinbit() __attribute__ ((always_inline)) { return _BIT; }
};
diff --git a/platforms/arm/mxrt1062/fastspi_arm_mxrt1062.h b/platforms/arm/mxrt1062/fastspi_arm_mxrt1062.h
index fa6b81ff..068c7be1 100644
--- a/platforms/arm/mxrt1062/fastspi_arm_mxrt1062.h
+++ b/platforms/arm/mxrt1062/fastspi_arm_mxrt1062.h
@@ -9,18 +9,18 @@ FASTLED_NAMESPACE_BEGIN
template <uint8_t _DATA_PIN, uint8_t _CLOCK_PIN, uint32_t _SPI_CLOCK_RATE, SPIClass & _SPIObject, int _SPI_INDEX>
class Teesy4HardwareSPIOutput {
Selectable *m_pSelect;
- uint32_t m_bitCount;
- uint32_t m_bitData;
- inline IMXRT_LPSPI_t & port() __attribute__((always_inline)) {
- switch(_SPI_INDEX) {
- case 0:
- return IMXRT_LPSPI4_S;
- case 1:
- return IMXRT_LPSPI3_S;
- case 2:
- return IMXRT_LPSPI1_S;
- }
- }
+ uint32_t m_bitCount;
+ uint32_t m_bitData;
+ inline IMXRT_LPSPI_t & port() __attribute__((always_inline)) {
+ switch(_SPI_INDEX) {
+ case 0:
+ return IMXRT_LPSPI4_S;
+ case 1:
+ return IMXRT_LPSPI3_S;
+ case 2:
+ return IMXRT_LPSPI1_S;
+ }
+ }
public:
Teesy4HardwareSPIOutput() { m_pSelect = NULL; m_bitCount = 0;}
@@ -34,42 +34,42 @@ public:
// latch the CS select
void inline select() __attribute__((always_inline)) {
- // begin the SPI transaction
- _SPIObject.beginTransaction(SPISettings(_SPI_CLOCK_RATE, MSBFIRST, SPI_MODE0));
- if(m_pSelect != NULL) { m_pSelect->select(); }
- }
+ // begin the SPI transaction
+ _SPIObject.beginTransaction(SPISettings(_SPI_CLOCK_RATE, MSBFIRST, SPI_MODE0));
+ if(m_pSelect != NULL) { m_pSelect->select(); }
+ }
// release the CS select
void inline release() __attribute__((always_inline)) {
- if(m_pSelect != NULL) { m_pSelect->release(); }
- _SPIObject.endTransaction();
- }
+ if(m_pSelect != NULL) { m_pSelect->release(); }
+ _SPIObject.endTransaction();
+ }
// wait until all queued up data has been written
static void waitFully() { /* TODO */ }
// write a byte out via SPI (returns immediately on writing register) -
void inline writeByte(uint8_t b) __attribute__((always_inline)) {
- if(m_bitCount == 0) {
- _SPIObject.transfer(b);
- } else {
- // There's been a bit of data written, add that to the output as well
- uint32_t outData = (m_bitData << 8) | b;
- uint32_t tcr = port().TCR;
- port().TCR = (tcr & 0xfffff000) | LPSPI_TCR_FRAMESZ((8+m_bitCount) - 1); // turn on 9 bit mode
- port().TDR = outData; // output 9 bit data.
- while ((port().RSR & LPSPI_RSR_RXEMPTY)) ; // wait while the RSR fifo is empty...
+ if(m_bitCount == 0) {
+ _SPIObject.transfer(b);
+ } else {
+ // There's been a bit of data written, add that to the output as well
+ uint32_t outData = (m_bitData << 8) | b;
+ uint32_t tcr = port().TCR;
+ port().TCR = (tcr & 0xfffff000) | LPSPI_TCR_FRAMESZ((8+m_bitCount) - 1); // turn on 9 bit mode
+ port().TDR = outData; // output 9 bit data.
+ while ((port().RSR & LPSPI_RSR_RXEMPTY)) ; // wait while the RSR fifo is empty...
port().TCR = (tcr & 0xfffff000) | LPSPI_TCR_FRAMESZ((8) - 1); // turn back on 8 bit mode
- port().RDR;
- m_bitCount = 0;
- }
- }
+ port().RDR;
+ m_bitCount = 0;
+ }
+ }
// write a word out via SPI (returns immediately on writing register)
void inline writeWord(uint16_t w) __attribute__((always_inline)) {
- writeByte(((w>>8) & 0xFF));
- _SPIObject.transfer(w & 0xFF);
- }
+ writeByte(((w>>8) & 0xFF));
+ _SPIObject.transfer(w & 0xFF);
+ }
// A raw set of writing byte values, assumes setup/init/waiting done elsewhere
static void writeBytesValueRaw(uint8_t value, int len) {
@@ -99,16 +99,16 @@ public:
// write a single bit out, which bit from the passed in byte is determined by template parameter
template <uint8_t BIT> inline void writeBit(uint8_t b) {
- m_bitData = (m_bitData<<1) | ((b&(1<<BIT)) != 0);
- // If this is the 8th bit we've collected, just write it out raw
- register uint32_t bc = m_bitCount;
- bc = (bc + 1) & 0x07;
- if (!bc) {
- m_bitCount = 0;
- _SPIObject.transfer(m_bitData);
- }
- m_bitCount = bc;
- }
+ m_bitData = (m_bitData<<1) | ((b&(1<<BIT)) != 0);
+ // If this is the 8th bit we've collected, just write it out raw
+ register uint32_t bc = m_bitCount;
+ bc = (bc + 1) & 0x07;
+ if (!bc) {
+ m_bitCount = 0;
+ _SPIObject.transfer(m_bitData);
+ }
+ m_bitCount = bc;
+ }
// write a block of uint8_ts out in groups of three. len is the total number of uint8_ts to write out. The template
// parameters indicate how many uint8_ts to skip at the beginning and/or end of each grouping
diff --git a/platforms/arm/nrf51/clockless_arm_nrf51.h b/platforms/arm/nrf51/clockless_arm_nrf51.h
index b7489579..c607e61e 100644
--- a/platforms/arm/nrf51/clockless_arm_nrf51.h
+++ b/platforms/arm/nrf51/clockless_arm_nrf51.h
@@ -20,62 +20,63 @@
#include "../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 CPixelLEDController<RGB_ORDER> {
- typedef typename FastPinBB<DATA_PIN>::port_ptr_t data_ptr_t;
- typedef typename FastPinBB<DATA_PIN>::port_t data_t;
+ typedef typename FastPinBB<DATA_PIN>::port_ptr_t data_ptr_t;
+ typedef typename FastPinBB<DATA_PIN>::port_t data_t;
+
+ data_t mPinMask;
+ data_ptr_t mPort;
+ CMinWait<WAIT_TIME> mWait;
- data_t mPinMask;
- data_ptr_t mPort;
- CMinWait<WAIT_TIME> mWait;
public:
- virtual void init() {
- FastPinBB<DATA_PIN>::setOutput();
- mPinMask = FastPinBB<DATA_PIN>::mask();
- mPort = FastPinBB<DATA_PIN>::port();
- }
+ virtual void init() {
+ FastPinBB<DATA_PIN>::setOutput();
+ mPinMask = FastPinBB<DATA_PIN>::mask();
+ mPort = FastPinBB<DATA_PIN>::port();
+ }
virtual uint16_t getMaxRefreshRate() const { return 400; }
- virtual void showPixels(PixelController<RGB_ORDER> & pixels) {
- mWait.wait();
- cli();
- if(!showRGBInternal(pixels)) {
- sei(); delayMicroseconds(WAIT_TIME); cli();
- showRGBInternal(pixels);
+ virtual void showPixels(PixelController<RGB_ORDER> & pixels) {
+ mWait.wait();
+ cli();
+ if(!showRGBInternal(pixels)) {
+ sei(); delayMicroseconds(WAIT_TIME); cli();
+ 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> pixels) {
+ struct M0ClocklessData data;
+ data.d[0] = pixels.d[0];
+ data.d[1] = pixels.d[1];
+ data.d[2] = pixels.d[2];
+ data.s[0] = pixels.mScale[0];
+ data.s[1] = pixels.mScale[1];
+ data.s[2] = pixels.mScale[2];
+ data.e[0] = pixels.e[0];
+ data.e[1] = pixels.e[1];
+ data.e[2] = pixels.e[2];
+ data.adj = pixels.mAdvance;
+
+ typename FastPin<DATA_PIN>::port_ptr_t portBase = FastPin<DATA_PIN>::port();
+
+ // timer mode w/prescaler of 0
+ LED_TIMER->MODE = TIMER_MODE_MODE_Timer;
+ LED_TIMER->PRESCALER = 0;
+ LED_TIMER->EVENTS_COMPARE[0] = 0;
+ LED_TIMER->BITMODE = TIMER_BITMODE_BITMODE_16Bit;
+ LED_TIMER->SHORTS = TIMER_SHORTS_COMPARE0_CLEAR_Msk;
+ LED_TIMER->TASKS_START = 1;
+
+ int ret = showLedData<4,8,T1,T2,T3,RGB_ORDER,WAIT_TIME>(portBase, FastPin<DATA_PIN>::mask(), pixels.mData, pixels.mLen, &data);
+
+ LED_TIMER->TASKS_STOP = 1;
+ return ret; // 0x00FFFFFF - _VAL;
}
- 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> pixels) {
- struct M0ClocklessData data;
- data.d[0] = pixels.d[0];
- data.d[1] = pixels.d[1];
- data.d[2] = pixels.d[2];
- data.s[0] = pixels.mScale[0];
- data.s[1] = pixels.mScale[1];
- data.s[2] = pixels.mScale[2];
- data.e[0] = pixels.e[0];
- data.e[1] = pixels.e[1];
- data.e[2] = pixels.e[2];
- data.adj = pixels.mAdvance;
-
- typename FastPin<DATA_PIN>::port_ptr_t portBase = FastPin<DATA_PIN>::port();
-
- // timer mode w/prescaler of 0
- LED_TIMER->MODE = TIMER_MODE_MODE_Timer;
- LED_TIMER->PRESCALER = 0;
- LED_TIMER->EVENTS_COMPARE[0] = 0;
- LED_TIMER->BITMODE = TIMER_BITMODE_BITMODE_16Bit;
- LED_TIMER->SHORTS = TIMER_SHORTS_COMPARE0_CLEAR_Msk;
- LED_TIMER->TASKS_START = 1;
-
- int ret = showLedData<4,8,T1,T2,T3,RGB_ORDER,WAIT_TIME>(portBase, FastPin<DATA_PIN>::mask(), pixels.mData, pixels.mLen, &data);
-
- LED_TIMER->TASKS_STOP = 1;
- return ret; // 0x00FFFFFF - _VAL;
- }
};
diff --git a/platforms/arm/nrf51/fastpin_arm_nrf51.h b/platforms/arm/nrf51/fastpin_arm_nrf51.h
index 3d02edc1..6005c448 100644
--- a/platforms/arm/nrf51/fastpin_arm_nrf51.h
+++ b/platforms/arm/nrf51/fastpin_arm_nrf51.h
@@ -9,28 +9,28 @@
#if 0
template<uint8_t PIN, uint32_t _MASK, typename _DIRSET, typename _DIRCLR, typename _OUTSET, typename _OUTCLR, typename _OUT> class _ARMPIN {
public:
- typedef volatile uint32_t * port_ptr_t;
- typedef uint32_t port_t;
+ typedef volatile uint32_t * port_ptr_t;
+ typedef uint32_t port_t;
- inline static void setOutput() { _DIRSET::r() = _MASK; }
- inline static void setInput() { _DIRCLR::r() = _MASK; }
+ inline static void setOutput() { _DIRSET::r() = _MASK; }
+ inline static void setInput() { _DIRCLR::r() = _MASK; }
- inline static void hi() __attribute__ ((always_inline)) { _OUTSET::r() = _MASK; }
- inline static void lo() __attribute__ ((always_inline)) { _OUTCLR::r() = _MASK; }
- inline static void set(register port_t val) __attribute__ ((always_inline)) { _OUT::r() = val; }
+ inline static void hi() __attribute__ ((always_inline)) { _OUTSET::r() = _MASK; }
+ inline static void lo() __attribute__ ((always_inline)) { _OUTCLR::r() = _MASK; }
+ inline static void set(register port_t val) __attribute__ ((always_inline)) { _OUT::r() = val; }
- inline static void strobe() __attribute__ ((always_inline)) { toggle(); toggle(); }
+ inline static void strobe() __attribute__ ((always_inline)) { toggle(); toggle(); }
- inline static void toggle() __attribute__ ((always_inline)) { _OUT::r() ^= _MASK; }
+ inline static void toggle() __attribute__ ((always_inline)) { _OUT::r() ^= _MASK; }
- inline static void hi(register port_ptr_t port) __attribute__ ((always_inline)) { hi(); }
- inline static void lo(register port_ptr_t port) __attribute__ ((always_inline)) { lo(); }
- inline static void fastset(register port_ptr_t port, register port_t val) __attribute__ ((always_inline)) { *port = val; }
+ inline static void hi(register port_ptr_t port) __attribute__ ((always_inline)) { hi(); }
+ inline static void lo(register port_ptr_t port) __attribute__ ((always_inline)) { lo(); }
+ inline static void fastset(register port_ptr_t port, register port_t val) __attribute__ ((always_inline)) { *port = val; }
- inline static port_t hival() __attribute__ ((always_inline)) { return _OUT::r() | _MASK; }
- inline static port_t loval() __attribute__ ((always_inline)) { return _OUT::r() & ~_MASK; }
- inline static port_ptr_t port() __attribute__ ((always_inline)) { return &_OUT::r(); }
- inline static port_t mask() __attribute__ ((always_inline)) { return _MASK; }
+ inline static port_t hival() __attribute__ ((always_inline)) { return _OUT::r() | _MASK; }
+ inline static port_t loval() __attribute__ ((always_inline)) { return _OUT::r() & ~_MASK; }
+ inline static port_ptr_t port() __attribute__ ((always_inline)) { return &_OUT::r(); }
+ inline static port_t mask() __attribute__ ((always_inline)) { return _MASK; }
};
#define ADDR(X) *(volatile uint32_t*)X
@@ -50,20 +50,20 @@ _RD32_NRF(NR_OUTCLR);
_RD32_NRF(NR_OUT);
#define _FL_DEFPIN(PIN) template<> class FastPin<PIN> : public _ARMPIN<PIN, 1 << PIN, \
- _R(NR_DIRSET), _R(NR_DIRCLR), _R(NR_OUTSET), _R(NR_OUTCLR), _R(NR_OUT)> {};
+ _R(NR_DIRSET), _R(NR_DIRCLR), _R(NR_OUTSET), _R(NR_OUTCLR), _R(NR_OUT)> {};
#else
typedef struct { /*!< GPIO Structure */
- // __I uint32_t RESERVED0[321];
- __IO uint32_t OUT; /*!< Write GPIO port. */
- __IO uint32_t OUTSET; /*!< Set individual bits in GPIO port. */
- __IO uint32_t OUTCLR; /*!< Clear individual bits in GPIO port. */
- __I uint32_t IN; /*!< Read GPIO port. */
- __IO uint32_t DIR; /*!< Direction of GPIO pins. */
- __IO uint32_t DIRSET; /*!< DIR set register. */
- __IO uint32_t DIRCLR; /*!< DIR clear register. */
- __I uint32_t RESERVED1[120];
- __IO uint32_t PIN_CNF[32]; /*!< Configuration of GPIO pins. */
+ // __I uint32_t RESERVED0[321];
+ __IO uint32_t OUT; /*!< Write GPIO port. */
+ __IO uint32_t OUTSET; /*!< Set individual bits in GPIO port. */
+ __IO uint32_t OUTCLR; /*!< Clear individual bits in GPIO port. */
+ __I uint32_t IN; /*!< Read GPIO port. */
+ __IO uint32_t DIR; /*!< Direction of GPIO pins. */
+ __IO uint32_t DIRSET; /*!< DIR set register. */
+ __IO uint32_t DIRCLR; /*!< DIR clear register. */
+ __I uint32_t RESERVED1[120];
+ __IO uint32_t PIN_CNF[32]; /*!< Configuration of GPIO pins. */
} FL_NRF_GPIO_Type;
#define FL_NRF_GPIO_BASE 0x50000504UL
@@ -71,30 +71,30 @@ typedef struct { /*!< GPIO Structure
template<uint8_t PIN, uint32_t _MASK> class _ARMPIN {
public:
- typedef volatile uint32_t * port_ptr_t;
- typedef uint32_t port_t;
+ typedef volatile uint32_t * port_ptr_t;
+ typedef uint32_t port_t;
- inline static void setOutput() { FL_NRF_GPIO->DIRSET = _MASK; }
- inline static void setInput() { FL_NRF_GPIO->DIRCLR = _MASK; }
+ inline static void setOutput() { FL_NRF_GPIO->DIRSET = _MASK; }
+ inline static void setInput() { FL_NRF_GPIO->DIRCLR = _MASK; }
- inline static void hi() __attribute__ ((always_inline)) { FL_NRF_GPIO->OUTSET = _MASK; }
- inline static void lo() __attribute__ ((always_inline)) { FL_NRF_GPIO->OUTCLR= _MASK; }
- inline static void set(register port_t val) __attribute__ ((always_inline)) { FL_NRF_GPIO->OUT = val; }
+ inline static void hi() __attribute__ ((always_inline)) { FL_NRF_GPIO->OUTSET = _MASK; }
+ inline static void lo() __attribute__ ((always_inline)) { FL_NRF_GPIO->OUTCLR= _MASK; }
+ inline static void set(register port_t val) __attribute__ ((always_inline)) { FL_NRF_GPIO->OUT = val; }
- inline static void strobe() __attribute__ ((always_inline)) { toggle(); toggle(); }
+ inline static void strobe() __attribute__ ((always_inline)) { toggle(); toggle(); }
- inline static void toggle() __attribute__ ((always_inline)) { FL_NRF_GPIO->OUT ^= _MASK; }
+ inline static void toggle() __attribute__ ((always_inline)) { FL_NRF_GPIO->OUT ^= _MASK; }
- inline static void hi(register port_ptr_t port) __attribute__ ((always_inline)) { hi(); }
- inline static void lo(register port_ptr_t port) __attribute__ ((always_inline)) { lo(); }
- inline static void fastset(register port_ptr_t port, register port_t val) __attribute__ ((always_inline)) { *port = val; }
+ inline static void hi(register port_ptr_t port) __attribute__ ((always_inline)) { hi(); }
+ inline static void lo(register port_ptr_t port) __attribute__ ((always_inline)) { lo(); }
+ inline static void fastset(register port_ptr_t port, register port_t val) __attribute__ ((always_inline)) { *port = val; }
- inline static port_t hival() __attribute__ ((always_inline)) { return FL_NRF_GPIO->OUT | _MASK; }
- inline static port_t loval() __attribute__ ((always_inline)) { return FL_NRF_GPIO->OUT & ~_MASK; }
- inline static port_ptr_t port() __attribute__ ((always_inline)) { return &FL_NRF_GPIO->OUT; }
- inline static port_t mask() __attribute__ ((always_inline)) { return _MASK; }
+ inline static port_t hival() __attribute__ ((always_inline)) { return FL_NRF_GPIO->OUT | _MASK; }
+ inline static port_t loval() __attribute__ ((always_inline)) { return FL_NRF_GPIO->OUT & ~_MASK; }
+ inline static port_ptr_t port() __attribute__ ((always_inline)) { return &FL_NRF_GPIO->OUT; }
+ inline static port_t mask() __attribute__ ((always_inline)) { return _MASK; }
- inline static bool isset() __attribute__ ((always_inline)) { return (FL_NRF_GPIO->IN & _MASK) != 0; }
+ inline static bool isset() __attribute__ ((always_inline)) { return (FL_NRF_GPIO->IN & _MASK) != 0; }
};
diff --git a/platforms/arm/nrf51/fastspi_arm_nrf51.h b/platforms/arm/nrf51/fastspi_arm_nrf51.h
index 6299e89d..6826ebcb 100644
--- a/platforms/arm/nrf51/fastspi_arm_nrf51.h
+++ b/platforms/arm/nrf51/fastspi_arm_nrf51.h
@@ -12,136 +12,135 @@
template <uint8_t _DATA_PIN, uint8_t _CLOCK_PIN, uint32_t _SPI_CLOCK_DIVIDER>
class NRF51SPIOutput {
- struct saveData {
- uint32_t sck;
- uint32_t mosi;
- uint32_t miso;
- uint32_t freq;
- uint32_t enable;
- } mSavedData;
-
- void saveSPIData() {
- mSavedData.sck = NRF_SPI0->PSELSCK;
- mSavedData.mosi = NRF_SPI0->PSELMOSI;
- mSavedData.miso = NRF_SPI0->PSELMISO;
- mSavedData.freq = NRF_SPI0->FREQUENCY;
- mSavedData.enable = NRF_SPI0->ENABLE;
- }
-
- void restoreSPIData() {
- NRF_SPI0->PSELSCK = mSavedData.sck;
- NRF_SPI0->PSELMOSI = mSavedData.mosi;
- NRF_SPI0->PSELMISO = mSavedData.miso;
- NRF_SPI0->FREQUENCY = mSavedData.freq;
- mSavedData.enable = NRF_SPI0->ENABLE;
- }
+ struct saveData {
+ uint32_t sck;
+ uint32_t mosi;
+ uint32_t miso;
+ uint32_t freq;
+ uint32_t enable;
+ } mSavedData;
+
+ void saveSPIData() {
+ mSavedData.sck = NRF_SPI0->PSELSCK;
+ mSavedData.mosi = NRF_SPI0->PSELMOSI;
+ mSavedData.miso = NRF_SPI0->PSELMISO;
+ mSavedData.freq = NRF_SPI0->FREQUENCY;
+ mSavedData.enable = NRF_SPI0->ENABLE;
+ }
+
+ void restoreSPIData() {
+ NRF_SPI0->PSELSCK = mSavedData.sck;
+ NRF_SPI0->PSELMOSI = mSavedData.mosi;
+ NRF_SPI0->PSELMISO = mSavedData.miso;
+ NRF_SPI0->FREQUENCY = mSavedData.freq;
+ mSavedData.enable = NRF_SPI0->ENABLE;
+ }
public:
- NRF51SPIOutput() { FastPin<_DATA_PIN>::setOutput(); FastPin<_CLOCK_PIN>::setOutput(); }
- NRF51SPIOutput(Selectable *pSelect) { FastPin<_DATA_PIN>::setOutput(); FastPin<_CLOCK_PIN>::setOutput(); }
-
- // set the object representing the selectable
- void setSelect(Selectable *pSelect) { /* TODO */ }
-
- // initialize the SPI subssytem
- void init() {
- FastPin<_DATA_PIN>::setOutput();
- FastPin<_CLOCK_PIN>::setOutput();
- NRF_SPI0->PSELSCK = _CLOCK_PIN;
- NRF_SPI0->PSELMOSI = _DATA_PIN;
- NRF_SPI0->PSELMISO = 0xFFFFFFFF;
- NRF_SPI0->FREQUENCY = 0x80000000;
- NRF_SPI0->ENABLE = 1;
- NRF_SPI0->EVENTS_READY = 0;
- }
-
- // latch the CS select
- void select() { saveSPIData(); init(); }
-
- // release the CS select
- void release() { shouldWait(); restoreSPIData(); }
-
- static bool shouldWait(bool wait = false) __attribute__((always_inline)) __attribute__((always_inline)) {
- // static bool sWait=false;
- // bool oldWait = sWait;
- // sWait = wait;
- // never going to bother with waiting since we're always running the spi clock at max speed on the rfduino
- // TODO: When we set clock rate, implement/fix waiting properly, otherwise the world hangs up
- return false;
- }
-
- // wait until all queued up data has been written
- static void waitFully() __attribute__((always_inline)){ if(shouldWait()) { while(NRF_SPI0->EVENTS_READY==0); } NRF_SPI0->INTENCLR; }
- static void wait() __attribute__((always_inline)){ if(shouldWait()) { while(NRF_SPI0->EVENTS_READY==0); } NRF_SPI0->INTENCLR; }
-
- // write a byte out via SPI (returns immediately on writing register)
- static void writeByte(uint8_t b) __attribute__((always_inline)) { wait(); NRF_SPI0->TXD = b; NRF_SPI0->INTENCLR; shouldWait(true); }
-
- // write a word out via SPI (returns immediately on writing register)
- static void writeWord(uint16_t w) __attribute__((always_inline)){ writeByte(w>>8); writeByte(w & 0xFF); }
-
- // A raw set of writing byte values, assumes setup/init/waiting done elsewhere (static for use by adjustment classes)
- static void writeBytesValueRaw(uint8_t value, int len) { while(len--) { writeByte(value); } }
-
- // A full cycle of writing a value for len bytes, including select, release, and waiting
- void writeBytesValue(uint8_t value, int len) {
- select();
- while(len--) {
- writeByte(value);
+ NRF51SPIOutput() { FastPin<_DATA_PIN>::setOutput(); FastPin<_CLOCK_PIN>::setOutput(); }
+ NRF51SPIOutput(Selectable *pSelect) { FastPin<_DATA_PIN>::setOutput(); FastPin<_CLOCK_PIN>::setOutput(); }
+
+ // set the object representing the selectable
+ void setSelect(Selectable *pSelect) { /* TODO */ }
+
+ // initialize the SPI subssytem
+ void init() {
+ FastPin<_DATA_PIN>::setOutput();
+ FastPin<_CLOCK_PIN>::setOutput();
+ NRF_SPI0->PSELSCK = _CLOCK_PIN;
+ NRF_SPI0->PSELMOSI = _DATA_PIN;
+ NRF_SPI0->PSELMISO = 0xFFFFFFFF;
+ NRF_SPI0->FREQUENCY = 0x80000000;
+ NRF_SPI0->ENABLE = 1;
+ NRF_SPI0->EVENTS_READY = 0;
}
- waitFully();
- release();
- }
-
- // A full cycle of writing a raw block of data out, including select, release, and waiting
- template<class D> void writeBytes(uint8_t *data, int len) {
- uint8_t *end = data + len;
- select();
- while(data != end) {
- writeByte(D::adjust(*data++));
+
+ // latch the CS select
+ void select() { saveSPIData(); init(); }
+
+ // release the CS select
+ void release() { shouldWait(); restoreSPIData(); }
+
+ static bool shouldWait(bool wait = false) __attribute__((always_inline)) __attribute__((always_inline)) {
+ // static bool sWait=false;
+ // bool oldWait = sWait;
+ // sWait = wait;
+ // never going to bother with waiting since we're always running the spi clock at max speed on the rfduino
+ // TODO: When we set clock rate, implement/fix waiting properly, otherwise the world hangs up
+ return false;
}
- D::postBlock(len);
- waitFully();
- release();
- }
-
- void writeBytes(uint8_t *data, int len) {
- writeBytes<DATA_NOP>(data, len);
- }
-
- // write a single bit out, which bit from the passed in byte is determined by template parameter
- template <uint8_t BIT> inline static void writeBit(uint8_t b) {
- waitFully();
- NRF_SPI0->ENABLE = 0;
- if(b & 1<<BIT) {
- FastPin<_DATA_PIN>::hi();
- } else {
- FastPin<_DATA_PIN>::lo();
+
+ // wait until all queued up data has been written
+ static void waitFully() __attribute__((always_inline)){ if(shouldWait()) { while(NRF_SPI0->EVENTS_READY==0); } NRF_SPI0->INTENCLR; }
+ static void wait() __attribute__((always_inline)){ if(shouldWait()) { while(NRF_SPI0->EVENTS_READY==0); } NRF_SPI0->INTENCLR; }
+
+ // write a byte out via SPI (returns immediately on writing register)
+ static void writeByte(uint8_t b) __attribute__((always_inline)) { wait(); NRF_SPI0->TXD = b; NRF_SPI0->INTENCLR; shouldWait(true); }
+
+ // write a word out via SPI (returns immediately on writing register)
+ static void writeWord(uint16_t w) __attribute__((always_inline)){ writeByte(w>>8); writeByte(w & 0xFF); }
+
+ // A raw set of writing byte values, assumes setup/init/waiting done elsewhere (static for use by adjustment classes)
+ static void writeBytesValueRaw(uint8_t value, int len) { while(len--) { writeByte(value); } }
+
+ // A full cycle of writing a value for len bytes, including select, release, and waiting
+ void writeBytesValue(uint8_t value, int len) {
+ select();
+ while(len--) {
+ writeByte(value);
+ }
+ waitFully();
+ release();
}
- FastPin<_CLOCK_PIN>::toggle();
- FastPin<_CLOCK_PIN>::toggle();
- NRF_SPI0->ENABLE = 1;
- }
-
- template <uint8_t FLAGS, class D, EOrder RGB_ORDER> void writePixels(PixelController<RGB_ORDER> pixels) {
- select();
- int len = pixels.mLen;
- while(pixels.has(1)) {
- if(FLAGS & FLAG_START_BIT) {
- writeBit<0>(1);
- }
- writeByte(D::adjust(pixels.loadAndScale0()));
- writeByte(D::adjust(pixels.loadAndScale1()));
- writeByte(D::adjust(pixels.loadAndScale2()));
-
- pixels.advanceData();
- pixels.stepDithering();
- }
- D::postBlock(len);
- waitFully();
- release();
- }
+ // A full cycle of writing a raw block of data out, including select, release, and waiting
+ template<class D> void writeBytes(uint8_t *data, int len) {
+ uint8_t *end = data + len;
+ select();
+ while(data != end) {
+ writeByte(D::adjust(*data++));
+ }
+ D::postBlock(len);
+ waitFully();
+ release();
+ }
+
+ void writeBytes(uint8_t *data, int len) {
+ writeBytes<DATA_NOP>(data, len);
+ }
+
+ // write a single bit out, which bit from the passed in byte is determined by template parameter
+ template <uint8_t BIT> inline static void writeBit(uint8_t b) {
+ waitFully();
+ NRF_SPI0->ENABLE = 0;
+ if(b & 1<<BIT) {
+ FastPin<_DATA_PIN>::hi();
+ } else {
+ FastPin<_DATA_PIN>::lo();
+ }
+ FastPin<_CLOCK_PIN>::toggle();
+ FastPin<_CLOCK_PIN>::toggle();
+ NRF_SPI0->ENABLE = 1;
+ }
+
+ template <uint8_t FLAGS, class D, EOrder RGB_ORDER> void writePixels(PixelController<RGB_ORDER> pixels) {
+ select();
+ int len = pixels.mLen;
+ while(pixels.has(1)) {
+ if(FLAGS & FLAG_START_BIT) {
+ writeBit<0>(1);
+ }
+ writeByte(D::adjust(pixels.loadAndScale0()));
+ writeByte(D::adjust(pixels.loadAndScale1()));
+ writeByte(D::adjust(pixels.loadAndScale2()));
+
+ pixels.advanceData();
+ pixels.stepDithering();
+ }
+ D::postBlock(len);
+ waitFully();
+ release();
+ }
};
#endif
diff --git a/platforms/arm/nrf52/arbiter_nrf52.h b/platforms/arm/nrf52/arbiter_nrf52.h
index 5a6aa92a..8972d2d2 100644
--- a/platforms/arm/nrf52/arbiter_nrf52.h
+++ b/platforms/arm/nrf52/arbiter_nrf52.h
@@ -36,7 +36,6 @@ static_assert(FASTLED_NRF52_PWM_INSTANCE_COUNT > 0, "Instance count must be grea
template <uint32_t _PWM_ID>
class PWM_Arbiter {
-
private:
static_assert(_PWM_ID < 32, "PWM_ID over 31 breaks current arbitration bitmask");
//const uint32_t _ACQUIRE_MASK = (1u << _PWM_ID) ;
diff --git a/platforms/arm/nrf52/clockless_arm_nrf52.h b/platforms/arm/nrf52/clockless_arm_nrf52.h
index 56a1dbe0..613ff282 100644
--- a/platforms/arm/nrf52/clockless_arm_nrf52.h
+++ b/platforms/arm/nrf52/clockless_arm_nrf52.h
@@ -15,7 +15,6 @@
// NOTE: Update platforms.cpp in root of FastLED library if this changes
#define FASTLED_NRF52_PWM_ID 0
-
extern uint32_t isrCount;
diff --git a/platforms/arm/nrf52/fastpin_arm_nrf52.h b/platforms/arm/nrf52/fastpin_arm_nrf52.h
index 7a780876..9d0a8ec9 100644
--- a/platforms/arm/nrf52/fastpin_arm_nrf52.h
+++ b/platforms/arm/nrf52/fastpin_arm_nrf52.h
@@ -90,54 +90,54 @@ struct __generated_struct_NRF_P1 {
// The actual class template can then use a typename, for what is essentially a constexpr NRF_GPIO_Type*
template <uint32_t _MASK, typename _PORT, uint8_t _PORT_NUMBER, uint8_t _PIN_NUMBER> class _ARMPIN {
public:
- typedef volatile uint32_t * port_ptr_t;
- typedef uint32_t port_t;
+ typedef volatile uint32_t * port_ptr_t;
+ typedef uint32_t port_t;
- FASTLED_NRF52_INLINE_ATTRIBUTE static void setOutput() {
- // OK for this to be more than one instruction, as unusual to quickly switch input/output modes
- nrf_gpio_cfg(
- nrf_pin(),
- NRF_GPIO_PIN_DIR_OUTPUT, // set pin as output
- NRF_GPIO_PIN_INPUT_DISCONNECT, // disconnect the input buffering
- NRF_GPIO_PIN_NOPULL, // neither pull-up nor pull-down resistors enabled
- NRF_GPIO_PIN_H0H1, // high drive mode required for faster speeds
- NRF_GPIO_PIN_NOSENSE // pin sense level disabled
- );
- }
- FASTLED_NRF52_INLINE_ATTRIBUTE static void setInput() {
- // OK for this to be more than one instruction, as unusual to quickly switch input/output modes
- nrf_gpio_cfg(
- nrf_pin(),
- NRF_GPIO_PIN_DIR_INPUT, // set pin as input
- NRF_GPIO_PIN_INPUT_DISCONNECT, // disconnect the input buffering
- NRF_GPIO_PIN_NOPULL, // neither pull-up nor pull-down resistors enabled
- NRF_GPIO_PIN_H0H1, // high drive mode required for faster speeds
- NRF_GPIO_PIN_NOSENSE // pin sense level disabled
- );
- }
- FASTLED_NRF52_INLINE_ATTRIBUTE static void hi() { (reinterpret_cast<NRF_GPIO_Type*>(_PORT::r()))->OUTSET = _MASK; } // sets _MASK in the SET OUTPUT register (output set high)
- FASTLED_NRF52_INLINE_ATTRIBUTE static void lo() { (reinterpret_cast<NRF_GPIO_Type*>(_PORT::r()))->OUTCLR = _MASK; } // sets _MASK in the CLEAR OUTPUT register (output set low)
- FASTLED_NRF52_INLINE_ATTRIBUTE static void toggle() { (reinterpret_cast<NRF_GPIO_Type*>(_PORT::r()))->OUT ^= _MASK; } // toggles _MASK bits in the OUTPUT GPIO port directly
- FASTLED_NRF52_INLINE_ATTRIBUTE static void strobe() { toggle(); toggle(); } // BUGBUG -- Is this used by FastLED? Without knowing (for example) SPI Speed?
- FASTLED_NRF52_INLINE_ATTRIBUTE static port_t hival() { return (reinterpret_cast<NRF_GPIO_Type*>(_PORT::r()))->OUT | _MASK; } // sets all _MASK bit(s) in the OUTPUT GPIO port to 1
- FASTLED_NRF52_INLINE_ATTRIBUTE static port_t loval() { return (reinterpret_cast<NRF_GPIO_Type*>(_PORT::r()))->OUT & ~_MASK; } // sets all _MASK bit(s) in the OUTPUT GPIO port to 0
- FASTLED_NRF52_INLINE_ATTRIBUTE static port_ptr_t port() { return &((reinterpret_cast<NRF_GPIO_Type*>(_PORT::r()))->OUT); } // gets raw pointer to OUTPUT GPIO port
- FASTLED_NRF52_INLINE_ATTRIBUTE static port_ptr_t cport() { return &((reinterpret_cast<NRF_GPIO_Type*>(_PORT::r()))->OUTCLR); } // gets raw pointer to SET DIRECTION GPIO port
- FASTLED_NRF52_INLINE_ATTRIBUTE static port_ptr_t sport() { return &((reinterpret_cast<NRF_GPIO_Type*>(_PORT::r()))->OUTSET); } // gets raw pointer to CLEAR DIRECTION GPIO port
- FASTLED_NRF52_INLINE_ATTRIBUTE static port_t mask() { return _MASK; } // gets the value of _MASK
- FASTLED_NRF52_INLINE_ATTRIBUTE static void hi (register port_ptr_t port) { hi(); } // sets _MASK in the SET OUTPUT register (output set high)
- FASTLED_NRF52_INLINE_ATTRIBUTE static void lo (register port_ptr_t port) { lo(); } // sets _MASK in the CLEAR OUTPUT register (output set low)
- FASTLED_NRF52_INLINE_ATTRIBUTE static void set(register port_t val ) { (reinterpret_cast<NRF_GPIO_Type*>(_PORT::r()))->OUT = val; } // sets entire port's value (optimization used by FastLED)
- FASTLED_NRF52_INLINE_ATTRIBUTE static void fastset(register port_ptr_t port, register port_t val) { *port = val; }
- constexpr static uint32_t nrf_pin2() { return NRF_GPIO_PIN_MAP(_PORT_NUMBER, _PIN_NUMBER); }
- constexpr static bool LowSpeedOnlyRecommended() {
- // Caller must always determine if high speed use if allowed on a given pin,
- // because it depends on more than just the chip packaging ... it depends on entire board (and even system) design.
- return false; // choosing default to be FALSE, to allow users to ATTEMPT to use high-speed on pins where support is not known
- }
- // Expose the nrf pin (port/pin combined), port, and pin as properties (e.g., for setting up SPI)
+ FASTLED_NRF52_INLINE_ATTRIBUTE static void setOutput() {
+ // OK for this to be more than one instruction, as unusual to quickly switch input/output modes
+ nrf_gpio_cfg(
+ nrf_pin(),
+ NRF_GPIO_PIN_DIR_OUTPUT, // set pin as output
+ NRF_GPIO_PIN_INPUT_DISCONNECT, // disconnect the input buffering
+ NRF_GPIO_PIN_NOPULL, // neither pull-up nor pull-down resistors enabled
+ NRF_GPIO_PIN_H0H1, // high drive mode required for faster speeds
+ NRF_GPIO_PIN_NOSENSE // pin sense level disabled
+ );
+ }
+ FASTLED_NRF52_INLINE_ATTRIBUTE static void setInput() {
+ // OK for this to be more than one instruction, as unusual to quickly switch input/output modes
+ nrf_gpio_cfg(
+ nrf_pin(),
+ NRF_GPIO_PIN_DIR_INPUT, // set pin as input
+ NRF_GPIO_PIN_INPUT_DISCONNECT, // disconnect the input buffering
+ NRF_GPIO_PIN_NOPULL, // neither pull-up nor pull-down resistors enabled
+ NRF_GPIO_PIN_H0H1, // high drive mode required for faster speeds
+ NRF_GPIO_PIN_NOSENSE // pin sense level disabled
+ );
+ }
+ FASTLED_NRF52_INLINE_ATTRIBUTE static void hi() { (reinterpret_cast<NRF_GPIO_Type*>(_PORT::r()))->OUTSET = _MASK; } // sets _MASK in the SET OUTPUT register (output set high)
+ FASTLED_NRF52_INLINE_ATTRIBUTE static void lo() { (reinterpret_cast<NRF_GPIO_Type*>(_PORT::r()))->OUTCLR = _MASK; } // sets _MASK in the CLEAR OUTPUT register (output set low)
+ FASTLED_NRF52_INLINE_ATTRIBUTE static void toggle() { (reinterpret_cast<NRF_GPIO_Type*>(_PORT::r()))->OUT ^= _MASK; } // toggles _MASK bits in the OUTPUT GPIO port directly
+ FASTLED_NRF52_INLINE_ATTRIBUTE static void strobe() { toggle(); toggle(); } // BUGBUG -- Is this used by FastLED? Without knowing (for example) SPI Speed?
+ FASTLED_NRF52_INLINE_ATTRIBUTE static port_t hival() { return (reinterpret_cast<NRF_GPIO_Type*>(_PORT::r()))->OUT | _MASK; } // sets all _MASK bit(s) in the OUTPUT GPIO port to 1
+ FASTLED_NRF52_INLINE_ATTRIBUTE static port_t loval() { return (reinterpret_cast<NRF_GPIO_Type*>(_PORT::r()))->OUT & ~_MASK; } // sets all _MASK bit(s) in the OUTPUT GPIO port to 0
+ FASTLED_NRF52_INLINE_ATTRIBUTE static port_ptr_t port() { return &((reinterpret_cast<NRF_GPIO_Type*>(_PORT::r()))->OUT); } // gets raw pointer to OUTPUT GPIO port
+ FASTLED_NRF52_INLINE_ATTRIBUTE static port_ptr_t cport() { return &((reinterpret_cast<NRF_GPIO_Type*>(_PORT::r()))->OUTCLR); } // gets raw pointer to SET DIRECTION GPIO port
+ FASTLED_NRF52_INLINE_ATTRIBUTE static port_ptr_t sport() { return &((reinterpret_cast<NRF_GPIO_Type*>(_PORT::r()))->OUTSET); } // gets raw pointer to CLEAR DIRECTION GPIO port
+ FASTLED_NRF52_INLINE_ATTRIBUTE static port_t mask() { return _MASK; } // gets the value of _MASK
+ FASTLED_NRF52_INLINE_ATTRIBUTE static void hi (register port_ptr_t port) { hi(); } // sets _MASK in the SET OUTPUT register (output set high)
+ FASTLED_NRF52_INLINE_ATTRIBUTE static void lo (register port_ptr_t port) { lo(); } // sets _MASK in the CLEAR OUTPUT register (output set low)
+ FASTLED_NRF52_INLINE_ATTRIBUTE static void set(register port_t val ) { (reinterpret_cast<NRF_GPIO_Type*>(_PORT::r()))->OUT = val; } // sets entire port's value (optimization used by FastLED)
+ FASTLED_NRF52_INLINE_ATTRIBUTE static void fastset(register port_ptr_t port, register port_t val) { *port = val; }
+ constexpr static uint32_t nrf_pin2() { return NRF_GPIO_PIN_MAP(_PORT_NUMBER, _PIN_NUMBER); }
+ constexpr static bool LowSpeedOnlyRecommended() {
+ // Caller must always determine if high speed use if allowed on a given pin,
+ // because it depends on more than just the chip packaging ... it depends on entire board (and even system) design.
+ return false; // choosing default to be FALSE, to allow users to ATTEMPT to use high-speed on pins where support is not known
+ }
+ // Expose the nrf pin (port/pin combined), port, and pin as properties (e.g., for setting up SPI)
- FASTLED_NRF52_INLINE_ATTRIBUTE static uint32_t nrf_pin() { return NRF_GPIO_PIN_MAP(_PORT_NUMBER, _PIN_NUMBER); }
+ FASTLED_NRF52_INLINE_ATTRIBUTE static uint32_t nrf_pin() { return NRF_GPIO_PIN_MAP(_PORT_NUMBER, _PIN_NUMBER); }
};
//
@@ -152,7 +152,7 @@ public:
// _FL_DEFPIN(47, 47, 1);
//
-#define _FL_DEFPIN(ARDUINO_PIN, BOARD_PIN, BOARD_PORT) \
+#define _FL_DEFPIN(ARDUINO_PIN, BOARD_PIN, BOARD_PORT) \
template<> class FastPin<ARDUINO_PIN> : \
public _ARMPIN< \
1u << (BOARD_PIN & 31u), \
diff --git a/platforms/arm/nrf52/fastspi_arm_nrf52.h b/platforms/arm/nrf52/fastspi_arm_nrf52.h
index 9c1a2198..89d006e3 100644
--- a/platforms/arm/nrf52/fastspi_arm_nrf52.h
+++ b/platforms/arm/nrf52/fastspi_arm_nrf52.h
@@ -23,7 +23,6 @@
/// SPI_CLOCK_DIVIDER is number of CPU clock cycles per SPI transmission bit?
template <uint8_t _DATA_PIN, uint8_t _CLOCK_PIN, uint32_t _SPI_CLOCK_DIVIDER>
class NRF52SPIOutput {
-
private:
// static variables -- always using same SPIM instance
static bool s_InUse;
diff --git a/platforms/arm/sam/clockless_arm_sam.h b/platforms/arm/sam/clockless_arm_sam.h
index 0fc621d2..737a4555 100644
--- a/platforms/arm/sam/clockless_arm_sam.h
+++ b/platforms/arm/sam/clockless_arm_sam.h
@@ -22,6 +22,7 @@ class ClocklessController : public CPixelLEDController<RGB_ORDER> {
data_t mPinMask;
data_ptr_t mPort;
CMinWait<WAIT_TIME> mWait;
+
public:
virtual void init() {
FastPinBB<DATA_PIN>::setOutput();
@@ -32,15 +33,14 @@ public:
virtual uint16_t getMaxRefreshRate() const { return 400; }
protected:
-
- virtual void showPixels(PixelController<RGB_ORDER> & pixels) {
- mWait.wait();
- if(!showRGBInternal(pixels)) {
- sei(); delayMicroseconds(WAIT_TIME); cli();
- showRGBInternal(pixels);
+ virtual void showPixels(PixelController<RGB_ORDER> & pixels) {
+ mWait.wait();
+ if(!showRGBInternal(pixels)) {
+ sei(); delayMicroseconds(WAIT_TIME); cli();
+ showRGBInternal(pixels);
+ }
+ mWait.mark();
}
- mWait.mark();
- }
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
@@ -90,7 +90,9 @@ protected:
#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 0; }
+ if((DUE_TIMER_VAL - next_mark) > ((WAIT_TIME-INTERRUPT_THRESHOLD)*CLKS_PER_US)) {
+ sei(); TC_Stop(DUE_TIMER,DUE_TIMER_CHANNEL); return 0;
+ }
}
#endif
diff --git a/platforms/arm/sam/clockless_block_arm_sam.h b/platforms/arm/sam/clockless_block_arm_sam.h
index 355f945d..a1799891 100644
--- a/platforms/arm/sam/clockless_block_arm_sam.h
+++ b/platforms/arm/sam/clockless_block_arm_sam.h
@@ -21,8 +21,8 @@ FASTLED_NAMESPACE_BEGIN
#define PORTB_FIRST_PIN 90
typedef union {
- uint8_t bytes[8];
- uint32_t raw[2];
+ uint8_t bytes[8];
+ uint32_t raw[2];
} Lines;
#define TADJUST 0
@@ -37,144 +37,143 @@ class InlineBlockClocklessController : public CPixelLEDController<RGB_ORDER, LAN
data_t mPinMask;
data_ptr_t mPort;
CMinWait<WAIT_TIME> mWait;
+
public:
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();
- case 7: FastPin<58>::setOutput();
- case 6: FastPin<100>::setOutput();
- case 5: FastPin<59>::setOutput();
- case 4: FastPin<60>::setOutput();
- case 3: FastPin<61>::setOutput();
- case 2: FastPin<68>::setOutput();
- case 1: FastPin<69>::setOutput();
- }
- } else if(FIRST_PIN == PORTD_FIRST_PIN) {
- switch(LANES) {
- case 8: FastPin<11>::setOutput();
- case 7: FastPin<29>::setOutput();
- case 6: FastPin<15>::setOutput();
- case 5: FastPin<14>::setOutput();
- case 4: FastPin<28>::setOutput();
- case 3: FastPin<27>::setOutput();
- case 2: FastPin<26>::setOutput();
- case 1: FastPin<25>::setOutput();
- }
- } else if(FIRST_PIN == PORTB_FIRST_PIN) {
- switch(LANES) {
- case 8: FastPin<97>::setOutput();
- case 7: FastPin<96>::setOutput();
- case 6: FastPin<95>::setOutput();
- case 5: FastPin<94>::setOutput();
- case 4: FastPin<93>::setOutput();
- case 3: FastPin<92>::setOutput();
- case 2: FastPin<91>::setOutput();
- case 1: FastPin<90>::setOutput();
- }
- }
- mPinMask = FastPin<FIRST_PIN>::mask();
- mPort = FastPin<FIRST_PIN>::port();
- }
-
- virtual uint16_t getMaxRefreshRate() const { return 400; }
-
- virtual void showPixels(PixelController<RGB_ORDER, LANES, PORT_MASK> & pixels) {
- mWait.wait();
- showRGBInternal(pixels);
- sei();
- mWait.mark();
- }
-
- static uint32_t showRGBInternal(PixelController<RGB_ORDER, LANES, PORT_MASK> &allpixels) {
- // Serial.println("Entering show");
-
- int nLeds = allpixels.mLen;
-
- // Setup the pixel controller and load/scale the first byte
- Lines b0,b1,b2;
-
- allpixels.preStepFirstByteDithering();
- for(uint8_t i = 0; i < LANES; i++) {
- b0.bytes[i] = allpixels.loadAndScale0(i);
- }
-
- // Setup and start the clock
- 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);
-
- #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;
+ 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();
+ case 7: FastPin<58>::setOutput();
+ case 6: FastPin<100>::setOutput();
+ case 5: FastPin<59>::setOutput();
+ case 4: FastPin<60>::setOutput();
+ case 3: FastPin<61>::setOutput();
+ case 2: FastPin<68>::setOutput();
+ case 1: FastPin<69>::setOutput();
+ }
+ } else if(FIRST_PIN == PORTD_FIRST_PIN) {
+ switch(LANES) {
+ case 8: FastPin<11>::setOutput();
+ case 7: FastPin<29>::setOutput();
+ case 6: FastPin<15>::setOutput();
+ case 5: FastPin<14>::setOutput();
+ case 4: FastPin<28>::setOutput();
+ case 3: FastPin<27>::setOutput();
+ case 2: FastPin<26>::setOutput();
+ case 1: FastPin<25>::setOutput();
+ }
+ } else if(FIRST_PIN == PORTB_FIRST_PIN) {
+ switch(LANES) {
+ case 8: FastPin<97>::setOutput();
+ case 7: FastPin<96>::setOutput();
+ case 6: FastPin<95>::setOutput();
+ case 5: FastPin<94>::setOutput();
+ case 4: FastPin<93>::setOutput();
+ case 3: FastPin<92>::setOutput();
+ case 2: FastPin<91>::setOutput();
+ case 1: FastPin<90>::setOutput();
+ }
}
- }
- #endif
+ mPinMask = FastPin<FIRST_PIN>::mask();
+ mPort = FastPin<FIRST_PIN>::port();
+ }
- // Write first byte, read next byte
- writeBits<8+XTRA0,1>(next_mark, b0, b1, allpixels);
+ virtual uint16_t getMaxRefreshRate() const { return 400; }
- // Write second byte, read 3rd byte
- writeBits<8+XTRA0,2>(next_mark, b1, b2, allpixels);
+ virtual void showPixels(PixelController<RGB_ORDER, LANES, PORT_MASK> & pixels) {
+ mWait.wait();
+ showRGBInternal(pixels);
+ sei();
+ mWait.mark();
+ }
- allpixels.advanceData();
- // Write third byte
- writeBits<8+XTRA0,0>(next_mark, b2, b0, allpixels);
+ static uint32_t showRGBInternal(PixelController<RGB_ORDER, LANES, PORT_MASK> &allpixels) {
+ // Serial.println("Entering show");
- #if (FASTLED_ALLOW_INTERRUPTS == 1)
- sei();
- #endif
- }
+ int nLeds = allpixels.mLen;
- return DUE_TIMER_VAL;
- }
+ // Setup the pixel controller and load/scale the first byte
+ Lines b0,b1,b2;
- 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);
+ allpixels.preStepFirstByteDithering();
+ for(uint8_t i = 0; i < LANES; i++) {
+ b0.bytes[i] = allpixels.loadAndScale0(i);
+ }
- register uint8_t d = pixels.template getd<PX>(pixels);
- register uint8_t scale = pixels.template getscale<PX>(pixels);
+ // Setup and start the clock
+ 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);
+
+ #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);
+
+ // Write second byte, read 3rd byte
+ writeBits<8+XTRA0,2>(next_mark, b1, b2, allpixels);
+
+ allpixels.advanceData();
+ // Write third byte
+ writeBits<8+XTRA0,0>(next_mark, b2, b0, allpixels);
+
+ #if (FASTLED_ALLOW_INTERRUPTS == 1)
+ sei();
+ #endif
+ }
- for(uint32_t i = 0; (i < LANES) && (i<8); i++) {
- while(DUE_TIMER_VAL < next_mark);
- next_mark = (DUE_TIMER_VAL+TOTAL);
+ return DUE_TIMER_VAL;
+ }
- *FastPin<FIRST_PIN>::sport() = PORT_MASK;
+ 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);
- while((next_mark - DUE_TIMER_VAL) > (T2+T3+6));
- *FastPin<FIRST_PIN>::cport() = (~b2.bytes[7-i]) & PORT_MASK;
+ register uint8_t d = pixels.template getd<PX>(pixels);
+ register uint8_t scale = pixels.template getscale<PX>(pixels);
- while((next_mark - (DUE_TIMER_VAL)) > T3);
- *FastPin<FIRST_PIN>::cport() = PORT_MASK;
+ for(uint32_t i = 0; (i < LANES) && (i<8); i++) {
+ while(DUE_TIMER_VAL < next_mark);
+ next_mark = (DUE_TIMER_VAL+TOTAL);
- b3.bytes[i] = pixels.template loadAndScale<PX>(pixels,i,d,scale);
- }
+ *FastPin<FIRST_PIN>::sport() = PORT_MASK;
- for(uint32_t 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) > (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;
- 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);
+ *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;
+ }
+ }
};
#endif
diff --git a/platforms/arm/sam/fastpin_arm_sam.h b/platforms/arm/sam/fastpin_arm_sam.h
index 339c5e75..e1354c73 100644
--- a/platforms/arm/sam/fastpin_arm_sam.h
+++ b/platforms/arm/sam/fastpin_arm_sam.h
@@ -92,7 +92,6 @@ _FL_IO(D,3);
#if defined(__SAM3X8E__)
-
#define MAX_PIN 78
_FL_DEFPIN(0, 8, A); _FL_DEFPIN(1, 9, A); _FL_DEFPIN(2, 25, B); _FL_DEFPIN(3, 28, C);
_FL_DEFPIN(4, 26, C); _FL_DEFPIN(5, 25, C); _FL_DEFPIN(6, 24, C); _FL_DEFPIN(7, 23, C);
diff --git a/platforms/arm/stm32/clockless_arm_stm32.h b/platforms/arm/stm32/clockless_arm_stm32.h
index e4b4de08..1cc1f667 100644
--- a/platforms/arm/stm32/clockless_arm_stm32.h
+++ b/platforms/arm/stm32/clockless_arm_stm32.h
@@ -9,118 +9,118 @@ FASTLED_NAMESPACE_BEGIN
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 CPixelLEDController<RGB_ORDER> {
- typedef typename FastPin<DATA_PIN>::port_ptr_t data_ptr_t;
- typedef typename FastPin<DATA_PIN>::port_t data_t;
+ typedef typename FastPin<DATA_PIN>::port_ptr_t data_ptr_t;
+ typedef typename FastPin<DATA_PIN>::port_t data_t;
+
+ data_t mPinMask;
+ data_ptr_t mPort;
+ CMinWait<WAIT_TIME> mWait;
- data_t mPinMask;
- data_ptr_t mPort;
- CMinWait<WAIT_TIME> mWait;
public:
- virtual void init() {
- FastPin<DATA_PIN>::setOutput();
- mPinMask = FastPin<DATA_PIN>::mask();
- mPort = FastPin<DATA_PIN>::port();
- }
+ virtual void init() {
+ FastPin<DATA_PIN>::setOutput();
+ mPinMask = FastPin<DATA_PIN>::mask();
+ mPort = FastPin<DATA_PIN>::port();
+ }
- virtual uint16_t getMaxRefreshRate() const { return 400; }
+ virtual uint16_t getMaxRefreshRate() const { return 400; }
protected:
-
- virtual void showPixels(PixelController<RGB_ORDER> & pixels) {
- mWait.wait();
- if(!showRGBInternal(pixels)) {
- sei(); delayMicroseconds(WAIT_TIME); cli();
- showRGBInternal(pixels);
+ virtual void showPixels(PixelController<RGB_ORDER> & pixels) {
+ mWait.wait();
+ if(!showRGBInternal(pixels)) {
+ sei(); delayMicroseconds(WAIT_TIME); cli();
+ showRGBInternal(pixels);
+ }
+ mWait.mark();
}
- mWait.mark();
- }
#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) {
- for(register uint32_t i = BITS-1; i > 0; i--) {
- while(_CYCCNT < (T1+T2+T3-20));
- FastPin<DATA_PIN>::fastset(port, hi);
- _CYCCNT = 4;
- if(b&0x80) {
- while(_CYCCNT < (T1+T2-20));
- FastPin<DATA_PIN>::fastset(port, lo);
- } else {
- while(_CYCCNT < (T1-10));
- FastPin<DATA_PIN>::fastset(port, lo);
- }
- b <<= 1;
+ 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--) {
+ while(_CYCCNT < (T1+T2+T3-20));
+ FastPin<DATA_PIN>::fastset(port, hi);
+ _CYCCNT = 4;
+ if(b&0x80) {
+ while(_CYCCNT < (T1+T2-20));
+ FastPin<DATA_PIN>::fastset(port, lo);
+ } else {
+ while(_CYCCNT < (T1-10));
+ FastPin<DATA_PIN>::fastset(port, lo);
+ }
+ b <<= 1;
+ }
+
+ while(_CYCCNT < (T1+T2+T3-20));
+ FastPin<DATA_PIN>::fastset(port, hi);
+ _CYCCNT = 4;
+
+ if(b&0x80) {
+ while(_CYCCNT < (T1+T2-20));
+ FastPin<DATA_PIN>::fastset(port, lo);
+ } else {
+ while(_CYCCNT < (T1-10));
+ FastPin<DATA_PIN>::fastset(port, lo);
+ }
}
- while(_CYCCNT < (T1+T2+T3-20));
- FastPin<DATA_PIN>::fastset(port, hi);
- _CYCCNT = 4;
-
- if(b&0x80) {
- while(_CYCCNT < (T1+T2-20));
- FastPin<DATA_PIN>::fastset(port, lo);
- } else {
- while(_CYCCNT < (T1-10));
- FastPin<DATA_PIN>::fastset(port, lo);
+ // 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) {
+ // Get access to the clock
+ CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
+ DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;
+ DWT->CYCCNT = 0;
+
+ register data_ptr_t port = FastPin<DATA_PIN>::port();
+ register data_t hi = *port | FastPin<DATA_PIN>::mask();;
+ register data_t lo = *port & ~FastPin<DATA_PIN>::mask();;
+ *port = lo;
+
+ // Setup the pixel controller and load/scale the first byte
+ pixels.preStepFirstByteDithering();
+ register uint8_t b = pixels.loadAndScale0();
+
+ cli();
+
+ uint32_t next_mark = (T1+T2+T3);
+
+ DWT->CYCCNT = 0;
+ 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(DWT->CYCCNT > next_mark) {
+ if((DWT->CYCCNT-next_mark) > ((WAIT_TIME-INTERRUPT_THRESHOLD)*CLKS_PER_US)) { sei(); return 0; }
+ }
+
+ hi = *port | FastPin<DATA_PIN>::mask();
+ lo = *port & ~FastPin<DATA_PIN>::mask();
+ #endif
+
+ // Write first byte, read next byte
+ writeBits<8+XTRA0>(next_mark, port, hi, lo, b);
+ b = pixels.loadAndScale1();
+
+ // Write second byte, read 3rd byte
+ writeBits<8+XTRA0>(next_mark, port, hi, lo, b);
+ b = pixels.loadAndScale2();
+
+ // 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
+ };
+
+ sei();
+ return DWT->CYCCNT;
}
- }
-
- // 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) {
- // Get access to the clock
- CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
- DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;
- DWT->CYCCNT = 0;
-
- register data_ptr_t port = FastPin<DATA_PIN>::port();
- register data_t hi = *port | FastPin<DATA_PIN>::mask();;
- register data_t lo = *port & ~FastPin<DATA_PIN>::mask();;
- *port = lo;
-
- // Setup the pixel controller and load/scale the first byte
- pixels.preStepFirstByteDithering();
- register uint8_t b = pixels.loadAndScale0();
-
- cli();
-
- uint32_t next_mark = (T1+T2+T3);
-
- DWT->CYCCNT = 0;
- 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(DWT->CYCCNT > next_mark) {
- if((DWT->CYCCNT-next_mark) > ((WAIT_TIME-INTERRUPT_THRESHOLD)*CLKS_PER_US)) { sei(); return 0; }
- }
-
- hi = *port | FastPin<DATA_PIN>::mask();
- lo = *port & ~FastPin<DATA_PIN>::mask();
- #endif
-
- // Write first byte, read next byte
- writeBits<8+XTRA0>(next_mark, port, hi, lo, b);
- b = pixels.loadAndScale1();
-
- // Write second byte, read 3rd byte
- writeBits<8+XTRA0>(next_mark, port, hi, lo, b);
- b = pixels.loadAndScale2();
-
- // 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
- };
-
- sei();
- return DWT->CYCCNT;
- }
};
FASTLED_NAMESPACE_END
- #endif
+#endif
diff --git a/platforms/arm/stm32/cm3_regs.h b/platforms/arm/stm32/cm3_regs.h
index f81f24cb..7bb7f759 100644
--- a/platforms/arm/stm32/cm3_regs.h
+++ b/platforms/arm/stm32/cm3_regs.h
@@ -4,20 +4,20 @@
#include <stdint.h>
#ifdef __cplusplus
- #define __I volatile /*!< Defines 'read only' permissions */
+#define __I volatile /*!< Defines 'read only' permissions */
#else
- #define __I volatile const /*!< Defines 'read only' permissions */
+#define __I volatile const /*!< Defines 'read only' permissions */
#endif
-#define __O volatile /*!< Defines 'write only' permissions */
-#define __IO volatile /*!< Defines 'read / write' permissions */
+#define __O volatile /*!< Defines 'write only' permissions */
+#define __IO volatile /*!< Defines 'read / write' permissions */
typedef struct
{
- __IO uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */
- __O uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */
- __IO uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */
- __IO uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */
+ __IO uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */
+ __O uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */
+ __IO uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */
+ __IO uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */
} CoreDebug_Type;
#define CoreDebug_BASE (0xE000EDF0UL) /*!< Core Debug Base Address */
@@ -28,29 +28,29 @@ typedef struct
typedef struct
{
- __IO uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */
- __IO uint32_t CYCCNT; /*!< Offset: 0x004 (R/W) Cycle Count Register */
- __IO uint32_t CPICNT; /*!< Offset: 0x008 (R/W) CPI Count Register */
- __IO uint32_t EXCCNT; /*!< Offset: 0x00C (R/W) Exception Overhead Count Register */
- __IO uint32_t SLEEPCNT; /*!< Offset: 0x010 (R/W) Sleep Count Register */
- __IO uint32_t LSUCNT; /*!< Offset: 0x014 (R/W) LSU Count Register */
- __IO uint32_t FOLDCNT; /*!< Offset: 0x018 (R/W) Folded-instruction Count Register */
- __I uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */
- __IO uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */
- __IO uint32_t MASK0; /*!< Offset: 0x024 (R/W) Mask Register 0 */
- __IO uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */
- uint32_t RESERVED0[1];
- __IO uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */
- __IO uint32_t MASK1; /*!< Offset: 0x034 (R/W) Mask Register 1 */
- __IO uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */
- uint32_t RESERVED1[1];
- __IO uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */
- __IO uint32_t MASK2; /*!< Offset: 0x044 (R/W) Mask Register 2 */
- __IO uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */
- uint32_t RESERVED2[1];
- __IO uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */
- __IO uint32_t MASK3; /*!< Offset: 0x054 (R/W) Mask Register 3 */
- __IO uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */
+ __IO uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */
+ __IO uint32_t CYCCNT; /*!< Offset: 0x004 (R/W) Cycle Count Register */
+ __IO uint32_t CPICNT; /*!< Offset: 0x008 (R/W) CPI Count Register */
+ __IO uint32_t EXCCNT; /*!< Offset: 0x00C (R/W) Exception Overhead Count Register */
+ __IO uint32_t SLEEPCNT; /*!< Offset: 0x010 (R/W) Sleep Count Register */
+ __IO uint32_t LSUCNT; /*!< Offset: 0x014 (R/W) LSU Count Register */
+ __IO uint32_t FOLDCNT; /*!< Offset: 0x018 (R/W) Folded-instruction Count Register */
+ __I uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */
+ __IO uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */
+ __IO uint32_t MASK0; /*!< Offset: 0x024 (R/W) Mask Register 0 */
+ __IO uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */
+ uint32_t RESERVED0[1];
+ __IO uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */
+ __IO uint32_t MASK1; /*!< Offset: 0x034 (R/W) Mask Register 1 */
+ __IO uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */
+ uint32_t RESERVED1[1];
+ __IO uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */
+ __IO uint32_t MASK2; /*!< Offset: 0x044 (R/W) Mask Register 2 */
+ __IO uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */
+ uint32_t RESERVED2[1];
+ __IO uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */
+ __IO uint32_t MASK3; /*!< Offset: 0x054 (R/W) Mask Register 3 */
+ __IO uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */
} DWT_Type;
diff --git a/platforms/arm/stm32/fastpin_arm_stm32.h b/platforms/arm/stm32/fastpin_arm_stm32.h
index 274d0f60..bc69912c 100644
--- a/platforms/arm/stm32/fastpin_arm_stm32.h
+++ b/platforms/arm/stm32/fastpin_arm_stm32.h
@@ -16,55 +16,56 @@ FASTLED_NAMESPACE_BEGIN
/// The registers are data output, set output, clear output, toggle output, input, and direction
template<uint8_t PIN, uint8_t _BIT, uint32_t _MASK, typename _GPIO> class _ARMPIN {
+
public:
- typedef volatile uint32_t * port_ptr_t;
- typedef uint32_t port_t;
-
- #if 0
- inline static void setOutput() {
- if(_BIT<8) {
- _CRL::r() = (_CRL::r() & (0xF << (_BIT*4)) | (0x1 << (_BIT*4));
- } else {
- _CRH::r() = (_CRH::r() & (0xF << ((_BIT-8)*4))) | (0x1 << ((_BIT-8)*4));
+ typedef volatile uint32_t * port_ptr_t;
+ typedef uint32_t port_t;
+
+ #if 0
+ inline static void setOutput() {
+ if(_BIT<8) {
+ _CRL::r() = (_CRL::r() & (0xF << (_BIT*4)) | (0x1 << (_BIT*4));
+ } else {
+ _CRH::r() = (_CRH::r() & (0xF << ((_BIT-8)*4))) | (0x1 << ((_BIT-8)*4));
+ }
}
- }
- inline static void setInput() { /* TODO */ } // TODO: preform MUX config { _PDDR::r() &= ~_MASK; }
- #endif
+ inline static void setInput() { /* TODO */ } // TODO: preform MUX config { _PDDR::r() &= ~_MASK; }
+ #endif
- inline static void setOutput() { pinMode(PIN, OUTPUT); } // TODO: perform MUX config { _PDDR::r() |= _MASK; }
- inline static void setInput() { pinMode(PIN, INPUT); } // TODO: preform MUX config { _PDDR::r() &= ~_MASK; }
+ inline static void setOutput() { pinMode(PIN, OUTPUT); } // TODO: perform MUX config { _PDDR::r() |= _MASK; }
+ inline static void setInput() { pinMode(PIN, INPUT); } // TODO: preform MUX config { _PDDR::r() &= ~_MASK; }
- inline static void hi() __attribute__ ((always_inline)) { _GPIO::r()->BSRR = _MASK; }
- inline static void lo() __attribute__ ((always_inline)) { _GPIO::r()->BRR = _MASK; }
- // inline static void lo() __attribute__ ((always_inline)) { _GPIO::r()->BSRR = (_MASK<<16); }
- inline static void set(register port_t val) __attribute__ ((always_inline)) { _GPIO::r()->ODR = val; }
+ inline static void hi() __attribute__ ((always_inline)) { _GPIO::r()->BSRR = _MASK; }
+ inline static void lo() __attribute__ ((always_inline)) { _GPIO::r()->BRR = _MASK; }
+ // inline static void lo() __attribute__ ((always_inline)) { _GPIO::r()->BSRR = (_MASK<<16); }
+ inline static void set(register port_t val) __attribute__ ((always_inline)) { _GPIO::r()->ODR = val; }
- inline static void strobe() __attribute__ ((always_inline)) { toggle(); toggle(); }
+ inline static void strobe() __attribute__ ((always_inline)) { toggle(); toggle(); }
- inline static void toggle() __attribute__ ((always_inline)) { if(_GPIO::r()->ODR & _MASK) { lo(); } else { hi(); } }
+ inline static void toggle() __attribute__ ((always_inline)) { if(_GPIO::r()->ODR & _MASK) { lo(); } else { hi(); } }
- inline static void hi(register port_ptr_t port) __attribute__ ((always_inline)) { hi(); }
- inline static void lo(register port_ptr_t port) __attribute__ ((always_inline)) { lo(); }
- inline static void fastset(register port_ptr_t port, register port_t val) __attribute__ ((always_inline)) { *port = val; }
+ inline static void hi(register port_ptr_t port) __attribute__ ((always_inline)) { hi(); }
+ inline static void lo(register port_ptr_t port) __attribute__ ((always_inline)) { lo(); }
+ inline static void fastset(register port_ptr_t port, register port_t val) __attribute__ ((always_inline)) { *port = val; }
- inline static port_t hival() __attribute__ ((always_inline)) { return _GPIO::r()->ODR | _MASK; }
- inline static port_t loval() __attribute__ ((always_inline)) { return _GPIO::r()->ODR & ~_MASK; }
- inline static port_ptr_t port() __attribute__ ((always_inline)) { return &_GPIO::r()->ODR; }
- inline static port_ptr_t sport() __attribute__ ((always_inline)) { return &_GPIO::r()->BSRR; }
- inline static port_ptr_t cport() __attribute__ ((always_inline)) { return &_GPIO::r()->BRR; }
- inline static port_t mask() __attribute__ ((always_inline)) { return _MASK; }
+ inline static port_t hival() __attribute__ ((always_inline)) { return _GPIO::r()->ODR | _MASK; }
+ inline static port_t loval() __attribute__ ((always_inline)) { return _GPIO::r()->ODR & ~_MASK; }
+ inline static port_ptr_t port() __attribute__ ((always_inline)) { return &_GPIO::r()->ODR; }
+ inline static port_ptr_t sport() __attribute__ ((always_inline)) { return &_GPIO::r()->BSRR; }
+ inline static port_ptr_t cport() __attribute__ ((always_inline)) { return &_GPIO::r()->BRR; }
+ inline static port_t mask() __attribute__ ((always_inline)) { return _MASK; }
};
#if defined(STM32F10X_MD)
- #define _R(T) struct __gen_struct_ ## T
- #define _RD32(T) struct __gen_struct_ ## T { static __attribute__((always_inline)) inline volatile GPIO_TypeDef * r() { return T; } };
- #define _FL_IO(L,C) _RD32(GPIO ## L); _FL_DEFINE_PORT3(L, C, _R(GPIO ## L));
+#define _R(T) struct __gen_struct_ ## T
+#define _RD32(T) struct __gen_struct_ ## T { static __attribute__((always_inline)) inline volatile GPIO_TypeDef * r() { return T; } };
+#define _FL_IO(L,C) _RD32(GPIO ## L); _FL_DEFINE_PORT3(L, C, _R(GPIO ## L));
#elif defined(__STM32F1__)
- #define _R(T) struct __gen_struct_ ## T
- #define _RD32(T) struct __gen_struct_ ## T { static __attribute__((always_inline)) inline gpio_reg_map* r() { return T->regs; } };
- #define _FL_IO(L,C) _RD32(GPIO ## L); _FL_DEFINE_PORT3(L, C, _R(GPIO ## L));
+#define _R(T) struct __gen_struct_ ## T
+#define _RD32(T) struct __gen_struct_ ## T { static __attribute__((always_inline)) inline gpio_reg_map* r() { return T->regs; } };
+#define _FL_IO(L,C) _RD32(GPIO ## L); _FL_DEFINE_PORT3(L, C, _R(GPIO ## L));
#else
- #error "Platform not supported"
+#error "Platform not supported"
#endif
#define _FL_DEFPIN(PIN, BIT, L) template<> class FastPin<PIN> : public _ARMPIN<PIN, BIT, 1 << BIT, _R(GPIO ## L)> {};
@@ -94,8 +95,6 @@ _FL_IO(G,6);
// Actual pin definitions
#if defined(SPARK) // Sparkfun STM32F103 based board
-
-
#define MAX_PIN 19
_FL_DEFPIN(0, 7, B);
_FL_DEFPIN(1, 6, B);
@@ -118,7 +117,6 @@ _FL_DEFPIN(17, 1, B);
_FL_DEFPIN(18, 3, A);
_FL_DEFPIN(19, 2, A);
-
#define SPI_DATA 15
#define SPI_CLOCK 13
diff --git a/platforms/arm/stm32/led_sysdefs_arm_stm32.h b/platforms/arm/stm32/led_sysdefs_arm_stm32.h
index 6b9ce7ca..afcf1785 100644
--- a/platforms/arm/stm32/led_sysdefs_arm_stm32.h
+++ b/platforms/arm/stm32/led_sysdefs_arm_stm32.h
@@ -3,25 +3,25 @@
#if defined(STM32F10X_MD)
- #include <application.h>
+#include <application.h>
- #define FASTLED_NAMESPACE_BEGIN namespace NSFastLED {
- #define FASTLED_NAMESPACE_END }
- #define FASTLED_USING_NAMESPACE using namespace NSFastLED;
+#define FASTLED_NAMESPACE_BEGIN namespace NSFastLED {
+#define FASTLED_NAMESPACE_END }
+#define FASTLED_USING_NAMESPACE using namespace NSFastLED;
- // reusing/abusing cli/sei defs for due
- #define cli() __disable_irq(); __disable_fault_irq();
- #define sei() __enable_irq(); __enable_fault_irq();
+// reusing/abusing cli/sei defs for due
+#define cli() __disable_irq(); __disable_fault_irq();
+#define sei() __enable_irq(); __enable_fault_irq();
#elif defined (__STM32F1__)
- #include "cm3_regs.h"
+#include "cm3_regs.h"
- #define cli() nvic_globalirq_disable()
- #define sei() nvic_globalirq_enable()
+#define cli() nvic_globalirq_disable()
+#define sei() nvic_globalirq_enable()
#else
- #error "Platform not supported"
+#error "Platform not supported"
#endif
#define FASTLED_ARM
@@ -56,6 +56,6 @@ typedef volatile uint8_t RwReg; /**< Read-Write 8-bit register (volatile u
#define FASTLED_NO_PINMAP
#ifndef F_CPU
- #define F_CPU 72000000
+#define F_CPU 72000000
#endif
#endif
diff --git a/platforms/avr/clockless_trinket.h b/platforms/avr/clockless_trinket.h
index 824553fe..b6ff96b9 100644
--- a/platforms/avr/clockless_trinket.h
+++ b/platforms/avr/clockless_trinket.h
@@ -97,6 +97,7 @@ class ClocklessController : public CPixelLEDController<RGB_ORDER> {
typedef typename FastPin<DATA_PIN>::port_t data_t;
CMinWait<WAIT_TIME> mWait;
+
public:
virtual void init() {
FastPin<DATA_PIN>::setOutput();
@@ -105,7 +106,6 @@ public:
virtual uint16_t getMaxRefreshRate() const { return 400; }
protected:
-
virtual void showPixels(PixelController<RGB_ORDER> & pixels) {
mWait.wait();
diff --git a/platforms/avr/fastspi_avr.h b/platforms/avr/fastspi_avr.h
index d2edc966..245e4065 100644
--- a/platforms/avr/fastspi_avr.h
+++ b/platforms/avr/fastspi_avr.h
@@ -187,7 +187,6 @@ public:
FastPin<_CLOCK_PIN>::setOutput();
FastPin<_DATA_PIN>::setOutput();
-
// must be done last, see page 206
setSPIRate();
}
@@ -249,12 +248,12 @@ public:
setSPIRate();
}
- void release() {
- if(m_pSelect != NULL) {
- m_pSelect->release();
- }
- disable_pins();
+ void release() {
+ if(m_pSelect != NULL) {
+ m_pSelect->release();
}
+ disable_pins();
+ }
static void writeBytesValueRaw(uint8_t value, int len) {
while(len--) {
@@ -333,6 +332,7 @@ template <uint8_t _DATA_PIN, uint8_t _CLOCK_PIN, uint32_t _SPI_CLOCK_DIVIDER>
class AVRHardwareSPIOutput {
Selectable *m_pSelect;
bool mWait;
+
public:
AVRHardwareSPIOutput() { m_pSelect = NULL; mWait = false;}
AVRHardwareSPIOutput(Selectable *pSelect) { m_pSelect = pSelect; }
@@ -510,6 +510,7 @@ template <uint8_t _DATA_PIN, uint8_t _CLOCK_PIN, uint32_t _SPI_CLOCK_DIVIDER>
class AVRHardwareSPIOutput {
Selectable *m_pSelect;
bool mWait;
+
public:
AVRHardwareSPIOutput() { m_pSelect = NULL; mWait = false;}
AVRHardwareSPIOutput(Selectable *pSelect) { m_pSelect = pSelect; }
diff --git a/platforms/esp/32/clockless_block_esp32.h b/platforms/esp/32/clockless_block_esp32.h
index 8ab5807a..41f44be2 100644
--- a/platforms/esp/32/clockless_block_esp32.h
+++ b/platforms/esp/32/clockless_block_esp32.h
@@ -24,6 +24,7 @@ class InlineBlockClocklessController : public CPixelLEDController<RGB_ORDER, LAN
data_t mPinMask;
data_ptr_t mPort;
CMinWait<WAIT_TIME> mWait;
+
public:
virtual int size() { return CLEDController::size() * LANES; }
diff --git a/platforms/esp/32/clockless_esp32.h.orig b/platforms/esp/32/clockless_esp32.h.orig
deleted file mode 100644
index e0cd00da..00000000
--- a/platforms/esp/32/clockless_esp32.h.orig
+++ /dev/null
@@ -1,786 +0,0 @@
-/*
- * Integration into FastLED ClocklessController 2017 Thomas Basler
- *
- * Modifications Copyright (c) 2017 Martin F. Falatic
- *
- * Modifications Copyright (c) 2018 Samuel Z. Guyer
- *
- * ESP32 support is provided using the RMT peripheral device -- a unit
- * on the chip designed specifically for generating (and receiving)
- * precisely-timed digital signals. Nominally for use in infrared
- * remote controls, we use it to generate the signals for clockless
- * LED strips. The main advantage of using the RMT device is that,
- * once programmed, it generates the signal asynchronously, allowing
- * the CPU to continue executing other code. It is also not vulnerable
- * to interrupts or other timing problems that could disrupt the signal.
- *
- * The implementation strategy is borrowed from previous work and from
- * the RMT support built into the ESP32 IDF. The RMT device has 8
- * channels, which can be programmed independently to send sequences
- * of high/low bits. Memory for each channel is limited, however, so
- * in order to send a long sequence of bits, we need to continuously
- * refill the buffer until all the data is sent. To do this, we fill
- * half the buffer and then set an interrupt to go off when that half
- * is sent. Then we refill that half while the second half is being
- * sent. This strategy effectively overlaps computation (by the CPU)
- * and communication (by the RMT).
- *
- * Since the RMT device only has 8 channels, we need a strategy to
- * allow more than 8 LED controllers. Our driver assigns controllers
- * to channels on the fly, queuing up controllers as necessary until a
- * channel is free. The main showPixels routine just fires off the
- * first 8 controllers; the interrupt handler starts new controllers
- * asynchronously as previous ones finish. So, for example, it can
- * send the data for 8 controllers simultaneously, but 16 controllers
- * would take approximately twice as much time.
- *
- * There is a #define that allows a program to control the total
- * number of channels that the driver is allowed to use. It defaults
- * to 8 -- use all the channels. Setting it to 1, for example, results
- * in fully serial output:
- *
- * #define FASTLED_RMT_MAX_CHANNELS 1
- *
- * OTHER RMT APPLICATIONS
- *
- * The default FastLED driver takes over control of the RMT interrupt
- * handler, making it hard to use the RMT device for other
- * (non-FastLED) purposes. You can change it's behavior to use the ESP
- * core driver instead, allowing other RMT applications to
- * co-exist. To switch to this mode, add the following directive
- * before you include FastLED.h:
- *
- * #define FASTLED_RMT_BUILTIN_DRIVER
- *
- * There may be a performance penalty for using this mode. We need to
- * compute the RMT signal for the entire LED strip ahead of time,
- * rather than overlapping it with communication. We also need a large
- * buffer to hold the signal specification. Each bit of pixel data is
- * represented by a 32-bit pulse specification, so it is a 32X blow-up
- * in memory use.
- *
- *
- * Based on public domain code created 19 Nov 2016 by Chris Osborn <fozztexx@fozztexx.com>
- * http://insentricity.com *
- *
- */
-/*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#pragma once
-
-FASTLED_NAMESPACE_BEGIN
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include "esp32-hal.h"
-#include "esp_intr.h"
-#include "driver/gpio.h"
-#include "driver/rmt.h"
-#include "driver/periph_ctrl.h"
-#include "freertos/semphr.h"
-#include "soc/rmt_struct.h"
-
-#include "esp_log.h"
-
-#ifdef __cplusplus
-}
-#endif
-
-__attribute__ ((always_inline)) inline static uint32_t __clock_cycles() {
- uint32_t cyc;
- __asm__ __volatile__ ("rsr %0,ccount":"=a" (cyc));
- return cyc;
-}
-
-#define FASTLED_HAS_CLOCKLESS 1
-
-// -- Configuration constants
-#define DIVIDER 2 /* 4, 8 still seem to work, but timings become marginal */
-#define MAX_PULSES 32 /* A channel has a 64 "pulse" buffer - we use half per pass */
-
-// -- Convert ESP32 cycles back into nanoseconds
-#define ESPCLKS_TO_NS(_CLKS) (((long)(_CLKS) * 1000L) / F_CPU_MHZ)
-
-// -- Convert nanoseconds into RMT cycles
-#define F_CPU_RMT ( 80000000L)
-#define NS_PER_SEC (1000000000L)
-#define CYCLES_PER_SEC (F_CPU_RMT/DIVIDER)
-#define NS_PER_CYCLE ( NS_PER_SEC / CYCLES_PER_SEC )
-#define NS_TO_CYCLES(n) ( (n) / NS_PER_CYCLE )
-
-// -- Convert ESP32 cycles to RMT cycles
-#define TO_RMT_CYCLES(_CLKS) NS_TO_CYCLES(ESPCLKS_TO_NS(_CLKS))
-
-// -- Number of cycles to signal the strip to latch
-#define RMT_RESET_DURATION NS_TO_CYCLES(50000)
-
-// -- Core or custom driver
-#ifndef FASTLED_RMT_BUILTIN_DRIVER
-#define FASTLED_RMT_BUILTIN_DRIVER false
-#endif
-
-// -- Max number of controllers we can support
-#ifndef FASTLED_RMT_MAX_CONTROLLERS
-#define FASTLED_RMT_MAX_CONTROLLERS 32
-#endif
-
-// -- Number of RMT channels to use (up to 8)
-// Redefine this value to 1 to force serial output
-#ifndef FASTLED_RMT_MAX_CHANNELS
-#define FASTLED_RMT_MAX_CHANNELS 8
-#endif
-
-// -- Array of all controllers
-static CLEDController * gControllers[FASTLED_RMT_MAX_CONTROLLERS];
-
-// -- Current set of active controllers, indexed by the RMT
-// channel assigned to them.
-static CLEDController * gOnChannel[FASTLED_RMT_MAX_CHANNELS];
-
-static int gNumControllers = 0;
-static int gNumStarted = 0;
-static int gNumDone = 0;
-static int gNext = 0;
-
-static intr_handle_t gRMT_intr_handle = NULL;
-
-// -- Global semaphore for the whole show process
-// Semaphore is not given until all data has been sent
-static xSemaphoreHandle gTX_sem = NULL;
-
-static bool gInitialized = false;
-
-template <int DATA_PIN, int T1, int T2, int T3, EOrder RGB_ORDER = RGB, int XTRA0 = 0, bool FLIP = false, int WAIT_TIME = 5>
-class ClocklessController : public CPixelLEDController<RGB_ORDER>
-{
- // -- RMT has 8 channels, numbered 0 to 7
- rmt_channel_t mRMT_channel;
-
- // -- Store the GPIO pin
- gpio_num_t mPin;
-<<<<<<< HEAD
-
- // -- This instantiation forces a check on the pin choice
- FastPin<DATA_PIN> mFastPin;
-
- // -- Timing values for zero and one bits, derived from T1, T2, and T3
- rmt_item32_t mZero;
- rmt_item32_t mOne;
-
-=======
-
- // -- Timing values for zero and one bits, derived from T1, T2, and T3
- rmt_item32_t mZero;
- rmt_item32_t mOne;
-
->>>>>>> upstream/master
- // -- State information for keeping track of where we are in the pixel data
- PixelController<RGB_ORDER> * mPixels = NULL;
- void * mPixelSpace = NULL;
- uint8_t mRGB_channel;
- uint16_t mCurPulse;
-
- // -- Buffer to hold all of the pulses. For the version that uses
- // the RMT driver built into the ESP core.
- rmt_item32_t * mBuffer;
- uint16_t mBufferSize;
-
-public:
-
- virtual void init()
- {
- // -- Precompute rmt items corresponding to a zero bit and a one bit
- // according to the timing values given in the template instantiation
- // T1H
- mOne.level0 = 1;
- mOne.duration0 = TO_RMT_CYCLES(T1+T2);
- // T1L
- mOne.level1 = 0;
- mOne.duration1 = TO_RMT_CYCLES(T3);
-
- // T0H
- mZero.level0 = 1;
- mZero.duration0 = TO_RMT_CYCLES(T1);
- // T0L
- mZero.level1 = 0;
- mZero.duration1 = TO_RMT_CYCLES(T2 + T3);
-
-<<<<<<< HEAD
- gControllers[gNumControllers] = this;
- gNumControllers++;
-
- mPin = gpio_num_t(DATA_PIN);
-=======
- gControllers[gNumControllers] = this;
- gNumControllers++;
-
- mPin = gpio_num_t(DATA_PIN);
->>>>>>> upstream/master
- }
-
- virtual uint16_t getMaxRefreshRate() const { return 400; }
-
-protected:
-
- void initRMT()
- {
-<<<<<<< HEAD
- // -- Only need to do this once
- if (gInitialized) return;
-
- for (int i = 0; i < FASTLED_RMT_MAX_CHANNELS; i++) {
- gOnChannel[i] = NULL;
-
- // -- RMT configuration for transmission
- rmt_config_t rmt_tx;
- rmt_tx.channel = rmt_channel_t(i);
- rmt_tx.rmt_mode = RMT_MODE_TX;
- rmt_tx.gpio_num = mPin; // The particular pin will be assigned later
- rmt_tx.mem_block_num = 1;
- rmt_tx.clk_div = DIVIDER;
- rmt_tx.tx_config.loop_en = false;
- rmt_tx.tx_config.carrier_level = RMT_CARRIER_LEVEL_LOW;
- rmt_tx.tx_config.carrier_en = false;
- rmt_tx.tx_config.idle_level = RMT_IDLE_LEVEL_LOW;
- rmt_tx.tx_config.idle_output_en = true;
-
- // -- Apply the configuration
- rmt_config(&rmt_tx);
-
- if (FASTLED_RMT_BUILTIN_DRIVER) {
- rmt_driver_install(rmt_channel_t(i), 0, 0);
- } else {
- // -- Set up the RMT to send 1/2 of the pulse buffer and then
- // generate an interrupt. When we get this interrupt we
- // fill the other half in preparation (kind of like double-buffering)
- rmt_set_tx_thr_intr_en(rmt_channel_t(i), true, MAX_PULSES);
- }
- }
-
- // -- Create a semaphore to block execution until all the controllers are done
- if (gTX_sem == NULL) {
- gTX_sem = xSemaphoreCreateBinary();
- xSemaphoreGive(gTX_sem);
- }
-
- if ( ! FASTLED_RMT_BUILTIN_DRIVER) {
- // -- Allocate the interrupt if we have not done so yet. This
- // interrupt handler must work for all different kinds of
- // strips, so it delegates to the refill function for each
- // specific instantiation of ClocklessController.
- if (gRMT_intr_handle == NULL)
- esp_intr_alloc(ETS_RMT_INTR_SOURCE, 0, interruptHandler, 0, &gRMT_intr_handle);
- }
-
- gInitialized = true;
- }
-
- virtual void showPixels(PixelController<RGB_ORDER> & pixels)
- {
- if (gNumStarted == 0) {
- // -- First controller: make sure everything is set up
- initRMT();
- xSemaphoreTake(gTX_sem, portMAX_DELAY);
- }
-
- // -- Initialize the local state, save a pointer to the pixel
- // data. We need to make a copy because pixels is a local
- // variable in the calling function, and this data structure
- // needs to outlive this call to showPixels.
-
- if (mPixels != NULL) delete mPixels;
- mPixels = new PixelController<RGB_ORDER>(pixels);
-
- // -- Keep track of the number of strips we've seen
- gNumStarted++;
-
- // -- The last call to showPixels is the one responsible for doing
- // all of the actual worl
- if (gNumStarted == gNumControllers) {
- gNext = 0;
-
- // -- First, fill all the available channels
- int channel = 0;
- while (channel < FASTLED_RMT_MAX_CHANNELS && gNext < gNumControllers) {
- startNext(channel);
- channel++;
- }
-
- // -- Wait here while the rest of the data is sent. The interrupt handler
- // will keep refilling the RMT buffers until it is all sent; then it
- // gives the semaphore back.
- xSemaphoreTake(gTX_sem, portMAX_DELAY);
- xSemaphoreGive(gTX_sem);
-
- // -- Reset the counters
- gNumStarted = 0;
- gNumDone = 0;
- gNext = 0;
- }
- }
-
- // -- Start up the next controller
- // This method is static so that it can dispatch to the appropriate
- // startOnChannel method of the given controller.
- static void startNext(int channel)
- {
- if (gNext < gNumControllers) {
- ClocklessController * pController = static_cast<ClocklessController*>(gControllers[gNext]);
- pController->startOnChannel(channel);
- gNext++;
- }
- }
-
- virtual void startOnChannel(int channel)
- {
- // -- Assign this channel and configure the RMT
- mRMT_channel = rmt_channel_t(channel);
-
- // -- Store a reference to this controller, so we can get it
- // inside the interrupt handler
- gOnChannel[channel] = this;
-
- // -- Assign the pin to this channel
- rmt_set_pin(mRMT_channel, RMT_MODE_TX, mPin);
-
- if (FASTLED_RMT_BUILTIN_DRIVER) {
- // -- Use the built-in RMT driver to send all the data in one shot
- rmt_register_tx_end_callback(doneOnChannel, 0);
- writeAllRMTItems();
- } else {
- // -- Use our custom driver to send the data incrementally
-
- // -- Turn on the interrupts
- rmt_set_tx_intr_en(mRMT_channel, true);
-
- // -- Initialize the counters that keep track of where we are in
- // the pixel data.
- mCurPulse = 0;
- mRGB_channel = 0;
-
- // -- Fill both halves of the buffer
- fillHalfRMTBuffer();
- fillHalfRMTBuffer();
-
- // -- Turn on the interrupts
- rmt_set_tx_intr_en(mRMT_channel, true);
-
- // -- Start the RMT TX operation
- rmt_tx_start(mRMT_channel, true);
- }
- }
-
- static void doneOnChannel(rmt_channel_t channel, void * arg)
- {
- ClocklessController * controller = static_cast<ClocklessController*>(gOnChannel[channel]);
- portBASE_TYPE HPTaskAwoken = 0;
-
- // -- Turn off output on the pin
- gpio_matrix_out(controller->mPin, 0x100, 0, 0);
-
- gOnChannel[channel] = NULL;
- gNumDone++;
-
- if (gNumDone == gNumControllers) {
- // -- If this is the last controller, signal that we are all done
- xSemaphoreGiveFromISR(gTX_sem, &HPTaskAwoken);
- if(HPTaskAwoken == pdTRUE) portYIELD_FROM_ISR();
- } else {
- // -- Otherwise, if there are still controllers waiting, then
- // start the next one on this channel
- if (gNext < gNumControllers)
- startNext(channel);
- }
-=======
- // -- Only need to do this once
- if (gInitialized) return;
-
- for (int i = 0; i < FASTLED_RMT_MAX_CHANNELS; i++) {
- gOnChannel[i] = NULL;
-
- // -- RMT configuration for transmission
- rmt_config_t rmt_tx;
- rmt_tx.channel = rmt_channel_t(i);
- rmt_tx.rmt_mode = RMT_MODE_TX;
- rmt_tx.gpio_num = mPin; // The particular pin will be assigned later
- rmt_tx.mem_block_num = 1;
- rmt_tx.clk_div = DIVIDER;
- rmt_tx.tx_config.loop_en = false;
- rmt_tx.tx_config.carrier_level = RMT_CARRIER_LEVEL_LOW;
- rmt_tx.tx_config.carrier_en = false;
- rmt_tx.tx_config.idle_level = RMT_IDLE_LEVEL_LOW;
- rmt_tx.tx_config.idle_output_en = true;
-
- // -- Apply the configuration
- rmt_config(&rmt_tx);
-
- if (FASTLED_RMT_BUILTIN_DRIVER) {
- rmt_driver_install(rmt_channel_t(i), 0, 0);
- } else {
- // -- Set up the RMT to send 1/2 of the pulse buffer and then
- // generate an interrupt. When we get this interrupt we
- // fill the other half in preparation (kind of like double-buffering)
- rmt_set_tx_thr_intr_en(rmt_channel_t(i), true, MAX_PULSES);
- }
- }
-
- // -- Create a semaphore to block execution until all the controllers are done
- if (gTX_sem == NULL) {
- gTX_sem = xSemaphoreCreateBinary();
- xSemaphoreGive(gTX_sem);
- }
-
- if ( ! FASTLED_RMT_BUILTIN_DRIVER) {
- // -- Allocate the interrupt if we have not done so yet. This
- // interrupt handler must work for all different kinds of
- // strips, so it delegates to the refill function for each
- // specific instantiation of ClocklessController.
- if (gRMT_intr_handle == NULL)
- esp_intr_alloc(ETS_RMT_INTR_SOURCE, 0, interruptHandler, 0, &gRMT_intr_handle);
- }
-
- gInitialized = true;
- }
-
- virtual void showPixels(PixelController<RGB_ORDER> & pixels)
- {
- if (gNumStarted == 0) {
- // -- First controller: make sure everything is set up
- initRMT();
- xSemaphoreTake(gTX_sem, portMAX_DELAY);
- }
-
- // -- Initialize the local state, save a pointer to the pixel
- // data. We need to make a copy because pixels is a local
- // variable in the calling function, and this data structure
- // needs to outlive this call to showPixels.
-
- if (mPixels != NULL) delete mPixels;
- mPixels = new PixelController<RGB_ORDER>(pixels);
-
- // -- Keep track of the number of strips we've seen
- gNumStarted++;
-
- // -- The last call to showPixels is the one responsible for doing
- // all of the actual worl
- if (gNumStarted == gNumControllers) {
- gNext = 0;
-
- // -- First, fill all the available channels
- int channel = 0;
- while (channel < FASTLED_RMT_MAX_CHANNELS && gNext < gNumControllers) {
- startNext(channel);
- channel++;
- }
-
- // -- Wait here while the rest of the data is sent. The interrupt handler
- // will keep refilling the RMT buffers until it is all sent; then it
- // gives the semaphore back.
- xSemaphoreTake(gTX_sem, portMAX_DELAY);
- xSemaphoreGive(gTX_sem);
-
- // -- Reset the counters
- gNumStarted = 0;
- gNumDone = 0;
- gNext = 0;
- }
- }
-
- // -- Start up the next controller
- // This method is static so that it can dispatch to the appropriate
- // startOnChannel method of the given controller.
- static void startNext(int channel)
- {
- if (gNext < gNumControllers) {
- ClocklessController * pController = static_cast<ClocklessController*>(gControllers[gNext]);
- pController->startOnChannel(channel);
- gNext++;
- }
- }
-
- virtual void startOnChannel(int channel)
- {
- // -- Assign this channel and configure the RMT
- mRMT_channel = rmt_channel_t(channel);
-
- // -- Store a reference to this controller, so we can get it
- // inside the interrupt handler
- gOnChannel[channel] = this;
-
- // -- Assign the pin to this channel
- rmt_set_pin(mRMT_channel, RMT_MODE_TX, mPin);
-
- if (FASTLED_RMT_BUILTIN_DRIVER) {
- // -- Use the built-in RMT driver to send all the data in one shot
- rmt_register_tx_end_callback(doneOnChannel, 0);
- writeAllRMTItems();
- } else {
- // -- Use our custom driver to send the data incrementally
-
- // -- Turn on the interrupts
- rmt_set_tx_intr_en(mRMT_channel, true);
-
- // -- Initialize the counters that keep track of where we are in
- // the pixel data.
- mCurPulse = 0;
- mRGB_channel = 0;
-
- // -- Fill both halves of the buffer
- fillHalfRMTBuffer();
- fillHalfRMTBuffer();
-
- // -- Turn on the interrupts
- rmt_set_tx_intr_en(mRMT_channel, true);
-
- // -- Start the RMT TX operation
- rmt_tx_start(mRMT_channel, true);
- }
- }
-
- static void doneOnChannel(rmt_channel_t channel, void * arg)
- {
- ClocklessController * controller = static_cast<ClocklessController*>(gOnChannel[channel]);
- portBASE_TYPE HPTaskAwoken = 0;
-
- // -- Turn off output on the pin
- gpio_matrix_out(controller->mPin, 0x100, 0, 0);
-
- gOnChannel[channel] = NULL;
- gNumDone++;
-
- if (gNumDone == gNumControllers) {
- // -- If this is the last controller, signal that we are all done
- xSemaphoreGiveFromISR(gTX_sem, &HPTaskAwoken);
- if(HPTaskAwoken == pdTRUE) portYIELD_FROM_ISR();
- } else {
- // -- Otherwise, if there are still controllers waiting, then
- // start the next one on this channel
- if (gNext < gNumControllers)
- startNext(channel);
- }
->>>>>>> upstream/master
- }
-
- static IRAM_ATTR void interruptHandler(void *arg)
- {
- // -- The basic structure of this code is borrowed from the
- // interrupt handler in esp-idf/components/driver/rmt.c
- uint32_t intr_st = RMT.int_st.val;
- uint8_t channel;
-
- for (channel = 0; channel < FASTLED_RMT_MAX_CHANNELS; channel++) {
- int tx_done_bit = channel * 3;
- int tx_next_bit = channel + 24;
-
- if (gOnChannel[channel] != NULL) {
-
-<<<<<<< HEAD
- ClocklessController * controller = static_cast<ClocklessController*>(gOnChannel[channel]);
-
- // -- More to send on this channel
- if (intr_st & BIT(tx_next_bit)) {
- RMT.int_clr.val |= BIT(tx_next_bit);
-
- // -- Refill the half of the buffer that we just finished,
- // allowing the other half to proceed.
- controller->fillHalfRMTBuffer();
- }
-
- // -- Transmission is complete on this channel
- if (intr_st & BIT(tx_done_bit)) {
- RMT.int_clr.val |= BIT(tx_done_bit);
- doneOnChannel(rmt_channel_t(channel), 0);
-=======
- ClocklessController * controller = static_cast<ClocklessController*>(gOnChannel[channel]);
-
- // -- More to send on this channel
- if (intr_st & BIT(tx_next_bit)) {
- RMT.int_clr.val |= BIT(tx_next_bit);
-
- // -- Refill the half of the buffer that we just finished,
- // allowing the other half to proceed.
- controller->fillHalfRMTBuffer();
- }
-
- // -- Transmission is complete on this channel
- if (intr_st & BIT(tx_done_bit)) {
- RMT.int_clr.val |= BIT(tx_done_bit);
- doneOnChannel(rmt_channel_t(channel), 0);
->>>>>>> upstream/master
- }
- }
- }
- }
-
- virtual void fillHalfRMTBuffer()
- {
- // -- Fill half of the RMT pulse buffer
-
- // The buffer holds 64 total pulse items, so this loop converts
- // as many pixels as can fit in half of the buffer (MAX_PULSES =
- // 32 items). In our case, each pixel consists of three bytes,
- // each bit turns into one pulse item -- 24 items per pixel. So,
- // each half of the buffer can hold 1 and 1/3 of a pixel.
-
- // The member variable mCurPulse keeps track of which of the 64
- // items we are writing. During the first call to this method it
- // fills 0-31; in the second call it fills 32-63, and then wraps
- // back around to zero.
-
- // When we run out of pixel data, just fill the remaining items
- // with zero pulses.
-
- uint16_t pulse_count = 0; // Ranges from 0-31 (half a buffer)
- uint32_t byteval = 0;
- uint32_t one_val = mOne.val;
- uint32_t zero_val = mZero.val;
- bool done_strip = false;
-
- while (pulse_count < MAX_PULSES) {
- if (! mPixels->has(1)) {
-<<<<<<< HEAD
- if (mCurPulse > 0) {
- // -- Extend the last pulse to force the strip to latch. Honestly, I'm not
- // sure if this is really necessary.
- // RMTMEM.chan[mRMT_channel].data32[mCurPulse-1].duration1 = RMT_RESET_DURATION;
- }
-=======
->>>>>>> upstream/master
- done_strip = true;
- break;
- }
-
- // -- Cycle through the R,G, and B values in the right order
- switch (mRGB_channel) {
- case 0:
- byteval = mPixels->loadAndScale0();
- mRGB_channel = 1;
- break;
- case 1:
- byteval = mPixels->loadAndScale1();
- mRGB_channel = 2;
- break;
- case 2:
- byteval = mPixels->loadAndScale2();
- mPixels->advanceData();
- mPixels->stepDithering();
- mRGB_channel = 0;
- break;
- default:
- break;
- }
-
- byteval <<= 24;
- // Shift bits out, MSB first, setting RMTMEM.chan[n].data32[x] to the
- // rmt_item32_t value corresponding to the buffered bit value
- for (register uint32_t j = 0; j < 8; j++) {
- uint32_t val = (byteval & 0x80000000L) ? one_val : zero_val;
- RMTMEM.chan[mRMT_channel].data32[mCurPulse].val = val;
- byteval <<= 1;
- mCurPulse++;
- pulse_count++;
- }
-<<<<<<< HEAD
-=======
-
- if (done_strip)
- RMTMEM.chan[mRMT_channel].data32[mCurPulse-1].duration1 = RMT_RESET_DURATION;
->>>>>>> upstream/master
- }
-
- if (done_strip) {
- // -- And fill the remaining items with zero pulses. The zero values triggers
- // the tx_done interrupt.
- while (pulse_count < MAX_PULSES) {
- RMTMEM.chan[mRMT_channel].data32[mCurPulse].val = 0;
- mCurPulse++;
- pulse_count++;
- }
- }
-
- // -- When we have filled the back half the buffer, reset the position to the first half
- if (mCurPulse >= MAX_PULSES*2)
- mCurPulse = 0;
- }
-
- virtual void writeAllRMTItems()
- {
- // -- Compute the pulse values for the whole strip at once.
- // Requires a large buffer
-<<<<<<< HEAD
- mBufferSize = mPixels->size() * 3 * 8;
-=======
- mBufferSize = mPixels->size() * 3 * 8;
->>>>>>> upstream/master
-
- // TODO: need a specific number here
- if (mBuffer == NULL) {
- mBuffer = (rmt_item32_t *) calloc( mBufferSize, sizeof(rmt_item32_t));
- }
-
- mCurPulse = 0;
- mRGB_channel = 0;
- uint32_t byteval = 0;
- while (mPixels->has(1)) {
- // -- Cycle through the R,G, and B values in the right order
- switch (mRGB_channel) {
- case 0:
- byteval = mPixels->loadAndScale0();
- mRGB_channel = 1;
- break;
- case 1:
- byteval = mPixels->loadAndScale1();
- mRGB_channel = 2;
- break;
- case 2:
- byteval = mPixels->loadAndScale2();
- mPixels->advanceData();
- mPixels->stepDithering();
- mRGB_channel = 0;
- break;
- default:
- break;
- }
-
- byteval <<= 24;
- // Shift bits out, MSB first, setting RMTMEM.chan[n].data32[x] to the
- // rmt_item32_t value corresponding to the buffered bit value
- for (register uint32_t j = 0; j < 8; j++) {
- mBuffer[mCurPulse] = (byteval & 0x80000000L) ? mOne : mZero;
- byteval <<= 1;
- mCurPulse++;
- }
- }
-
- mBuffer[mCurPulse-1].duration1 = RMT_RESET_DURATION;
- assert(mCurPulse == mBufferSize);
-
-<<<<<<< HEAD
- rmt_write_items(mRMT_channel, mBuffer, mBufferSize, false);
-=======
- rmt_write_items(mRMT_channel, mBuffer, mBufferSize, false);
->>>>>>> upstream/master
- }
-};
-
-FASTLED_NAMESPACE_END
diff --git a/platforms/esp/32/clockless_i2s_esp32.h b/platforms/esp/32/clockless_i2s_esp32.h
index 6d3241d9..a82e43a6 100644
--- a/platforms/esp/32/clockless_i2s_esp32.h
+++ b/platforms/esp/32/clockless_i2s_esp32.h
@@ -171,8 +171,8 @@ static DMABuffer * dmaBuffers[NUM_DMA_BUFFERS];
// are global variables.
static int gPulsesPerBit = 0;
-static uint32_t gOneBit[40] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
-static uint32_t gZeroBit[40] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+static uint32_t gOneBit[40] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+static uint32_t gZeroBit[40] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
// -- Counters to track progress
static int gCurBuffer = 0;
@@ -202,8 +202,7 @@ class ClocklessController : public CPixelLEDController<RGB_ORDER>
// -- Make sure we can't call show() too quickly
CMinWait<50> mWait;
- public:
-
+public:
void init()
{
i2sInit();
@@ -233,7 +232,6 @@ class ClocklessController : public CPixelLEDController<RGB_ORDER>
virtual uint16_t getMaxRefreshRate() const { return 400; }
protected:
-
static int pgcd(int smallest,int precision,int a,int b,int c)
{
int pgc_=1;
@@ -393,8 +391,8 @@ protected:
//int ones_for_zero = ((T1ns - 1)/FASTLED_I2S_NS_PER_PULSE) + 1;
ones_for_zero =T1/pgc_ ;
- // Serial.print("Zero bit: target ");
- // Serial.print(T1ns); Serial.print("ns --- ");
+ // Serial.print("Zero bit: target ");
+ // Serial.print(T1ns); Serial.print("ns --- ");
//Serial.print(ones_for_zero); Serial.print(" 1 bits");
//Serial.print(" = "); Serial.print(ones_for_zero * FASTLED_I2S_NS_PER_PULSE); Serial.println("ns");
// Serial.printf("Zero bit : target %d ns --- %d pulses 1 bit = %f ns\n",T1ns,ones_for_zero ,ones_for_zero*pulseduration);
@@ -664,11 +662,11 @@ protected:
uint8_t * row = (uint8_t *) (gPixelBits[channel][bitnum]);
uint32_t bit = (row[0] << 24) | (row[1] << 16) | (row[2] << 8) | row[3];
- /* SZG: More general, but too slow:
- for (int pulse_num = 0; pulse_num < gPulsesPerBit; pulse_num++) {
- buf[buf_index++] = has_data_mask & ( (bit & gOneBit[pulse_num]) | (~bit & gZeroBit[pulse_num]) );
- }
- */
+ /* SZG: More general, but too slow:
+ for (int pulse_num = 0; pulse_num < gPulsesPerBit; pulse_num++) {
+ buf[buf_index++] = has_data_mask & ( (bit & gOneBit[pulse_num]) | (~bit & gZeroBit[pulse_num]) );
+ }
+ */
// -- Only fill in the pulses that are different between the "0" and "1" encodings
for(int pulse_num = ones_for_zero; pulse_num < ones_for_one; pulse_num++) {
diff --git a/platforms/esp/32/clockless_rmt_esp32.h b/platforms/esp/32/clockless_rmt_esp32.h
index bf4dd142..82a1b3b6 100644
--- a/platforms/esp/32/clockless_rmt_esp32.h
+++ b/platforms/esp/32/clockless_rmt_esp32.h
@@ -214,7 +214,6 @@ class ClocklessController : public CPixelLEDController<RGB_ORDER>
CMinWait<50> mWait;
public:
-
void init()
{
// -- Allocate space to save the pixel controller
@@ -246,7 +245,6 @@ public:
virtual uint16_t getMaxRefreshRate() const { return 400; }
protected:
-
void initRMT()
{
for (int i = 0; i < FASTLED_RMT_MAX_CHANNELS; i++) {
diff --git a/platforms/esp/32/fastpin_esp32.h b/platforms/esp/32/fastpin_esp32.h
index d54d7fee..7876b281 100644
--- a/platforms/esp/32/fastpin_esp32.h
+++ b/platforms/esp/32/fastpin_esp32.h
@@ -3,7 +3,6 @@
FASTLED_NAMESPACE_BEGIN
template<uint8_t PIN, uint32_t MASK> class _ESPPIN {
-
public:
typedef volatile uint32_t * port_ptr_t;
typedef uint32_t port_t;
diff --git a/platforms/esp/8266/clockless_block_esp8266.h b/platforms/esp/8266/clockless_block_esp8266.h
index 40c91612..d3b1cf95 100644
--- a/platforms/esp/8266/clockless_block_esp8266.h
+++ b/platforms/esp/8266/clockless_block_esp8266.h
@@ -23,6 +23,7 @@ class InlineBlockClocklessController : public CPixelLEDController<RGB_ORDER, LAN
typedef typename FastPin<FIRST_PIN>::port_t data_t;
CMinWait<WAIT_TIME> mWait;
+
public:
virtual int size() { return CLEDController::size() * LANES; }
@@ -31,13 +32,13 @@ public:
/*uint32_t clocks = */
int cnt=FASTLED_INTERRUPT_RETRY_COUNT;
while(!showRGBInternal(pixels) && cnt--) {
- os_intr_unlock();
+ os_intr_unlock();
#ifdef FASTLED_DEBUG_COUNT_FRAME_RETRIES
_retry_cnt++;
#endif
- delayMicroseconds(WAIT_TIME * 10);
- os_intr_lock();
- }
+ delayMicroseconds(WAIT_TIME * 10);
+ os_intr_lock();
+ }
// #if FASTLED_ALLOW_INTTERUPTS == 0
// Adjust the timer
// long microsTaken = CLKS_TO_MICROS(clocks);
@@ -47,19 +48,19 @@ public:
// mWait.mark();
}
- template<int PIN> static void initPin() {
- _ESPPIN<PIN, 1<<(PIN & 0xFF)>::setOutput();
- }
+ template<int PIN> static void initPin() {
+ _ESPPIN<PIN, 1<<(PIN & 0xFF)>::setOutput();
+ }
- virtual void init() {
+ virtual void init() {
void (* funcs[])() ={initPin<12>, initPin<13>, initPin<14>, initPin<15>, initPin<4>, initPin<5>};
for (uint8_t i = 0; i < USED_LANES; ++i) {
funcs[i]();
}
- }
+ }
- virtual uint16_t getMaxRefreshRate() const { return 400; }
+ virtual uint16_t getMaxRefreshRate() const { return 400; }
typedef union {
uint8_t bytes[8];
@@ -69,8 +70,8 @@ public:
#define ESP_ADJUST 0 // (2*(F_CPU/24000000))
#define ESP_ADJUST2 0
- template<int BITS,int PX> __attribute__ ((always_inline)) inline static void writeBits(register uint32_t & last_mark, register Lines & b, PixelController<RGB_ORDER, LANES, PORT_MASK> &pixels) { // , register uint32_t & b2) {
- Lines b2 = b;
+ template<int BITS,int PX> __attribute__ ((always_inline)) inline static void writeBits(register uint32_t & last_mark, register Lines & b, PixelController<RGB_ORDER, LANES, PORT_MASK> &pixels) { // , register uint32_t & b2) {
+ Lines b2 = b;
transpose8x1_noinline(b.bytes,b2.bytes);
register uint8_t d = pixels.template getd<PX>(pixels);
@@ -105,9 +106,9 @@ 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
+ // 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 ICACHE_RAM_ATTR showRGBInternal(PixelController<RGB_ORDER, LANES, PORT_MASK> &allpixels) {
+ static uint32_t ICACHE_RAM_ATTR showRGBInternal(PixelController<RGB_ORDER, LANES, PORT_MASK> &allpixels) {
// Setup the pixel controller and load/scale the first byte
Lines b0;
@@ -132,26 +133,26 @@ public:
// Write third byte
writeBits<8+XTRA0,0>(last_mark, b0, allpixels);
- #if (FASTLED_ALLOW_INTERRUPTS == 1)
+ #if (FASTLED_ALLOW_INTERRUPTS == 1)
os_intr_unlock();
- #endif
+ #endif
allpixels.stepDithering();
- #if (FASTLED_ALLOW_INTERRUPTS == 1)
- os_intr_lock();
+ #if (FASTLED_ALLOW_INTERRUPTS == 1)
+ os_intr_lock();
// if interrupts took longer than 45µs, punt on the current frame
if((int32_t)(__clock_cycles()-last_mark) > 0) {
if((int32_t)(__clock_cycles()-last_mark) > (T1+T2+T3+((WAIT_TIME-INTERRUPT_THRESHOLD)*CLKS_PER_US))) { os_intr_unlock(); return 0; }
}
- #endif
+ #endif
};
- os_intr_unlock();
+ os_intr_unlock();
#ifdef FASTLED_DEBUG_COUNT_FRAME_RETRIES
_frame_cnt++;
#endif
- return __clock_cycles() - _start;
+ return __clock_cycles() - _start;
}
};
diff --git a/platforms/esp/8266/clockless_esp8266.h b/platforms/esp/8266/clockless_esp8266.h
index 83d05b3f..504b9f96 100644
--- a/platforms/esp/8266/clockless_esp8266.h
+++ b/platforms/esp/8266/clockless_esp8266.h
@@ -9,9 +9,9 @@ extern uint32_t _retry_cnt;
// Info on reading cycle counter from https://github.com/kbeckmann/nodemcu-firmware/blob/ws2812-dual/app/modules/ws2812.c
__attribute__ ((always_inline)) inline static uint32_t __clock_cycles() {
- uint32_t cyc;
- __asm__ __volatile__ ("rsr %0,ccount":"=a" (cyc));
- return cyc;
+ uint32_t cyc;
+ __asm__ __volatile__ ("rsr %0,ccount":"=a" (cyc));
+ return cyc;
}
#define FASTLED_HAS_CLOCKLESS 1
@@ -24,6 +24,7 @@ class ClocklessController : public CPixelLEDController<RGB_ORDER> {
data_t mPinMask;
data_ptr_t mPort;
CMinWait<WAIT_TIME> mWait;
+
public:
virtual void init() {
FastPin<DATA_PIN>::setOutput();
@@ -34,37 +35,36 @@ public:
virtual uint16_t getMaxRefreshRate() const { return 400; }
protected:
-
virtual void showPixels(PixelController<RGB_ORDER> & pixels) {
- // mWait.wait();
- int cnt = FASTLED_INTERRUPT_RETRY_COUNT;
- while((showRGBInternal(pixels)==0) && cnt--) {
- #ifdef FASTLED_DEBUG_COUNT_FRAME_RETRIES
- _retry_cnt++;
- #endif
- os_intr_unlock();
- delayMicroseconds(WAIT_TIME);
- os_intr_lock();
- }
- // mWait.mark();
+ // mWait.wait();
+ int cnt = FASTLED_INTERRUPT_RETRY_COUNT;
+ while((showRGBInternal(pixels)==0) && cnt--) {
+ #ifdef FASTLED_DEBUG_COUNT_FRAME_RETRIES
+ _retry_cnt++;
+ #endif
+ os_intr_unlock();
+ delayMicroseconds(WAIT_TIME);
+ os_intr_lock();
+ }
+ // mWait.mark();
}
#define _ESP_ADJ (0)
#define _ESP_ADJ2 (0)
template<int BITS> __attribute__ ((always_inline)) inline static void writeBits(register uint32_t & last_mark, register uint32_t b) {
- b <<= 24; b = ~b;
- for(register uint32_t i = BITS; i > 0; i--) {
- while((__clock_cycles() - last_mark) < (T1+T2+T3));
+ b <<= 24; b = ~b;
+ for(register uint32_t i = BITS; i > 0; i--) {
+ while((__clock_cycles() - last_mark) < (T1+T2+T3));
last_mark = __clock_cycles();
- FastPin<DATA_PIN>::hi();
+ FastPin<DATA_PIN>::hi();
- while((__clock_cycles() - last_mark) < T1);
- if(b & 0x80000000L) { FastPin<DATA_PIN>::lo(); }
- b <<= 1;
+ while((__clock_cycles() - last_mark) < T1);
+ if(b & 0x80000000L) { FastPin<DATA_PIN>::lo(); }
+ b <<= 1;
- while((__clock_cycles() - last_mark) < (T1+T2));
- FastPin<DATA_PIN>::lo();
+ while((__clock_cycles() - last_mark) < (T1+T2));
+ FastPin<DATA_PIN>::lo();
}
}
@@ -74,9 +74,9 @@ protected:
// Setup the pixel controller and load/scale the first byte
pixels.preStepFirstByteDithering();
register uint32_t b = pixels.loadAndScale0();
- pixels.preStepFirstByteDithering();
+ pixels.preStepFirstByteDithering();
os_intr_lock();
- uint32_t start = __clock_cycles();
+ uint32_t start = __clock_cycles();
uint32_t last_mark = start;
while(pixels.has(1)) {
// Write first byte, read next byte
@@ -89,13 +89,13 @@ protected:
// Write third byte, read 1st byte of next pixel
writeBits<8+XTRA0>(last_mark, b);
- b = pixels.advanceAndLoadAndScale0();
+ b = pixels.advanceAndLoadAndScale0();
#if (FASTLED_ALLOW_INTERRUPTS == 1)
os_intr_unlock();
#endif
- pixels.stepDithering();
+ pixels.stepDithering();
#if (FASTLED_ALLOW_INTERRUPTS == 1)
os_intr_lock();
@@ -107,9 +107,9 @@ protected:
};
os_intr_unlock();
- #ifdef FASTLED_DEBUG_COUNT_FRAME_RETRIES
- _frame_cnt++;
- #endif
+ #ifdef FASTLED_DEBUG_COUNT_FRAME_RETRIES
+ _frame_cnt++;
+ #endif
return __clock_cycles() - start;
}
};
diff --git a/platforms/esp/8266/fastpin_esp8266.h b/platforms/esp/8266/fastpin_esp8266.h
index 1ce7934b..4d6cbaaf 100644
--- a/platforms/esp/8266/fastpin_esp8266.h
+++ b/platforms/esp/8266/fastpin_esp8266.h
@@ -3,43 +3,42 @@
FASTLED_NAMESPACE_BEGIN
struct FASTLED_ESP_IO {
- volatile uint32_t _GPO;
- volatile uint32_t _GPOS;
- volatile uint32_t _GPOC;
+ volatile uint32_t _GPO;
+ volatile uint32_t _GPOS;
+ volatile uint32_t _GPOC;
};
#define _GPB (*(FASTLED_ESP_IO*)(0x60000000+(0x300)))
template<uint8_t PIN, uint32_t MASK> class _ESPPIN {
-
public:
- typedef volatile uint32_t * port_ptr_t;
- typedef uint32_t port_t;
+ typedef volatile uint32_t * port_ptr_t;
+ typedef uint32_t port_t;
- inline static void setOutput() { pinMode(PIN, OUTPUT); }
- inline static void setInput() { pinMode(PIN, INPUT); }
+ inline static void setOutput() { pinMode(PIN, OUTPUT); }
+ inline static void setInput() { pinMode(PIN, INPUT); }
- inline static void hi() __attribute__ ((always_inline)) { if(PIN < 16) { _GPB._GPOS = MASK; } else { GP16O |= MASK; } }
- inline static void lo() __attribute__ ((always_inline)) { if(PIN < 16) { _GPB._GPOC = MASK; } else { GP16O &= ~MASK; } }
- inline static void set(register port_t val) __attribute__ ((always_inline)) { if(PIN < 16) { _GPB._GPO = val; } else { GP16O = val; }}
+ inline static void hi() __attribute__ ((always_inline)) { if(PIN < 16) { _GPB._GPOS = MASK; } else { GP16O |= MASK; } }
+ inline static void lo() __attribute__ ((always_inline)) { if(PIN < 16) { _GPB._GPOC = MASK; } else { GP16O &= ~MASK; } }
+ inline static void set(register port_t val) __attribute__ ((always_inline)) { if(PIN < 16) { _GPB._GPO = val; } else { GP16O = val; }}
- inline static void strobe() __attribute__ ((always_inline)) { toggle(); toggle(); }
+ inline static void strobe() __attribute__ ((always_inline)) { toggle(); toggle(); }
- inline static void toggle() __attribute__ ((always_inline)) { if(PIN < 16) { _GPB._GPO ^= MASK; } else { GP16O ^= MASK; } }
+ inline static void toggle() __attribute__ ((always_inline)) { if(PIN < 16) { _GPB._GPO ^= MASK; } else { GP16O ^= MASK; } }
- inline static void hi(register port_ptr_t port) __attribute__ ((always_inline)) { hi(); }
- inline static void lo(register port_ptr_t port) __attribute__ ((always_inline)) { lo(); }
- inline static void fastset(register port_ptr_t port, register port_t val) __attribute__ ((always_inline)) { *port = val; }
+ inline static void hi(register port_ptr_t port) __attribute__ ((always_inline)) { hi(); }
+ inline static void lo(register port_ptr_t port) __attribute__ ((always_inline)) { lo(); }
+ inline static void fastset(register port_ptr_t port, register port_t val) __attribute__ ((always_inline)) { *port = val; }
- inline static port_t hival() __attribute__ ((always_inline)) { if (PIN<16) { return GPO | MASK; } else { return GP16O | MASK; } }
- inline static port_t loval() __attribute__ ((always_inline)) { if (PIN<16) { return GPO & ~MASK; } else { return GP16O & ~MASK; } }
- inline static port_ptr_t port() __attribute__ ((always_inline)) { if(PIN<16) { return &_GPB._GPO; } else { return &GP16O; } }
- inline static port_ptr_t sport() __attribute__ ((always_inline)) { return &_GPB._GPOS; } // there is no GP160 support for this
- inline static port_ptr_t cport() __attribute__ ((always_inline)) { return &_GPB._GPOC; }
- inline static port_t mask() __attribute__ ((always_inline)) { return MASK; }
+ inline static port_t hival() __attribute__ ((always_inline)) { if (PIN<16) { return GPO | MASK; } else { return GP16O | MASK; } }
+ inline static port_t loval() __attribute__ ((always_inline)) { if (PIN<16) { return GPO & ~MASK; } else { return GP16O & ~MASK; } }
+ inline static port_ptr_t port() __attribute__ ((always_inline)) { if(PIN<16) { return &_GPB._GPO; } else { return &GP16O; } }
+ inline static port_ptr_t sport() __attribute__ ((always_inline)) { return &_GPB._GPOS; } // there is no GP160 support for this
+ inline static port_ptr_t cport() __attribute__ ((always_inline)) { return &_GPB._GPOC; }
+ inline static port_t mask() __attribute__ ((always_inline)) { return MASK; }
- inline static bool isset() __attribute__ ((always_inline)) { return (PIN < 16) ? (GPO & MASK) : (GP16O & MASK); }
+ inline static bool isset() __attribute__ ((always_inline)) { return (PIN < 16) ? (GPO & MASK) : (GP16O & MASK); }
};
#define _FL_DEFPIN(PIN, REAL_PIN) template<> class FastPin<PIN> : public _ESPPIN<REAL_PIN, (1<<(REAL_PIN & 0xFF))> {};
diff --git a/power_mgt.cpp b/power_mgt.cpp
index 8e46d93f..33b4cece 100644
--- a/power_mgt.cpp
+++ b/power_mgt.cpp
@@ -88,7 +88,7 @@ uint8_t calculate_max_brightness_for_power_mW(const CRGB* ledbuffer, uint16_t nu
uint8_t recommended_brightness = target_brightness;
if(requested_power_mW > max_power_mW) {
- recommended_brightness = (uint32_t)((uint8_t)(target_brightness) * (uint32_t)(max_power_mW)) / ((uint32_t)(requested_power_mW));
+ recommended_brightness = (uint32_t)((uint8_t)(target_brightness) * (uint32_t)(max_power_mW)) / ((uint32_t)(requested_power_mW));
}
return recommended_brightness;
@@ -163,23 +163,23 @@ void set_max_power_indicator_LED( uint8_t pinNumber)
void set_max_power_in_volts_and_milliamps( uint8_t volts, uint32_t milliamps)
{
- FastLED.setMaxPowerInVoltsAndMilliamps(volts, milliamps);
+ FastLED.setMaxPowerInVoltsAndMilliamps(volts, milliamps);
}
void set_max_power_in_milliwatts( uint32_t powerInmW)
{
- FastLED.setMaxPowerInMilliWatts(powerInmW);
+ FastLED.setMaxPowerInMilliWatts(powerInmW);
}
void show_at_max_brightness_for_power()
{
- // power management usage is now in FastLED.show, no need for this function
- FastLED.show();
+ // power management usage is now in FastLED.show, no need for this function
+ FastLED.show();
}
void delay_at_max_brightness_for_power( uint16_t ms)
{
- FastLED.delay(ms);
+ FastLED.delay(ms);
}
FASTLED_NAMESPACE_END
diff --git a/wiring.cpp b/wiring.cpp
index b2af51cd..e366c64c 100644
--- a/wiring.cpp
+++ b/wiring.cpp
@@ -17,16 +17,16 @@ volatile unsigned long FastLED_timer0_overflow_count=0;
volatile unsigned long FastLED_timer0_millis = 0;
LIB8STATIC void __attribute__((always_inline)) fastinc32 (volatile uint32_t & _long) {
- uint8_t b = ++((tBytesForLong&)_long).raw[0];
- if(!b) {
- b = ++((tBytesForLong&)_long).raw[1];
+ uint8_t b = ++((tBytesForLong&)_long).raw[0];
if(!b) {
- b = ++((tBytesForLong&)_long).raw[2];
- if(!b) {
- ++((tBytesForLong&)_long).raw[3];
- }
+ b = ++((tBytesForLong&)_long).raw[1];
+ if(!b) {
+ b = ++((tBytesForLong&)_long).raw[2];
+ if(!b) {
+ ++((tBytesForLong&)_long).raw[3];
+ }
+ }
}
- }
}
#if defined(__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__)
@@ -35,200 +35,200 @@ ISR(TIM0_OVF_vect)
ISR(TIMER0_OVF_vect)
#endif
{
- fastinc32(FastLED_timer0_overflow_count);
- // FastLED_timer0_overflow_count++;
+ fastinc32(FastLED_timer0_overflow_count);
+ // FastLED_timer0_overflow_count++;
}
// there are 1024 microseconds per overflow counter tick.
unsigned long millis()
{
- unsigned long m;
- uint8_t oldSREG = SREG;
+ unsigned long m;
+ uint8_t oldSREG = SREG;
- // disable interrupts while we read FastLED_timer0_millis or we might get an
- // inconsistent value (e.g. in the middle of a write to FastLED_timer0_millis)
- cli();
- m = FastLED_timer0_overflow_count; //._long;
- SREG = oldSREG;
+ // disable interrupts while we read FastLED_timer0_millis or we might get an
+ // inconsistent value (e.g. in the middle of a write to FastLED_timer0_millis)
+ cli();
+ m = FastLED_timer0_overflow_count; //._long;
+ SREG = oldSREG;
- return (m*(MICROSECONDS_PER_TIMER0_OVERFLOW/8))/(1000/8);
+ return (m*(MICROSECONDS_PER_TIMER0_OVERFLOW/8))/(1000/8);
}
unsigned long micros() {
- unsigned long m;
- uint8_t oldSREG = SREG, t;
+ unsigned long m;
+ uint8_t oldSREG = SREG, t;
- cli();
- m = FastLED_timer0_overflow_count; // ._long;
+ cli();
+ m = FastLED_timer0_overflow_count; // ._long;
#if defined(TCNT0)
- t = TCNT0;
+ t = TCNT0;
#elif defined(TCNT0L)
- t = TCNT0L;
+ t = TCNT0L;
#else
- #error TIMER 0 not defined
+#error TIMER 0 not defined
#endif
#ifdef TIFR0
- if ((TIFR0 & _BV(TOV0)) && (t < 255))
- m++;
+ if ((TIFR0 & _BV(TOV0)) && (t < 255))
+ m++;
#else
- if ((TIFR & _BV(TOV0)) && (t < 255))
- m++;
+ if ((TIFR & _BV(TOV0)) && (t < 255))
+ m++;
#endif
- SREG = oldSREG;
+ SREG = oldSREG;
- return ((m << 8) + t) * (64 / clockCyclesPerMicrosecond());
+ return ((m << 8) + t) * (64 / clockCyclesPerMicrosecond());
}
void delay(unsigned long ms)
{
- uint16_t start = (uint16_t)micros();
+ uint16_t start = (uint16_t)micros();
- while (ms > 0) {
- if (((uint16_t)micros() - start) >= 1000) {
- ms--;
- start += 1000;
- }
+ while (ms > 0) {
+ if (((uint16_t)micros() - start) >= 1000) {
+ ms--;
+ start += 1000;
}
+ }
}
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
void init()
{
- // this needs to be called before setup() or some functions won't
- // work there
- sei();
+ // this needs to be called before setup() or some functions won't
+ // work there
+ sei();
- // on the ATmega168, timer 0 is also used for fast hardware pwm
- // (using phase-correct PWM would mean that timer 0 overflowed half as often
- // resulting in different millis() behavior on the ATmega8 and ATmega168)
+ // on the ATmega168, timer 0 is also used for fast hardware pwm
+ // (using phase-correct PWM would mean that timer 0 overflowed half as often
+ // resulting in different millis() behavior on the ATmega8 and ATmega168)
#if defined(TCCR0A) && defined(WGM01)
- sbi(TCCR0A, WGM01);
- sbi(TCCR0A, WGM00);
+ sbi(TCCR0A, WGM01);
+ sbi(TCCR0A, WGM00);
#endif
- // set timer 0 prescale factor to 64
+ // set timer 0 prescale factor to 64
#if defined(__AVR_ATmega128__)
- // CPU specific: different values for the ATmega128
- sbi(TCCR0, CS02);
+ // CPU specific: different values for the ATmega128
+ sbi(TCCR0, CS02);
#elif defined(TCCR0) && defined(CS01) && defined(CS00)
- // this combination is for the standard atmega8
- sbi(TCCR0, CS01);
- sbi(TCCR0, CS00);
+ // this combination is for the standard atmega8
+ sbi(TCCR0, CS01);
+ sbi(TCCR0, CS00);
#elif defined(TCCR0B) && defined(CS01) && defined(CS00)
- // this combination is for the standard 168/328/1280/2560
- sbi(TCCR0B, CS01);
- sbi(TCCR0B, CS00);
+ // this combination is for the standard 168/328/1280/2560
+ sbi(TCCR0B, CS01);
+ sbi(TCCR0B, CS00);
#elif defined(TCCR0A) && defined(CS01) && defined(CS00)
- // this combination is for the __AVR_ATmega645__ series
- sbi(TCCR0A, CS01);
- sbi(TCCR0A, CS00);
+ // this combination is for the __AVR_ATmega645__ series
+ sbi(TCCR0A, CS01);
+ sbi(TCCR0A, CS00);
#else
- #error Timer 0 prescale factor 64 not set correctly
+#error Timer 0 prescale factor 64 not set correctly
#endif
- // enable timer 0 overflow interrupt
+ // enable timer 0 overflow interrupt
#if defined(TIMSK) && defined(TOIE0)
- sbi(TIMSK, TOIE0);
+ sbi(TIMSK, TOIE0);
#elif defined(TIMSK0) && defined(TOIE0)
- sbi(TIMSK0, TOIE0);
+ sbi(TIMSK0, TOIE0);
#else
- #error Timer 0 overflow interrupt not set correctly
+#error Timer 0 overflow interrupt not set correctly
#endif
- // timers 1 and 2 are used for phase-correct hardware pwm
- // this is better for motors as it ensures an even waveform
- // note, however, that fast pwm mode can achieve a frequency of up
- // 8 MHz (with a 16 MHz clock) at 50% duty cycle
+ // timers 1 and 2 are used for phase-correct hardware pwm
+ // this is better for motors as it ensures an even waveform
+ // note, however, that fast pwm mode can achieve a frequency of up
+ // 8 MHz (with a 16 MHz clock) at 50% duty cycle
#if defined(TCCR1B) && defined(CS11) && defined(CS10)
- TCCR1B = 0;
+ TCCR1B = 0;
- // set timer 1 prescale factor to 64
- sbi(TCCR1B, CS11);
+ // set timer 1 prescale factor to 64
+ sbi(TCCR1B, CS11);
#if F_CPU >= 8000000L
- sbi(TCCR1B, CS10);
+ sbi(TCCR1B, CS10);
#endif
#elif defined(TCCR1) && defined(CS11) && defined(CS10)
- sbi(TCCR1, CS11);
+ sbi(TCCR1, CS11);
#if F_CPU >= 8000000L
- sbi(TCCR1, CS10);
+ sbi(TCCR1, CS10);
#endif
#endif
- // put timer 1 in 8-bit phase correct pwm mode
+ // put timer 1 in 8-bit phase correct pwm mode
#if defined(TCCR1A) && defined(WGM10)
- sbi(TCCR1A, WGM10);
+ sbi(TCCR1A, WGM10);
#elif defined(TCCR1)
- #warning this needs to be finished
+#warning this needs to be finished
#endif
// set timer 2 prescale factor to 64
#if defined(TCCR2) && defined(CS22)
- sbi(TCCR2, CS22);
+ sbi(TCCR2, CS22);
#elif defined(TCCR2B) && defined(CS22)
- sbi(TCCR2B, CS22);
+ sbi(TCCR2B, CS22);
#else
- #warning Timer 2 not finished (may not be present on this CPU)
+#warning Timer 2 not finished (may not be present on this CPU)
#endif
// configure timer 2 for phase correct pwm (8-bit)
#if defined(TCCR2) && defined(WGM20)
- sbi(TCCR2, WGM20);
+ sbi(TCCR2, WGM20);
#elif defined(TCCR2A) && defined(WGM20)
- sbi(TCCR2A, WGM20);
+ sbi(TCCR2A, WGM20);
#else
- #warning Timer 2 not finished (may not be present on this CPU)
+#warning Timer 2 not finished (may not be present on this CPU)
#endif
#if defined(TCCR3B) && defined(CS31) && defined(WGM30)
- sbi(TCCR3B, CS31); // set timer 3 prescale factor to 64
- sbi(TCCR3B, CS30);
- sbi(TCCR3A, WGM30); // put timer 3 in 8-bit phase correct pwm mode
+ sbi(TCCR3B, CS31); // set timer 3 prescale factor to 64
+ sbi(TCCR3B, CS30);
+ sbi(TCCR3A, WGM30); // put timer 3 in 8-bit phase correct pwm mode
#endif
#if defined(TCCR4A) && defined(TCCR4B) && defined(TCCR4D) /* beginning of timer4 block for 32U4 and similar */
- sbi(TCCR4B, CS42); // set timer4 prescale factor to 64
- sbi(TCCR4B, CS41);
- sbi(TCCR4B, CS40);
- sbi(TCCR4D, WGM40); // put timer 4 in phase- and frequency-correct PWM mode
- sbi(TCCR4A, PWM4A); // enable PWM mode for comparator OCR4A
- sbi(TCCR4C, PWM4D); // enable PWM mode for comparator OCR4D
+ sbi(TCCR4B, CS42); // set timer4 prescale factor to 64
+ sbi(TCCR4B, CS41);
+ sbi(TCCR4B, CS40);
+ sbi(TCCR4D, WGM40); // put timer 4 in phase- and frequency-correct PWM mode
+ sbi(TCCR4A, PWM4A); // enable PWM mode for comparator OCR4A
+ sbi(TCCR4C, PWM4D); // enable PWM mode for comparator OCR4D
#else /* beginning of timer4 block for ATMEGA1280 and ATMEGA2560 */
#if defined(TCCR4B) && defined(CS41) && defined(WGM40)
- sbi(TCCR4B, CS41); // set timer 4 prescale factor to 64
- sbi(TCCR4B, CS40);
- sbi(TCCR4A, WGM40); // put timer 4 in 8-bit phase correct pwm mode
+ sbi(TCCR4B, CS41); // set timer 4 prescale factor to 64
+ sbi(TCCR4B, CS40);
+ sbi(TCCR4A, WGM40); // put timer 4 in 8-bit phase correct pwm mode
#endif
#endif /* end timer4 block for ATMEGA1280/2560 and similar */
#if defined(TCCR5B) && defined(CS51) && defined(WGM50)
- sbi(TCCR5B, CS51); // set timer 5 prescale factor to 64
- sbi(TCCR5B, CS50);
- sbi(TCCR5A, WGM50); // put timer 5 in 8-bit phase correct pwm mode
+ sbi(TCCR5B, CS51); // set timer 5 prescale factor to 64
+ sbi(TCCR5B, CS50);
+ sbi(TCCR5A, WGM50); // put timer 5 in 8-bit phase correct pwm mode
#endif
#if defined(ADCSRA)
- // set a2d prescale factor to 128
- // 16 MHz / 128 = 125 KHz, inside the desired 50-200 KHz range.
- // XXX: this will not work properly for other clock speeds, and
- // this code should use F_CPU to determine the prescale factor.
- sbi(ADCSRA, ADPS2);
- sbi(ADCSRA, ADPS1);
- sbi(ADCSRA, ADPS0);
+ // set a2d prescale factor to 128
+ // 16 MHz / 128 = 125 KHz, inside the desired 50-200 KHz range.
+ // XXX: this will not work properly for other clock speeds, and
+ // this code should use F_CPU to determine the prescale factor.
+ sbi(ADCSRA, ADPS2);
+ sbi(ADCSRA, ADPS1);
+ sbi(ADCSRA, ADPS0);
- // enable a2d conversions
- sbi(ADCSRA, ADEN);
+ // enable a2d conversions
+ sbi(ADCSRA, ADEN);
#endif
- // the bootloader connects pins 0 and 1 to the USART; disconnect them
- // here so they can be used as normal digital i/o; they will be
- // reconnected in Serial.begin()
+ // the bootloader connects pins 0 and 1 to the USART; disconnect them
+ // here so they can be used as normal digital i/o; they will be
+ // reconnected in Serial.begin()
#if defined(UCSRB)
- UCSRB = 0;
+ UCSRB = 0;
#elif defined(UCSR0B)
- UCSR0B = 0;
+ UCSR0B = 0;
#endif
}
};