diff options
author | Daniel Garcia <danielgarcia@gmail.com> | 2015-06-30 08:55:00 +0300 |
---|---|---|
committer | Daniel Garcia <danielgarcia@gmail.com> | 2015-06-30 08:55:00 +0300 |
commit | c1285ef603fa3017af21101ebf5ce7354be1c0bb (patch) | |
tree | 33dda2ef0854b828a232be03ddf03a7b65d8172a | |
parent | 681cb735570bfd5fb6b32599459aa2c576164184 (diff) | |
parent | bf0014574f4bc643ccf2b96f3b6b5f178a83786f (diff) |
Merge branch 'FastLED3.1' into d21
30 files changed, 411 insertions, 241 deletions
@@ -54,7 +54,7 @@ FASTLED_NAMESPACE_BEGIN -/// definitions for the spi chipset constants +/// definitions for the spi chipset constants enum ESPIChipsets { LPD8806, WS2801, @@ -66,7 +66,7 @@ enum ESPIChipsets { }; enum ESM { SMART_MATRIX }; -enum OWS2811 { OCTOWS2811 }; +enum OWS2811 { OCTOWS2811,OCTOWS2811_400 }; #ifdef FASTLED_HAS_CLOCKLESS template<uint8_t DATA_PIN> class NEOPIXEL : public WS2812Controller800Khz<DATA_PIN, GRB> {}; @@ -96,18 +96,23 @@ template<EOrder RGB_ORDER> class DMXSERIAL : public DMXSerialController<RGB_ORDE enum EBlockChipsets { #ifdef PORTA_FIRST_PIN WS2811_PORTA, + WS2811_400_PORTA, #endif #ifdef PORTB_FIRST_PIN WS2811_PORTB, + WS2811_400_PORTB, #endif #ifdef PORTC_FIRST_PIN WS2811_PORTC, + WS2811_400_PORTC, #endif #ifdef PORTD_FIRST_PIN WS2811_PORTD, + WS2811_400_PORTD, #endif #ifdef HAS_PORTDC WS2811_PORTDC, + WS2811_400_PORTDC, #endif }; @@ -300,6 +305,7 @@ public: { switch(CHIPSET) { case OCTOWS2811: { static COctoWS2811Controller<RGB_ORDER> controller; return addLeds(&controller, data, nLedsOrOffset, nLedsIfOffset); } + case OCTOWS2811_400: { static COctoWS2811Controller<RGB_ORDER,true> controller; return addLeds(&controller, data, nLedsOrOffset, nLedsIfOffset); } } } @@ -348,18 +354,23 @@ public: switch(CHIPSET) { #ifdef PORTA_FIRST_PIN case WS2811_PORTA: return addLeds(new InlineBlockClocklessController<NUM_LANES, PORTA_FIRST_PIN, NS(320), NS(320), NS(640), RGB_ORDER>(), data, nLedsOrOffset, nLedsIfOffset); + case WS2811_400_PORTA: return addLeds(new InlineBlockClocklessController<NUM_LANES, PORTA_FIRST_PIN, NS(800), NS(800), NS(900), RGB_ORDER>(), data, nLedsOrOffset, nLedsIfOffset); #endif #ifdef PORTB_FIRST_PIN case WS2811_PORTB: return addLeds(new InlineBlockClocklessController<NUM_LANES, PORTB_FIRST_PIN, NS(320), NS(320), NS(640), RGB_ORDER>(), data, nLedsOrOffset, nLedsIfOffset); + case WS2811_400_PORTB: return addLeds(new InlineBlockClocklessController<NUM_LANES, PORTB_FIRST_PIN, NS(800), NS(800), NS(900), RGB_ORDER>(), data, nLedsOrOffset, nLedsIfOffset); #endif #ifdef PORTC_FIRST_PIN case WS2811_PORTC: return addLeds(new InlineBlockClocklessController<NUM_LANES, PORTC_FIRST_PIN, NS(320), NS(320), NS(640), RGB_ORDER>(), data, nLedsOrOffset, nLedsIfOffset); + case WS2811_400_PORTC: return addLeds(new InlineBlockClocklessController<NUM_LANES, PORTC_FIRST_PIN, NS(800), NS(800), NS(900), RGB_ORDER>(), data, nLedsOrOffset, nLedsIfOffset); #endif #ifdef PORTD_FIRST_PIN case WS2811_PORTD: return addLeds(new InlineBlockClocklessController<NUM_LANES, PORTD_FIRST_PIN, NS(320), NS(320), NS(640), RGB_ORDER>(), data, nLedsOrOffset, nLedsIfOffset); + case WS2811_400_PORTD: return addLeds(new InlineBlockClocklessController<NUM_LANES, PORTD_FIRST_PIN, NS(800), NS(800), NS(900), RGB_ORDER>(), data, nLedsOrOffset, nLedsIfOffset); #endif #ifdef HAS_PORTDC case WS2811_PORTDC: return addLeds(new SixteenWayInlineBlockClocklessController<16,NS(320), NS(320), NS(640), RGB_ORDER>(), data, nLedsOrOffset, nLedsIfOffset); + case WS2811_400_PORTDC: return addLeds(new SixteenWayInlineBlockClocklessController<16,NS(800), NS(800), NS(900), RGB_ORDER>(), data, nLedsOrOffset, nLedsIfOffset); #endif } } @@ -2,12 +2,12 @@ == Setting up the basic files/folders == -* Create platform directory (e.g. platforms/arm/k26) -* Create configuration header led_sysdefs_arm_k26.h: +* Create platform directory (e.g. platforms/arm/kl26) +* Create configuration header led_sysdefs_arm_kl26.h: * Define platform flags (like FASTLED_ARM/FASTLED_TEENSY) * Define configuration parameters re: interrupts, or clock doubling * Include extar system header files if needed -* Create main platform include, fastled_arm_k26.h +* Create main platform include, fastled_arm_kl26.h * Include the various other header files as needed * Modify led_sysdefs.h to conditionally include platform sysdefs header file * Modify platforms.h to conditionally include platform fastled header @@ -33,8 +33,8 @@ How quickly can you get up and running with the library? Here's a simple blink #define NUM_LEDS 60 CRGB leds[NUM_LEDS]; void setup() { FastLED.addLeds<NEOPIXEL, 6>(leds, NUM_LEDS); } - void loop() { - leds[0] = CRGB::White; FastLED.show(); delay(30); + void loop() { + leds[0] = CRGB::White; FastLED.show(); delay(30); leds[0] = CRGB::Black; FastLED.show(); delay(30); } @@ -42,6 +42,7 @@ How quickly can you get up and running with the library? Here's a simple blink Here's a list of all the LED chipsets are supported. More details on the led chipsets are included *TODO: Link to wiki page* +* Adafruit's DotStars - AKA the APA102 * Adafruit's Neopixel - aka the WS2812B (also WS2811/WS2812, also suppored in lo-speed mode) - a 3 wire addressable led chipset * TM1809/4 - 3 wire chipset, cheaply available on aliexpress.com * TM1803 - 3 wire chipset, sold by radio shack @@ -63,12 +64,14 @@ LPD6803, HL1606, and "595"-style shift registers are no longer supported by the Right now the library is supported on a variety of arduino compatable platforms. If it's ARM or AVR and uses the arduino software (or a modified version of it to build) then it is likely supported. Note that we have a long list of upcoming platforms to support, so if you don't see what you're looking for here, ask, it may be on the roadmap (or may already be supported). N.B. at the moment we are only supporting the stock compilers that ship with the arduino software. Support for upgraded compilers, as well as using AVR studio and skipping the arduino entirely, should be coming in a near future release. -* Arduino & compatibles - straight up arduino devices, uno, duo, leonardo, mega, nano, etc... +* Arduino & compatibles - straight up arduino devices, uno, duo, leonardo, mega, nano, etc... NOTE: On the mega, you can't use pins 42,43,44,45,46,47,48, and 49 with 3-wire chipsets. * Adafruit Trinket & Gemma - Trinket Pro may be supported, but haven't tested to confirm yet -* Teensy 2, Teensy++ 2, Teensy 3.1 - arduino compataible from pjrc.com with some extra goodies (note the teensy 3 is ARM, not AVR!) +* Teensy 2, Teensy++ 2, Teensy 3.0, Teensy 3.1, Teensy LC - arduino compataible from pjrc.com with some extra goodies (note the teensy 3 is ARM, not AVR!) * Arduino Due and the digistump DigiX +* RFDuino +* SparkCore -What types of platforms are we thinking about supporting in the future? Here's a short list: RFDuino, SparkCore, MSP430, ChipKit32, Maple, Beagleboard +What types of platforms are we thinking about supporting in the future? Here's a short list: ChipKit32, Maple, Beagleboard ## What about that name? @@ -80,4 +83,3 @@ Check out the official site http://fastled.io for links to documentation, issues *TODO* - get candy - @@ -55,6 +55,7 @@ public: mSPI.select(); mSPI.writeBytesValueRaw(0x80, nLeds * 3); mSPI.writeBytesValueRaw(0, ((nLeds*3+63)>>6)); + mSPI.waitFully(); mSPI.release(); } @@ -151,7 +152,7 @@ class APA102Controller : public CLEDController { SPI mSPI; void startBoundary() { mSPI.writeWord(0); mSPI.writeWord(0); } - void endBoundary(int nLeds) { int nBytes = (nLeds/64); do { mSPI.writeByte(0xFF); mSPI.writeByte(0x00); mSPI.writeByte(0x00); mSPI.writeByte(0x00); } while(nBytes--); } + void endBoundary(int nLeds) { int nBytes = (nLeds/32); do { mSPI.writeByte(0xFF); mSPI.writeByte(0x00); mSPI.writeByte(0x00); mSPI.writeByte(0x00); } while(nBytes--); } inline void writeLed(uint8_t b0, uint8_t b1, uint8_t b2) __attribute__((always_inline)) { mSPI.writeByte(0xFF); mSPI.writeByte(b0); mSPI.writeByte(b1); mSPI.writeByte(b2); @@ -198,7 +199,7 @@ protected: pixels.stepDithering(); } endBoundary(nLeds); - + mSPI.waitFully(); mSPI.release(); } @@ -215,7 +216,7 @@ protected: pixels.stepDithering(); } endBoundary(nLeds); - + mSPI.waitFully(); mSPI.release(); } #endif @@ -286,6 +287,7 @@ protected: pixels.stepDithering(); } writeBoundary(); + mSPI.waitFully(); mSPI.release(); } @@ -303,6 +305,7 @@ protected: pixels.stepDithering(); } writeBoundary(); + mSPI.waitFully(); mSPI.release(); } diff --git a/colorutils.h b/colorutils.h index b44afffa..35627835 100644 --- a/colorutils.h +++ b/colorutils.h @@ -809,17 +809,17 @@ public: -typedef enum { NOBLEND=0, BLEND=1 } TBlendType; +typedef enum { NOBLEND=0, LINEARBLEND=1 } TBlendType; CRGB ColorFromPalette( const CRGBPalette16& pal, uint8_t index, uint8_t brightness=255, - TBlendType blendType=BLEND); + TBlendType blendType=LINEARBLEND); CRGB ColorFromPalette( const TProgmemRGBPalette16& pal, uint8_t index, uint8_t brightness=255, - TBlendType blendType=BLEND); + TBlendType blendType=LINEARBLEND); CRGB ColorFromPalette( const CRGBPalette256& pal, uint8_t index, @@ -829,7 +829,7 @@ CRGB ColorFromPalette( const CRGBPalette256& pal, CHSV ColorFromPalette( const CHSVPalette16& pal, uint8_t index, uint8_t brightness=255, - TBlendType blendType=BLEND); + TBlendType blendType=LINEARBLEND); CHSV ColorFromPalette( const CHSVPalette256& pal, uint8_t index, @@ -856,7 +856,7 @@ void map_data_into_colors_through_palette( const PALETTE& pal, uint8_t brightness=255, uint8_t opacity=255, - TBlendType blendType=BLEND) + TBlendType blendType=LINEARBLEND) { for( uint16_t i = 0; i < dataCount; i++) { uint8_t d = dataArray[i]; diff --git a/examples/Blink/Blink.ino b/examples/Blink/Blink.ino index ab307fda..95eb6cb2 100644 --- a/examples/Blink/Blink.ino +++ b/examples/Blink/Blink.ino @@ -21,6 +21,7 @@ void setup() { // FastLED.addLeds<WS2812, DATA_PIN, RGB>(leds, NUM_LEDS); // FastLED.addLeds<WS2812B, DATA_PIN, RGB>(leds, NUM_LEDS); FastLED.addLeds<NEOPIXEL, DATA_PIN>(leds, NUM_LEDS); + // FastLED.addLeds<APA104, DATA_PIN, RGB>(leds, NUM_LEDS); // FastLED.addLeds<UCS1903, DATA_PIN, RGB>(leds, NUM_LEDS); // FastLED.addLeds<UCS1903B, DATA_PIN, RGB>(leds, NUM_LEDS); // FastLED.addLeds<GW6205, DATA_PIN, RGB>(leds, NUM_LEDS); @@ -29,10 +30,16 @@ void setup() { // FastLED.addLeds<WS2801, RGB>(leds, NUM_LEDS); // FastLED.addLeds<SM16716, RGB>(leds, NUM_LEDS); // FastLED.addLeds<LPD8806, RGB>(leds, NUM_LEDS); + // FastLED.addLeds<P9813, RGB>(leds, NUM_LEDS); + // FastLED.addLeds<APA102, RGB>(leds, NUM_LEDS); + // FastLED.addLeds<DOTSTAR, RGB>(leds, NUM_LEDS); // FastLED.addLeds<WS2801, DATA_PIN, CLOCK_PIN, RGB>(leds, NUM_LEDS); // FastLED.addLeds<SM16716, DATA_PIN, CLOCK_PIN, RGB>(leds, NUM_LEDS); // FastLED.addLeds<LPD8806, DATA_PIN, CLOCK_PIN, RGB>(leds, NUM_LEDS); + // FastLED.addLeds<P9813, DATA_PIN, CLOCK_PIN, RGB>(leds, NUM_LEDS); + // FastLED.addLeds<APA102, DATA_PIN, CLOCK_PIN, RGB>(leds, NUM_LEDS); + // FastLED.addLeds<DOTSTAR, DATA_PIN, CLOCK_PIN, RGB>(leds, NUM_LEDS); } void loop() { diff --git a/examples/ColorPalette/ColorPalette.ino b/examples/ColorPalette/ColorPalette.ino index 93318998..0fdfb594 100644 --- a/examples/ColorPalette/ColorPalette.ino +++ b/examples/ColorPalette/ColorPalette.ino @@ -12,18 +12,18 @@ CRGB leds[NUM_LEDS]; // This example shows several ways to set up and use 'palettes' of colors // with FastLED. // -// These compact palettes provide an easy way to re-colorize your +// These compact palettes provide an easy way to re-colorize your // animation on the fly, quickly, easily, and with low overhead. // // USING palettes is MUCH simpler in practice than in theory, so first just -// run this sketch, and watch the pretty lights as you then read through +// run this sketch, and watch the pretty lights as you then read through // the code. Although this sketch has eight (or more) different color schemes, // the entire sketch compiles down to about 6.5K on AVR. // // FastLED provides a few pre-configured color palettes, and makes it // extremely easy to make up your own color schemes with palettes. // -// Some notes on the more abstract 'theory and practice' of +// Some notes on the more abstract 'theory and practice' of // FastLED compact palettes are at the bottom of this file. @@ -36,36 +36,36 @@ extern const TProgmemPalette16 myRedWhiteBluePalette_p PROGMEM; void setup() { - delay( 3000 ); // power-up safety delay - FastLED.addLeds<LED_TYPE, LED_PIN, COLOR_ORDER>(leds, NUM_LEDS).setCorrection( TypicalLEDStrip ); - FastLED.setBrightness( BRIGHTNESS ); - - currentPalette = RainbowColors_p; - currentBlending = BLEND; + delay( 3000 ); // power-up safety delay + FastLED.addLeds<LED_TYPE, LED_PIN, COLOR_ORDER>(leds, NUM_LEDS).setCorrection( TypicalLEDStrip ); + FastLED.setBrightness( BRIGHTNESS ); + + currentPalette = RainbowColors_p; + currentBlending = LINEARBLEND; } void loop() { - ChangePalettePeriodically(); - - static uint8_t startIndex = 0; - startIndex = startIndex + 1; /* motion speed */ - - FillLEDsFromPaletteColors( startIndex); - - FastLED.show(); - FastLED.delay(1000 / UPDATES_PER_SECOND); + ChangePalettePeriodically(); + + static uint8_t startIndex = 0; + startIndex = startIndex + 1; /* motion speed */ + + FillLEDsFromPaletteColors( startIndex); + + FastLED.show(); + FastLED.delay(1000 / UPDATES_PER_SECOND); } void FillLEDsFromPaletteColors( uint8_t colorIndex) { - uint8_t brightness = 255; - - for( int i = 0; i < NUM_LEDS; i++) { - leds[i] = ColorFromPalette( currentPalette, colorIndex, brightness, currentBlending); - colorIndex += 3; - } + uint8_t brightness = 255; + + for( int i = 0; i < NUM_LEDS; i++) { + leds[i] = ColorFromPalette( currentPalette, colorIndex, brightness, currentBlending); + colorIndex += 3; + } } @@ -79,31 +79,31 @@ void FillLEDsFromPaletteColors( uint8_t colorIndex) void ChangePalettePeriodically() { - uint8_t secondHand = (millis() / 1000) % 60; - static uint8_t lastSecond = 99; - - if( lastSecond != secondHand) { - lastSecond = secondHand; - if( secondHand == 0) { currentPalette = RainbowColors_p; currentBlending = BLEND; } - if( secondHand == 10) { currentPalette = RainbowStripeColors_p; currentBlending = NOBLEND; } - if( secondHand == 15) { currentPalette = RainbowStripeColors_p; currentBlending = BLEND; } - if( secondHand == 20) { SetupPurpleAndGreenPalette(); currentBlending = BLEND; } - if( secondHand == 25) { SetupTotallyRandomPalette(); currentBlending = BLEND; } - if( secondHand == 30) { SetupBlackAndWhiteStripedPalette(); currentBlending = NOBLEND; } - if( secondHand == 35) { SetupBlackAndWhiteStripedPalette(); currentBlending = BLEND; } - if( secondHand == 40) { currentPalette = CloudColors_p; currentBlending = BLEND; } - if( secondHand == 45) { currentPalette = PartyColors_p; currentBlending = BLEND; } - if( secondHand == 50) { currentPalette = myRedWhiteBluePalette_p; currentBlending = NOBLEND; } - if( secondHand == 55) { currentPalette = myRedWhiteBluePalette_p; currentBlending = BLEND; } - } + uint8_t secondHand = (millis() / 1000) % 60; + static uint8_t lastSecond = 99; + + if( lastSecond != secondHand) { + lastSecond = secondHand; + if( secondHand == 0) { currentPalette = RainbowColors_p; currentBlending = LINEARBLEND; } + if( secondHand == 10) { currentPalette = RainbowStripeColors_p; currentBlending = NOBLEND; } + if( secondHand == 15) { currentPalette = RainbowStripeColors_p; currentBlending = LINEARBLEND; } + if( secondHand == 20) { SetupPurpleAndGreenPalette(); currentBlending = LINEARBLEND; } + if( secondHand == 25) { SetupTotallyRandomPalette(); currentBlending = LINEARBLEND; } + if( secondHand == 30) { SetupBlackAndWhiteStripedPalette(); currentBlending = NOBLEND; } + if( secondHand == 35) { SetupBlackAndWhiteStripedPalette(); currentBlending = LINEARBLEND; } + if( secondHand == 40) { currentPalette = CloudColors_p; currentBlending = LINEARBLEND; } + if( secondHand == 45) { currentPalette = PartyColors_p; currentBlending = LINEARBLEND; } + if( secondHand == 50) { currentPalette = myRedWhiteBluePalette_p; currentBlending = NOBLEND; } + if( secondHand == 55) { currentPalette = myRedWhiteBluePalette_p; currentBlending = LINEARBLEND; } + } } // This function fills the palette with totally random colors. void SetupTotallyRandomPalette() { - for( int i = 0; i < 16; i++) { - currentPalette[i] = CHSV( random8(), 255, random8()); - } + for( int i = 0; i < 16; i++) { + currentPalette[i] = CHSV( random8(), 255, random8()); + } } // This function sets up a palette of black and white stripes, @@ -112,55 +112,55 @@ void SetupTotallyRandomPalette() // to set them up. void SetupBlackAndWhiteStripedPalette() { - // 'black out' all 16 palette entries... - fill_solid( currentPalette, 16, CRGB::Black); - // and set every fourth one to white. - currentPalette[0] = CRGB::White; - currentPalette[4] = CRGB::White; - currentPalette[8] = CRGB::White; - currentPalette[12] = CRGB::White; - + // 'black out' all 16 palette entries... + fill_solid( currentPalette, 16, CRGB::Black); + // and set every fourth one to white. + currentPalette[0] = CRGB::White; + currentPalette[4] = CRGB::White; + currentPalette[8] = CRGB::White; + currentPalette[12] = CRGB::White; + } // This function sets up a palette of purple and green stripes. void SetupPurpleAndGreenPalette() { - CRGB purple = CHSV( HUE_PURPLE, 255, 255); - CRGB green = CHSV( HUE_GREEN, 255, 255); - CRGB black = CRGB::Black; - - currentPalette = CRGBPalette16( - green, green, black, black, - purple, purple, black, black, - green, green, black, black, - purple, purple, black, black ); + CRGB purple = CHSV( HUE_PURPLE, 255, 255); + CRGB green = CHSV( HUE_GREEN, 255, 255); + CRGB black = CRGB::Black; + + currentPalette = CRGBPalette16( + green, green, black, black, + purple, purple, black, black, + green, green, black, black, + purple, purple, black, black ); } // This example shows how to set up a static color palette -// which is stored in PROGMEM (flash), which is almost always more +// which is stored in PROGMEM (flash), which is almost always more // plentiful than RAM. A static PROGMEM palette like this // takes up 64 bytes of flash. const TProgmemPalette16 myRedWhiteBluePalette_p PROGMEM = { - CRGB::Red, - CRGB::Gray, // 'white' is too bright compared to red and blue - CRGB::Blue, - CRGB::Black, - - CRGB::Red, - CRGB::Gray, - CRGB::Blue, - CRGB::Black, - - CRGB::Red, - CRGB::Red, - CRGB::Gray, - CRGB::Gray, - CRGB::Blue, - CRGB::Blue, - CRGB::Black, - CRGB::Black + CRGB::Red, + CRGB::Gray, // 'white' is too bright compared to red and blue + CRGB::Blue, + CRGB::Black, + + CRGB::Red, + CRGB::Gray, + CRGB::Blue, + CRGB::Black, + + CRGB::Red, + CRGB::Red, + CRGB::Gray, + CRGB::Gray, + CRGB::Blue, + CRGB::Blue, + CRGB::Black, + CRGB::Black }; @@ -171,7 +171,7 @@ const TProgmemPalette16 myRedWhiteBluePalette_p PROGMEM = // has 256 entries, each containing a specific 24-bit RGB color. You can then // index into the color palette using a simple 8-bit (one byte) value. // A 256-entry color palette takes up 768 bytes of RAM, which on Arduino -// is quite possibly "too many" bytes. +// is quite possibly "too many" bytes. // // FastLED does offer traditional 256-element palettes, for setups that // can afford the 768-byte cost in RAM. @@ -179,11 +179,10 @@ const TProgmemPalette16 myRedWhiteBluePalette_p PROGMEM = // However, FastLED also offers a compact alternative. FastLED offers // palettes that store 16 distinct entries, but can be accessed AS IF // they actually have 256 entries; this is accomplished by interpolating -// between the 16 explicit entries to create fifteen intermediate palette +// between the 16 explicit entries to create fifteen intermediate palette // entries between each pair. // // So for example, if you set the first two explicit entries of a compact // palette to Green (0,255,0) and Blue (0,0,255), and then retrieved // the first sixteen entries from the virtual palette (of 256), you'd get // Green, followed by a smooth gradient from green-to-blue, and then Blue. - diff --git a/examples/FirstLight/FirstLight.ino b/examples/FirstLight/FirstLight.ino index beec2986..ce89f640 100644 --- a/examples/FirstLight/FirstLight.ino +++ b/examples/FirstLight/FirstLight.ino @@ -36,6 +36,7 @@ void setup() { // FastLED.addLeds<WS2812, DATA_PIN, RGB>(leds, NUM_LEDS); // FastLED.addLeds<WS2812B, DATA_PIN, RGB>(leds, NUM_LEDS); // FastLED.addLeds<NEOPIXEL, DATA_PIN>(leds, NUM_LEDS); + // FastLED.addLeds<APA104, DATA_PIN>(leds, NUM_LEDS); // FastLED.addLeds<WS2811_400, DATA_PIN, RGB>(leds, NUM_LEDS); // FastLED.addLeds<GW6205, DATA_PIN, RGB>(leds, NUM_LEDS); // FastLED.addLeds<GW6205_400, DATA_PIN, RGB>(leds, NUM_LEDS); @@ -46,10 +47,15 @@ void setup() { // FastLED.addLeds<SM16716, RGB>(leds, NUM_LEDS); // FastLED.addLeds<LPD8806, RGB>(leds, NUM_LEDS); // FastLED.addLeds<P9813, RGB>(leds, NUM_LEDS); + // FastLED.addLeds<APA102, RGB>(leds, NUM_LEDS); + // FastLED.addLeds<DOTSTAR, RGB>(leds, NUM_LEDS); // FastLED.addLeds<WS2801, DATA_PIN, CLOCK_PIN, RGB>(leds, NUM_LEDS); // FastLED.addLeds<SM16716, DATA_PIN, CLOCK_PIN, RGB>(leds, NUM_LEDS); // FastLED.addLeds<LPD8806, DATA_PIN, CLOCK_PIN, RGB>(leds, NUM_LEDS); + // FastLED.addLeds<P9813, DATA_PIN, CLOCK_PIN, RGB>(leds, NUM_LEDS); + // FastLED.addLeds<APA102, DATA_PIN, CLOCK_PIN, RGB>(leds, NUM_LEDS); + // FastLED.addLeds<DOTSTAR, DATA_PIN, CLOCK_PIN, RGB>(leds, NUM_LEDS); } // This function runs over and over, and is where you do the magic to light diff --git a/fastled_delay.h b/fastled_delay.h new file mode 100644 index 00000000..015bc1a1 --- /dev/null +++ b/fastled_delay.h @@ -0,0 +1,119 @@ +#ifndef __INC_FL_DELAY_H +#define __INC_FL_DELAY_H + +FASTLED_NAMESPACE_BEGIN + +/// Class to ensure that a minimum amount of time has kicked since the last time run - and delay if not enough time has passed yet +/// this should make sure that chipsets that have +template<int WAIT> class CMinWait { + uint16_t mLastMicros; +public: + CMinWait() { mLastMicros = 0; } + + void wait() { + uint16_t diff; + do { + diff = (micros() & 0xFFFF) - mLastMicros; + } while(diff < WAIT); + } + + void mark() { mLastMicros = micros() & 0xFFFF; } +}; + + +//////////////////////////////////////////////////////////////////////////////////////////// +// +// Clock cycle counted delay loop +// +//////////////////////////////////////////////////////////////////////////////////////////// + +#if defined(__arm__) +# define NOP __asm__ __volatile__ ("nop\n"); +# define NOP2 __asm__ __volatile__ ("nop\n\tnop"); +#else +# define NOP __asm__ __volatile__ ("cp r0,r0\n"); +# define NOP2 __asm__ __volatile__ ("rjmp .+0"); +#endif + +// predeclaration to not upset the compiler +template<int CYCLES> inline void delaycycles(); + +// TODO: ARM version of _delaycycles_ + +// usable definition +#if defined(FASTLED_AVR) +// worker template - this will nop for LOOP * 3 + PAD cycles total +template<int LOOP, int PAD> inline void _delaycycles_AVR() { + delaycycles<PAD>(); + // the loop below is 3 cycles * LOOP. the LDI is one cycle, + // the DEC is 1 cycle, the BRNE is 2 cycles if looping back and + // 1 if not (the LDI balances out the BRNE being 1 cycle on exit) + __asm__ __volatile__ ( + " LDI R16, %0\n" + "L_%=: DEC R16\n" + " BRNE L_%=\n" + : /* no outputs */ + : "M" (LOOP) + : "r16" + ); +} + +template<int CYCLES> __attribute__((always_inline)) inline void delaycycles() { + _delaycycles_AVR<CYCLES / 3, CYCLES % 3>(); +} +#else +// template<int LOOP, int PAD> inline void _delaycycles_ARM() { +// delaycycles<PAD>(); +// // the loop below is 3 cycles * LOOP. the LDI is one cycle, +// // the DEC is 1 cycle, the BRNE is 2 cycles if looping back and +// // 1 if not (the LDI balances out the BRNE being 1 cycle on exit) +// __asm__ __volatile__ ( +// " mov.w r9, %0\n" +// "L_%=: subs.w r9, r9, #1\n" +// " bne.n L_%=\n" +// : /* no outputs */ +// : "M" (LOOP) +// : "r9" +// ); +// } + + +template<int CYCLES> __attribute__((always_inline)) inline void delaycycles() { + // _delaycycles_ARM<CYCLES / 3, CYCLES % 3>(); + NOP; delaycycles<CYCLES-1>(); +} +#endif + +// pre-instantiations for values small enough to not need the loop, as well as sanity holders +// for some negative values. +template<> __attribute__((always_inline)) inline void delaycycles<-6>() {} +template<> __attribute__((always_inline)) inline void delaycycles<-5>() {} +template<> __attribute__((always_inline)) inline void delaycycles<-4>() {} +template<> __attribute__((always_inline)) inline void delaycycles<-3>() {} +template<> __attribute__((always_inline)) inline void delaycycles<-2>() {} +template<> __attribute__((always_inline)) inline void delaycycles<-1>() {} +template<> __attribute__((always_inline)) inline void delaycycles<0>() {} +template<> __attribute__((always_inline)) inline void delaycycles<1>() {NOP;} +template<> __attribute__((always_inline)) inline void delaycycles<2>() {NOP2;} +template<> __attribute__((always_inline)) inline void delaycycles<3>() {NOP;NOP2;} +template<> __attribute__((always_inline)) inline void delaycycles<4>() {NOP2;NOP2;} +template<> __attribute__((always_inline)) inline void delaycycles<5>() {NOP2;NOP2;NOP;} + +// Some timing related macros/definitions + +// Macro to convert from nano-seconds to clocks and clocks to nano-seconds +// #define NS(_NS) (_NS / (1000 / (F_CPU / 1000000L))) +#if 1 || (F_CPU < 96000000) +#define NS(_NS) ( (_NS * (F_CPU / 1000000L))) / 1000 +#define CLKS_TO_MICROS(_CLKS) ((long)(_CLKS)) / (F_CPU / 1000000L) +#else +#define NS(_NS) ( (_NS * (F_CPU / 2000000L))) / 1000 +#define CLKS_TO_MICROS(_CLKS) ((long)(_CLKS)) / (F_CPU / 2000000L) +#endif + +// Macro for making sure there's enough time available +#define NO_TIME(A, B, C) (NS(A) < 3 || NS(B) < 3 || NS(C) < 6) + +FASTLED_NAMESPACE_END + +#endif @@ -41,19 +41,33 @@ class SPIOutput<SPI_DATA, SPI_CLOCK, SPI_SPEED> : public ARMHardwareSPIOutput<SP template<uint8_t SPI_SPEED> class SPIOutput<SPI2_DATA, SPI2_CLOCK, SPI_SPEED> : public ARMHardwareSPIOutput<SPI2_DATA, SPI2_CLOCK, SPI_SPEED, 0x4002C000> {}; -#endif - -#elif defined(FASTLED_TEENSYLC) && defined(ARM_HARDWARE_SPI) template<uint8_t SPI_SPEED> -class SPIOutput<SPI_DATA, SPI_CLOCK, SPI_SPEED> : public ARMHardwareSPIOutput<SPI_DATA, SPI_CLOCK, SPI_SPEED, 0x40076000> {}; - -#if defined(SPI2_DATA) +class SPIOutput<SPI_DATA, SPI2_CLOCK, SPI_SPEED> : public ARMHardwareSPIOutput<SPI_DATA, SPI2_CLOCK, SPI_SPEED, 0x4002C000> {}; template<uint8_t SPI_SPEED> -class SPIOutput<SPI2_DATA, SPI2_CLOCK, SPI_SPEED> : public ARMHardwareSPIOutput<SPI2_DATA, SPI2_CLOCK, SPI_SPEED, 0x40077000> {}; +class SPIOutput<SPI2_DATA, SPI_CLOCK, SPI_SPEED> : public ARMHardwareSPIOutput<SPI2_DATA, SPI_CLOCK, SPI_SPEED, 0x4002C000> {}; #endif +#elif defined(FASTLED_TEENSYLC) && defined(ARM_HARDWARE_SPI) + +#define DECLARE_SPI0(__DATA,__CLOCK) template<uint8_t SPI_SPEED>\ + class SPIOutput<__DATA, __CLOCK, SPI_SPEED> : public ARMHardwareSPIOutput<__DATA, __CLOCK, SPI_SPEED, 0x40076000> {}; + #define DECLARE_SPI1(__DATA,__CLOCK) template<uint8_t SPI_SPEED>\ + class SPIOutput<__DATA, __CLOCK, SPI_SPEED> : public ARMHardwareSPIOutput<__DATA, __CLOCK, SPI_SPEED, 0x40077000> {}; + +DECLARE_SPI0(7,13); +DECLARE_SPI0(8,13); +DECLARE_SPI0(11,13); +DECLARE_SPI0(12,13); +DECLARE_SPI0(7,14); +DECLARE_SPI0(8,14); +DECLARE_SPI0(11,14); +DECLARE_SPI0(12,14); +DECLARE_SPI1(0,20); +DECLARE_SPI1(1,20); +DECLARE_SPI1(21,20); + #elif defined(__SAM3X8E__) template<uint8_t SPI_SPEED> diff --git a/hsv2rgb.cpp b/hsv2rgb.cpp index 9806565d..f16472fc 100644 --- a/hsv2rgb.cpp +++ b/hsv2rgb.cpp @@ -538,7 +538,17 @@ CHSV rgb2hsv_approximate( const CRGB& rgb) // saturation is opposite of desaturation s = 255 - desat; - if( v != 255) s = (s * 256) / v; + if( v != 255) { + // this part could probably use refinement/rethinking, + // (but it doesn't overflow & wrap anymore) + uint16_t s16; + s16 = (s * 256) / v; + if( s16 < 256) { + s = s16; + } else { + s = 255; // clamp to prevent overflow + } + } // undo 'dimming' of saturation if( s != 255 ) s = 255 - sqrt16( (255-s) * 256); @@ -557,7 +567,7 @@ CHSV rgb2hsv_approximate( const CRGB& rgb) if( g == 0 ) { // if green is zero, we're in Purple/Pink-Red h = (HUE_PURPLE + HUE_PINK) / 2; - h += scale8( r - 128, FIXFRAC8(48,128)); + h += scale8( qsub8(r, 128), FIXFRAC8(48,128)); } else if ( (r - g) > g) { // if R-G > G then we're in Red-Orange h = HUE_RED; @@ -582,7 +592,7 @@ CHSV rgb2hsv_approximate( const CRGB& rgb) h += scale8( b, FIXFRAC8(32,85)); } else { h = HUE_AQUA; - h += scale8( b - 85, FIXFRAC8(8,42)); + h += scale8( qsub8(b, 85), FIXFRAC8(8,42)); } } @@ -592,7 +602,7 @@ CHSV rgb2hsv_approximate( const CRGB& rgb) if( r == 0) { // if red is zero, we're in Aqua/Blue-Blue h = HUE_AQUA + ((HUE_BLUE - HUE_AQUA) / 4); - h += scale8( b - 128, FIXFRAC8(24,128)); + h += scale8( qsub8(b, 128), FIXFRAC8(24,128)); } else if ( (b-r) > r) { // B-R > R, we're in Blue-Purple h = HUE_BLUE; @@ -600,7 +610,7 @@ CHSV rgb2hsv_approximate( const CRGB& rgb) } else { // B-R < R, we're in Purple-Pink h = HUE_PURPLE; - h += scale8( r - 85, FIXFRAC8(32,85)); + h += scale8( qsub8(r, 85), FIXFRAC8(32,85)); } } diff --git a/keywords.txt b/keywords.txt index e1aaebec..9cfe1d69 100644 --- a/keywords.txt +++ b/keywords.txt @@ -30,16 +30,16 @@ CRGBPalette256 KEYWORD1 # FastLED methods addLeds KEYWORD2 -setBrightness KEYWORD2 -getBrightness KEYWORD2 -show KEYWORD2 -clear KEYWORD2 -showColor KEYWORD2 -setTemperature KEYWORD2 -setCorrection KEYWORD2 -setDither KEYWORD2 -countFPS KEYWORD2 -getFPS KEYWORD2 +setBrightness KEYWORD2 +getBrightness KEYWORD2 +show KEYWORD2 +clear KEYWORD2 +showColor KEYWORD2 +setTemperature KEYWORD2 +setCorrection KEYWORD2 +setDither KEYWORD2 +countFPS KEYWORD2 +getFPS KEYWORD2 # Noise methods inoise16_raw KEYWORD2 @@ -289,28 +289,28 @@ CRGB::YellowGreen KEYWORD2 # Chipsets LPD8806 LITERAL1 -WS2801 LITERAL1 -WS2803 LITERAL1 -P9813 LITERAL1 -SM16716 LITERAL1 -APA102 LITERAL1 -DMXSERIAL LITERAL1 -DMXSIMPLE LITERAL1 -TM1829 LITERAL1 -TM1809 LITERAL1 -TM1804 LITERAL1 +WS2801 LITERAL1 +WS2803 LITERAL1 +P9813 LITERAL1 +SM16716 LITERAL1 +APA102 LITERAL1 +DMXSERIAL LITERAL1 +DMXSIMPLE LITERAL1 +TM1829 LITERAL1 +TM1809 LITERAL1 +TM1804 LITERAL1 TM1803 LITERAL1 -APA104 LITERAL1 -WS2811 LITERAL1 +APA104 LITERAL1 +WS2811 LITERAL1 WS2812 LITERAL1 WS2812B LITERAL1 WS2811_400 LITERAL1 NEOPIXEL LITERAL1 UCS1903 LITERAL1 -UCS1903B LITERAL1 -GW6205 LITERAL1 -GW6205B LITERAL1 -LPD1886 LITERAL1 +UCS1903B LITERAL1 +GW6205 LITERAL1 +GW6205B LITERAL1 +LPD1886 LITERAL1 # RGB orderings RGB LITERAL1 @@ -362,6 +362,6 @@ FORWARD_HUES LITERAL1 BACKWARD_HUES LITERAL1 SHORTEST_HUES LITERAL1 LONGEST_HUES LITERAL1 -BLEND LITERAL1 +LINEARBLEND LITERAL1 NOBLEND LITERAL1 diff --git a/led_sysdefs.h b/led_sysdefs.h index d182e183..d8723d6c 100644 --- a/led_sysdefs.h +++ b/led_sysdefs.h @@ -9,8 +9,8 @@ // Include k20/T3 headers #include "platforms/arm/k20/led_sysdefs_arm_k20.h" #elif defined(__MKL26Z64__) -// Include k26/T-LC headers -#include "platforms/arm/k26/led_sysdefs_arm_k26.h" +// Include kl26/T-LC headers +#include "platforms/arm/kl26/led_sysdefs_arm_kl26.h" #elif defined(__SAM3X8E__) // Include sam/due headers #include "platforms/arm/sam/led_sysdefs_arm_sam.h" @@ -29,7 +29,7 @@ #define FASTLED_USING_NAMESPACE #endif -// Arduino.h needed for convinience functions digitalPinToPort/BitMask/portOutputRegister and the pinMode methods. +// Arduino.h needed for convenience functions digitalPinToPort/BitMask/portOutputRegister and the pinMode methods. #ifdef ARDUINO #include<Arduino.h> #endif diff --git a/platforms.h b/platforms.h index 112fa7d6..b64279de 100644 --- a/platforms.h +++ b/platforms.h @@ -9,8 +9,8 @@ // Include k20/T3 headers #include "platforms/arm/k20/fastled_arm_k20.h" #elif defined(__MKL26Z64__) -// Include k26/T-LC headers -#include "platforms/arm/k26/fastled_arm_k26.h" +// Include kl26/T-LC headers +#include "platforms/arm/kl26/fastled_arm_kl26.h" #elif defined(__SAM3X8E__) // Include sam/due headers #include "platforms/arm/sam/fastled_arm_sam.h" diff --git a/platforms/arm/k20/fastspi_arm_k20.h b/platforms/arm/k20/fastspi_arm_k20.h index 311586be..9bf383ff 100644 --- a/platforms/arm/k20/fastspi_arm_k20.h +++ b/platforms/arm/k20/fastspi_arm_k20.h @@ -93,30 +93,34 @@ class ARMHardwareSPIOutput { // Borrowed from the teensy3 SPSR emulation code static inline void enable_pins(void) __attribute__((always_inline)) { //serial_print("enable_pins\n"); - if(_DATA_PIN == 11) { - CORE_PIN11_CONFIG = PORT_PCR_DSE | PORT_PCR_MUX(2); - CORE_PIN12_CONFIG = PORT_PCR_MUX(2); - CORE_PIN13_CONFIG = PORT_PCR_DSE | PORT_PCR_MUX(2); - } else if(_DATA_PIN == 7) { - CORE_PIN7_CONFIG = PORT_PCR_DSE | PORT_PCR_MUX(2); - CORE_PIN8_CONFIG = PORT_PCR_DSE | PORT_PCR_MUX(2); - CORE_PIN14_CONFIG = PORT_PCR_DSE | PORT_PCR_MUX(2); + switch(_DATA_PIN) { + case 7: CORE_PIN7_CONFIG = PORT_PCR_DSE | PORT_PCR_MUX(2); break; + // case 8: CORE_PIN8_CONFIG = PORT_PCR_DSE | PORT_PCR_MUX(2); break; + case 11: CORE_PIN11_CONFIG = PORT_PCR_DSE | PORT_PCR_MUX(2); break; + // case 12: CORE_PIN12_CONFIG = PORT_PCR_DSE | PORT_PCR_MUX(2); break; + } + + switch(_CLOCK_PIN) { + case 13: CORE_PIN13_CONFIG = PORT_PCR_DSE | PORT_PCR_MUX(2); break; + case 14: CORE_PIN14_CONFIG = PORT_PCR_DSE | PORT_PCR_MUX(2); break; } } // Borrowed from the teensy3 SPSR emulation code static inline void disable_pins(void) __attribute__((always_inline)) { - //serial_print("disable_pins\n"); - if(_DATA_PIN == 11) { - CORE_PIN11_CONFIG = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(0); - CORE_PIN12_CONFIG = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(0); - CORE_PIN13_CONFIG = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(0); - } else if(_DATA_PIN == 7) { - CORE_PIN7_CONFIG = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(0); - CORE_PIN8_CONFIG = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(0); - CORE_PIN14_CONFIG = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(0); + switch(_DATA_PIN) { + case 7: CORE_PIN7_CONFIG = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1); break; + // case 8: CORE_PIN8_CONFIG = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1); break; + case 11: CORE_PIN11_CONFIG = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1); break; + // case 12: CORE_PIN12_CONFIG = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1); break; } -} + + switch(_CLOCK_PIN) { + case 13: CORE_PIN13_CONFIG = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1); break; + case 14: CORE_PIN14_CONFIG = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1); break; + } + } + public: ARMHardwareSPIOutput() { m_pSelect = NULL; } ARMHardwareSPIOutput(Selectable *pSelect) { m_pSelect = pSelect; } diff --git a/platforms/arm/k20/led_sysdefs_arm_k20.h b/platforms/arm/k20/led_sysdefs_arm_k20.h index a5a15429..b5e1984f 100644 --- a/platforms/arm/k20/led_sysdefs_arm_k20.h +++ b/platforms/arm/k20/led_sysdefs_arm_k20.h @@ -25,7 +25,7 @@ #include <avr/io.h> #include <avr/interrupt.h> // for cli/se definitions -// Define the rgister types +// Define the register types #if defined(ARDUINO) // && ARDUINO < 150 typedef volatile uint8_t RoReg; /**< Read only 8-bit register (volatile const unsigned int) */ typedef volatile uint8_t RwReg; /**< Read-Write 8-bit register (volatile unsigned int) */ diff --git a/platforms/arm/k20/octows2811_controller.h b/platforms/arm/k20/octows2811_controller.h index b5d53198..ed748919 100644 --- a/platforms/arm/k20/octows2811_controller.h +++ b/platforms/arm/k20/octows2811_controller.h @@ -7,7 +7,7 @@ FASTLED_NAMESPACE_BEGIN -template<EOrder RGB_ORDER = GRB> +template<EOrder RGB_ORDER = GRB, boolean SLOW=false> class COctoWS2811Controller : public CLEDController { OctoWS2811 *pocto; uint8_t *drawbuffer,*framebuffer; @@ -16,14 +16,15 @@ class COctoWS2811Controller : public CLEDController { if(pocto == NULL) { drawbuffer = (uint8_t*)malloc(nLeds * 8 * 3); framebuffer = (uint8_t*)malloc(nLeds * 8 * 3); - switch(RGB_ORDER) { - case RGB: pocto = new OctoWS2811(nLeds, framebuffer, drawbuffer, WS2811_RGB); break; - case RBG: pocto = new OctoWS2811(nLeds, framebuffer, drawbuffer, WS2811_RBG); break; - case GBR: pocto = new OctoWS2811(nLeds, framebuffer, drawbuffer, WS2811_GBR); break; - case GRB: - default: - pocto = new OctoWS2811(nLeds, framebuffer,drawbuffer, WS2811_GRB); break; + + // byte ordering is handled in show by the pixel controller + int config = WS2811_RGB; + if(SLOW) { + config |= WS2811_400kHz; } + + pocto = new OctoWS2811(nLeds, framebuffer, drawbuffer, config); + pocto->begin(); } } diff --git a/platforms/arm/k26/fastled_arm_k26.h b/platforms/arm/k26/fastled_arm_k26.h deleted file mode 100644 index 382531bf..00000000 --- a/platforms/arm/k26/fastled_arm_k26.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef __INC_FASTLED_ARM_K26_H -#define __INC_FASTLED_ARM_K26_H - -// Include the k20 headers -#include "fastled_delay.h" -#include "fastpin_arm_k26.h" -#include "fastspi_arm_k26.h" -#include "clockless_arm_k26.h" - -#endif diff --git a/platforms/arm/k26/clockless_arm_k26.h b/platforms/arm/kl26/clockless_arm_kl26.h index 1ebb7cd8..6525309e 100644 --- a/platforms/arm/k26/clockless_arm_k26.h +++ b/platforms/arm/kl26/clockless_arm_kl26.h @@ -1,5 +1,5 @@ -#ifndef __INC_CLOCKLESS_ARM_K26 -#define __INC_CLOCKLESS_ARM_K26 +#ifndef __INC_CLOCKLESS_ARM_KL26 +#define __INC_CLOCKLESS_ARM_KL26 #define TADJUST 0 #define TOTAL ( (T1+TADJUST) + (T2+TADJUST) + (T3+TADJUST) ) diff --git a/platforms/arm/kl26/fastled_arm_kl26.h b/platforms/arm/kl26/fastled_arm_kl26.h new file mode 100644 index 00000000..9a93caa5 --- /dev/null +++ b/platforms/arm/kl26/fastled_arm_kl26.h @@ -0,0 +1,10 @@ +#ifndef __INC_FASTLED_ARM_KL26_H +#define __INC_FASTLED_ARM_KL26_H + +// Include the k20 headers +#include "fastled_delay.h" +#include "fastpin_arm_kl26.h" +#include "fastspi_arm_kl26.h" +#include "clockless_arm_kl26.h" + +#endif diff --git a/platforms/arm/k26/fastpin_arm_k26.h b/platforms/arm/kl26/fastpin_arm_kl26.h index 487a5eb1..4c30cd78 100644 --- a/platforms/arm/k26/fastpin_arm_k26.h +++ b/platforms/arm/kl26/fastpin_arm_kl26.h @@ -1,5 +1,5 @@ -#ifndef __FASTPIN_ARM_K20_H -#define __FASTPIN_ARM_K20_H +#ifndef __FASTPIN_ARM_KL26_H +#define __FASTPIN_ARM_KL26_H FASTLED_NAMESPACE_BEGIN @@ -11,7 +11,7 @@ FASTLED_NAMESPACE_BEGIN #else -/// Template definition for teensy 3.0 style ARM pins, providing direct access to the various GPIO registers. Note that this +/// Template definition for teensy LC style ARM pins, providing direct access to the various GPIO registers. Note that this /// uses the full port GPIO registers. In theory, in some way, bit-band register access -should- be faster, however I have found /// that something about the way gcc does register allocation results in the bit-band code being slower. It will need more fine tuning. /// The registers are data output, set output, clear output, toggle output, input, and direction @@ -43,37 +43,7 @@ public: inline static port_t mask() __attribute__ ((always_inline)) { return _MASK; } }; -#if 0 -/// Template definition for teensy 3.0 style ARM pins using bit banding, providing direct access to the various GPIO registers. GCC -/// does a poor job of optimizing around these accesses so they are not being used just yet. -template<uint8_t PIN, int _BIT, typename _PDOR, typename _PSOR, typename _PCOR, typename _PTOR, typename _PDIR, typename _PDDR> class _ARMPIN_BITBAND { -public: - typedef volatile uint32_t * port_ptr_t; - typedef uint32_t port_t; - - 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)) { *_PDOR::template rx<_BIT>() = 1; } - inline static void lo() __attribute__ ((always_inline)) { *_PDOR::template rx<_BIT>() = 0; } - inline static void set(register port_t val) __attribute__ ((always_inline)) { *_PDOR::template rx<_BIT>() = val; } - - inline static void strobe() __attribute__ ((always_inline)) { toggle(); toggle(); } - - inline static void toggle() __attribute__ ((always_inline)) { *_PTOR::template rx<_BIT>() = 1; } - - 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)) { *_PDOR::template rx<_BIT>() = val; } - - inline static port_t hival() __attribute__ ((always_inline)) { return 1; } - inline static port_t loval() __attribute__ ((always_inline)) { return 0; } - inline static port_ptr_t port() __attribute__ ((always_inline)) { return _PDOR::template rx<_BIT>(); } - inline static port_t mask() __attribute__ ((always_inline)) { return 1; } -}; -#endif - -// Macros for k20 pin access/definition +// Macros for kl26 pin access/definition #define GPIO_BITBAND_ADDR(reg, bit) (((uint32_t)&(reg) - 0x40000000) * 32 + (bit) * 4 + 0x42000000) #define GPIO_BITBAND_PTR(reg, bit) ((uint32_t *)GPIO_BITBAND_ADDR((reg), (bit))) diff --git a/platforms/arm/k26/fastspi_arm_k26.h b/platforms/arm/kl26/fastspi_arm_kl26.h index ce28cda8..869b6054 100644 --- a/platforms/arm/k26/fastspi_arm_k26.h +++ b/platforms/arm/kl26/fastspi_arm_kl26.h @@ -1,5 +1,5 @@ -#ifndef __INC_FASTSPI_ARM_K26_H -#define __INC_FASTSPI_ARM_K26_h +#ifndef __INC_FASTSPI_ARM_KL26_H +#define __INC_FASTSPI_ARM_KL26_h FASTLED_NAMESPACE_BEGIN @@ -87,19 +87,39 @@ class ARMHardwareSPIOutput { Selectable *m_pSelect; static inline void enable_pins(void) __attribute__((always_inline)) { - if(_DATA_PIN == 11) CORE_PIN11_CONFIG = PORT_PCR_MUX(2); // MOSI = 11 (PTC6) - if(_DATA_PIN == 0) CORE_PIN0_CONFIG = PORT_PCR_MUX(2); - // CORE_PIN12_CONFIG = PORT_PCR_MUX(2); // MISO = 12 (PTC7) - if(_CLOCK_PIN == 13) CORE_PIN13_CONFIG = PORT_PCR_MUX(2); // SCK = 13 (PTC5) - if(_CLOCK_PIN == 20) CORE_PIN20_CONFIG = PORT_PCR_MUX(2); + switch(_DATA_PIN) { + case 0: CORE_PIN0_CONFIG = PORT_PCR_MUX(2); break; + case 1: CORE_PIN1_CONFIG = PORT_PCR_MUX(5); break; + case 7: CORE_PIN7_CONFIG = PORT_PCR_MUX(2); break; + case 8: CORE_PIN8_CONFIG = PORT_PCR_MUX(5); break; + case 11: CORE_PIN11_CONFIG = PORT_PCR_MUX(2); break; + case 12: CORE_PIN12_CONFIG = PORT_PCR_MUX(5); break; + case 21: CORE_PIN21_CONFIG = PORT_PCR_MUX(2); break; + } + + switch(_CLOCK_PIN) { + case 13: CORE_PIN13_CONFIG = PORT_PCR_MUX(2); break; + case 14: CORE_PIN14_CONFIG = PORT_PCR_MUX(2); break; + case 20: CORE_PIN20_CONFIG = PORT_PCR_MUX(2); break; + } } static inline void disable_pins(void) __attribute((always_inline)) { - if(_DATA_PIN == 11) CORE_PIN11_CONFIG = PORT_PCR_SRE | PORT_PCR_MUX(1); - if(_DATA_PIN == 0) CORE_PIN0_CONFIG = PORT_PCR_SRE | PORT_PCR_MUX(1); - // CORE_PIN12_CONFIG = PORT_PCR_SRE | PORT_PCR_MUX(1); - if(_CLOCK_PIN == 13) CORE_PIN13_CONFIG = PORT_PCR_SRE | PORT_PCR_MUX(1); - if(_CLOCK_PIN == 20) CORE_PIN20_CONFIG = PORT_PCR_SRE | PORT_PCR_MUX(1); + switch(_DATA_PIN) { + case 0: CORE_PIN0_CONFIG = PORT_PCR_SRE | PORT_PCR_MUX(1); break; + case 1: CORE_PIN1_CONFIG = PORT_PCR_SRE | PORT_PCR_MUX(1); break; + case 7: CORE_PIN7_CONFIG = PORT_PCR_SRE | PORT_PCR_MUX(1); break; + case 8: CORE_PIN8_CONFIG = PORT_PCR_SRE | PORT_PCR_MUX(1); break; + case 11: CORE_PIN11_CONFIG = PORT_PCR_SRE | PORT_PCR_MUX(1); break; + case 12: CORE_PIN12_CONFIG = PORT_PCR_SRE | PORT_PCR_MUX(1); break; + case 21: CORE_PIN21_CONFIG = PORT_PCR_SRE | PORT_PCR_MUX(1); break; + } + + switch(_CLOCK_PIN) { + case 13: CORE_PIN13_CONFIG = PORT_PCR_SRE | PORT_PCR_MUX(1); break; + case 14: CORE_PIN14_CONFIG = PORT_PCR_SRE | PORT_PCR_MUX(1); break; + case 20: CORE_PIN20_CONFIG = PORT_PCR_SRE | PORT_PCR_MUX(1); break; + } } void setSPIRate() { diff --git a/platforms/arm/k26/led_sysdefs_arm_k26.h b/platforms/arm/kl26/led_sysdefs_arm_kl26.h index 10bc271e..ff39c8d0 100644 --- a/platforms/arm/k26/led_sysdefs_arm_k26.h +++ b/platforms/arm/kl26/led_sysdefs_arm_kl26.h @@ -1,5 +1,5 @@ -#ifndef __INC_LED_SYSDEFS_ARM_K26_H -#define __INC_LED_SYSDEFS_ARM_K26_H +#ifndef __INC_LED_SYSDEFS_ARM_KL26_H +#define __INC_LED_SYSDEFS_ARM_KL26_H #define FASTLED_TEENSYLC #define FASTLED_ARM @@ -25,7 +25,7 @@ #include <avr/io.h> #include <avr/interrupt.h> // for cli/se definitions -// Define the rgister types +// Define the register types #if defined(ARDUINO) // && ARDUINO < 150 typedef volatile uint8_t RoReg; /**< Read only 8-bit register (volatile const unsigned int) */ typedef volatile uint8_t RwReg; /**< Read-Write 8-bit register (volatile unsigned int) */ diff --git a/platforms/arm/sam/led_sysdefs_arm_sam.h b/platforms/arm/sam/led_sysdefs_arm_sam.h index 20bf4600..a4828648 100644 --- a/platforms/arm/sam/led_sysdefs_arm_sam.h +++ b/platforms/arm/sam/led_sysdefs_arm_sam.h @@ -31,7 +31,7 @@ #define FASTLED_ACCURATE_CLOCK #endif -// reuseing/abusing cli/sei defs for due +// reusing/abusing cli/sei defs for due #define cli() __disable_irq(); __disable_fault_irq(); #define sei() __enable_irq(); __enable_fault_irq(); diff --git a/platforms/arm/stm32/led_sysdefs_arm_stm32.h b/platforms/arm/stm32/led_sysdefs_arm_stm32.h index cb6fb989..e51b3166 100644 --- a/platforms/arm/stm32/led_sysdefs_arm_stm32.h +++ b/platforms/arm/stm32/led_sysdefs_arm_stm32.h @@ -22,7 +22,7 @@ #define FASTLED_ACCURATE_CLOCK #endif -// reuseing/abusing cli/sei defs for due +// reusing/abusing cli/sei defs for due #define cli() __disable_irq(); __disable_fault_irq(); #define sei() __enable_irq(); __enable_fault_irq(); diff --git a/platforms/avr/clockless_trinket.h b/platforms/avr/clockless_trinket.h index 9d29b81d..0e516355 100644 --- a/platforms/avr/clockless_trinket.h +++ b/platforms/avr/clockless_trinket.h @@ -21,7 +21,7 @@ FASTLED_NAMESPACE_BEGIN // Variations on the functions in delay.h - w/a loop var passed in to preserve registers across calls by the optimizer/compiler template<int CYCLES> inline void _dc(register uint8_t & loopvar); -template<int _LOOP, int PAD> inline void _dc_AVR(register uint8_t & loopvar) { +template<int _LOOP, int PAD> __attribute__((always_inline)) inline void _dc_AVR(register uint8_t & loopvar) { _dc<PAD>(loopvar); // The convolution in here is to ensure that the state of the carry flag coming into the delay loop is preserved asm __volatile__ ( "BRCS L_PC%=\n\t" diff --git a/platforms/avr/fastpin_avr.h b/platforms/avr/fastpin_avr.h index faeca65c..cc0699fa 100644 --- a/platforms/avr/fastpin_avr.h +++ b/platforms/avr/fastpin_avr.h @@ -87,7 +87,7 @@ _DEFPIN_AVR( 20, 0x80, D); // #define SPI_CLOCK 1 // #define AVR_HARDWARE_SPI 1 -#elif defined(__AVR_ATmega328P__) || defined(__AVR_ATmega168__) +#elif defined(__AVR_ATmega328P__) || defined(__AVR_ATmega168__) || defined(__AVR_ATmega168P__) || defined(__AVR_ATmega8__) // Accelerated port definitions for arduino avrs _IO(D); _IO(B); _IO(C); diff --git a/platforms/avr/fastspi_avr.h b/platforms/avr/fastspi_avr.h index c0ebc789..2ed5bb15 100644 --- a/platforms/avr/fastspi_avr.h +++ b/platforms/avr/fastspi_avr.h @@ -308,6 +308,7 @@ public: pixels.stepDithering(); } D::postBlock(len); + waitFully(); release(); } }; @@ -488,6 +489,7 @@ public: pixels.stepDithering(); } D::postBlock(len); + waitFully(); release(); } }; diff --git a/platforms/avr/led_sysdefs_avr.h b/platforms/avr/led_sysdefs_avr.h index ebba81aa..ed41fcb5 100644 --- a/platforms/avr/led_sysdefs_avr.h +++ b/platforms/avr/led_sysdefs_avr.h @@ -10,7 +10,7 @@ #include <avr/io.h> #include <avr/interrupt.h> // for cli/se definitions -// Define the rgister types +// Define the register types #if defined(ARDUINO) // && ARDUINO < 150 typedef volatile uint8_t RoReg; /**< Read only 8-bit register (volatile const unsigned int) */ typedef volatile uint8_t RwReg; /**< Read-Write 8-bit register (volatile unsigned int) */ @@ -27,12 +27,14 @@ typedef volatile uint8_t RwReg; /**< Read-Write 8-bit register (volatile u #define FASTLED_ACCURATE_CLOCK #endif -# if defined(CORE_TEENSY) +extern "C" { +# if defined(CORE_TEENSY) || defined(TEENSYDUINO) extern volatile unsigned long timer0_millis_count; # define MS_COUNTER timer0_millis_count # else extern volatile unsigned long timer0_millis; # define MS_COUNTER timer0_millis # endif +}; #endif diff --git a/preview_changes.txt b/preview_changes.txt index 36162ea8..423e761a 100644 --- a/preview_changes.txt +++ b/preview_changes.txt @@ -7,7 +7,7 @@ FastLED 3.1 preview changes: * Added DOTSTAR definition for adafruit dotstar pixels (aka APA102) * 8-way parallel output on teensy 3, 3.1 (portc,portd), due/digix (porta, portb, portd) * 12-way parallel output on teensy 3, 3.1 (portc) -* 16-way parallel output on teensy 3, 3.1 (portd & portd paired) +* 16-way parallel output on teensy 3, 3.1 (portc & portd paired) * refresh rate limiting * interrupt friendly code on teensy 3/3.1 * -interrupt friendly code on AVR- <-- disabled for now |