diff options
-rw-r--r-- | FastLED.h | 29 | ||||
-rw-r--r-- | chipsets.h | 1 | ||||
-rw-r--r-- | clockless.h | 28 | ||||
-rw-r--r-- | colorutils.cpp | 115 | ||||
-rw-r--r-- | fastled_config.h | 12 | ||||
-rw-r--r-- | fastpin.h | 58 | ||||
-rw-r--r-- | fastspi.h | 44 | ||||
-rw-r--r-- | fastspi_types.h | 37 | ||||
-rw-r--r-- | hsv2rgb.cpp | 85 | ||||
-rw-r--r-- | led_sysdefs.h | 82 | ||||
-rw-r--r-- | lib8tion.h | 18 | ||||
-rw-r--r-- | platforms.h | 15 | ||||
-rw-r--r-- | platforms/arm/k20/clockless_arm_k20.h (renamed from clockless_arm_k20.h) | 0 | ||||
-rw-r--r-- | platforms/arm/k20/clockless_block_arm_k20.h (renamed from clockless_block_arm_k20.h) | 0 | ||||
-rw-r--r-- | platforms/arm/k20/fastled_arm_k20.h | 14 | ||||
-rw-r--r-- | platforms/arm/k20/fastpin_arm_k20.h (renamed from fastpin_arm_k20.h) | 13 | ||||
-rw-r--r-- | platforms/arm/k20/fastspi_arm_k20.h (renamed from fastspi_arm_k20.h) | 0 | ||||
-rw-r--r-- | platforms/arm/k20/led_sysdefs_arm_k20.h | 26 | ||||
-rw-r--r-- | platforms/arm/k20/octows2811_controller.h (renamed from octows2811_controller.h) | 0 | ||||
-rw-r--r-- | platforms/arm/k20/smartmatrix_t3.h (renamed from smartmatrix_t3.h) | 0 | ||||
-rw-r--r-- | platforms/arm/sam/clockless_arm_sam.h (renamed from clockless_arm_sam.h) | 0 | ||||
-rw-r--r-- | platforms/arm/sam/clockless_block_arm_sam.h (renamed from clockless_block_arm_sam.h) | 5 | ||||
-rw-r--r-- | platforms/arm/sam/fastled_arm_sam.h | 11 | ||||
-rw-r--r-- | platforms/arm/sam/fastpin_arm_sam.h (renamed from fastpin_arm_sam.h) | 29 | ||||
-rw-r--r-- | platforms/arm/sam/fastspi_arm_sam.h (renamed from fastspi_arm_sam.h) | 0 | ||||
-rw-r--r-- | platforms/arm/sam/led_sysdefs_arm_sam.h | 30 | ||||
-rw-r--r-- | platforms/avr/clockless_trinket.h (renamed from clockless_trinket.h) | 1 | ||||
-rw-r--r-- | platforms/avr/fastled_avr.h | 9 | ||||
-rw-r--r-- | platforms/avr/fastpin_avr.h (renamed from fastpin_avr.h) | 111 | ||||
-rw-r--r-- | platforms/avr/fastspi_avr.h (renamed from fastspi_avr.h) | 0 | ||||
-rw-r--r-- | platforms/avr/led_sysdefs_avr.h | 21 | ||||
-rw-r--r-- | preview_changes.txt | 2 | ||||
-rw-r--r-- | wiring.cpp | 3 |
33 files changed, 430 insertions, 369 deletions
@@ -26,21 +26,29 @@ #include<DMXSerial.h> #endif +#include <stdint.h> + +#include "fastled_config.h" +#include "led_sysdefs.h" + +#include "bitswap.h" #include "controller.h" #include "fastpin.h" -#include "fastspi.h" -#include "bitswap.h" -#include "clockless.h" +#include "fastspi_types.h" +#include "./dmx.h" + +#include "platforms.h" + #include "lib8tion.h" #include "hsv2rgb.h" #include "colorutils.h" #include "colorpalettes.h" -#include "chipsets.h" -#include "./dmx.h" -#include "smartmatrix_t3.h" + #include "noise.h" #include "power_mgt.h" -#include "octows2811_controller.h" + +#include "fastspi.h" +#include "chipsets.h" enum ESPIChipsets { LPD8806, @@ -325,4 +333,11 @@ void delayMicroseconds(unsigned int us); extern CFastLED FastLED; +// Warnings for undefined things +#ifndef HAS_HARDWARE_PIN_SUPPORT +#warning "No pin/port mappings found, pin access will be slightly slower. See fastpin.h for info." +#define NO_HARDWARE_PIN_SUPPORT +#endif + + #endif @@ -2,7 +2,6 @@ #define __INC_CHIPSETS_H #include "pixeltypes.h" -#include "clockless.h" ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // diff --git a/clockless.h b/clockless.h deleted file mode 100644 index 896cf046..00000000 --- a/clockless.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef __INC_CLOCKLESS_H -#define __INC_CLOCKLESS_H - -#include "controller.h" -#include "lib8tion.h" -#include "led_sysdefs.h" -#include "delay.h" - -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// -// Base template for clockless controllers. These controllers have 3 control points in their cycle for each bit. The first point -// is where the line is raised hi. The second pointsnt is where the line is dropped low for a zero. The third point is where the -// line is dropped low for a one. T1, T2, and T3 correspond to the timings for those three in clock cycles. -// -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -// Convinience macros to wrap around the toggling of hi vs. lo -#define SET_LO FLIP ? FastPin<DATA_PIN>::fastset(port, hi) : FastPin<DATA_PIN>::fastset(port, lo); -#define SET_HI FLIP ? FastPin<DATA_PIN>::fastset(port, lo) : FastPin<DATA_PIN>::fastset(port, hi); - -// #include "clockless_avr.h" -#include "clockless_trinket.h" -#include "clockless_arm_k20.h" -#include "clockless_arm_sam.h" -#include "clockless_block_arm_sam.h" -#include "clockless_block_arm_k20.h" - -#endif diff --git a/colorutils.cpp b/colorutils.cpp index 995db69e..9bb64b7e 100644 --- a/colorutils.cpp +++ b/colorutils.cpp @@ -2,8 +2,7 @@ #include <stdint.h> -#include "hsv2rgb.h" -#include "colorutils.h" +#include "FastLED.h" @@ -73,22 +72,22 @@ void fill_gradient_RGB( CRGB* leds, endcolor = startcolor; endpos = startpos; } - + saccum87 rdistance87; saccum87 gdistance87; saccum87 bdistance87; - + rdistance87 = (endcolor.r - startcolor.r) << 7; gdistance87 = (endcolor.g - startcolor.g) << 7; bdistance87 = (endcolor.b - startcolor.b) << 7; - + uint16_t pixeldistance = endpos - startpos; int16_t divisor = pixeldistance ? pixeldistance : 1; saccum87 rdelta87 = rdistance87 / divisor; saccum87 gdelta87 = gdistance87 / divisor; saccum87 bdelta87 = bdistance87 / divisor; - + rdelta87 *= 2; gdelta87 *= 2; bdelta87 *= 2; @@ -213,23 +212,23 @@ CRGB& nblend( CRGB& existing, const CRGB& overlay, fract8 amountOfOverlay ) if( amountOfOverlay == 0) { return existing; } - + if( amountOfOverlay == 255) { existing = overlay; return existing; } - + fract8 amountOfKeep = 256 - amountOfOverlay; - + existing.red = scale8_LEAVING_R1_DIRTY( existing.red, amountOfKeep) + scale8_LEAVING_R1_DIRTY( overlay.red, amountOfOverlay); existing.green = scale8_LEAVING_R1_DIRTY( existing.green, amountOfKeep) + scale8_LEAVING_R1_DIRTY( overlay.green, amountOfOverlay); existing.blue = scale8_LEAVING_R1_DIRTY( existing.blue, amountOfKeep) + scale8_LEAVING_R1_DIRTY( overlay.blue, amountOfOverlay); - + cleanup_R1(); - + return existing; } @@ -266,30 +265,30 @@ CHSV& nblend( CHSV& existing, const CHSV& overlay, fract8 amountOfOverlay, TGrad if( amountOfOverlay == 0) { return existing; } - + if( amountOfOverlay == 255) { existing = overlay; return existing; } - + fract8 amountOfKeep = 256 - amountOfOverlay; - + uint8_t huedelta8 = overlay.hue - existing.hue; - + if( directionCode == SHORTEST_HUES ) { directionCode = FORWARD_HUES; if( huedelta8 > 127) { directionCode = BACKWARD_HUES; } } - + if( directionCode == LONGEST_HUES ) { directionCode = FORWARD_HUES; if( huedelta8 < 128) { directionCode = BACKWARD_HUES; } } - + if( directionCode == FORWARD_HUES) { existing.hue = existing.hue + scale8( huedelta8, amountOfOverlay); } @@ -298,14 +297,14 @@ CHSV& nblend( CHSV& existing, const CHSV& overlay, fract8 amountOfOverlay, TGrad huedelta8 = -huedelta8; existing.hue = existing.hue - scale8( huedelta8, amountOfOverlay); } - + existing.sat = scale8_LEAVING_R1_DIRTY( existing.sat, amountOfKeep) + scale8_LEAVING_R1_DIRTY( overlay.sat, amountOfOverlay); existing.val = scale8_LEAVING_R1_DIRTY( existing.val, amountOfKeep) + scale8_LEAVING_R1_DIRTY( overlay.val, amountOfOverlay); - + cleanup_R1(); - + return existing; } @@ -351,37 +350,37 @@ CHSV* blend( const CHSV* src1, const CHSV* src2, CHSV* dest, uint16_t count, fra CRGB HeatColor( uint8_t temperature) { CRGB heatcolor; - + // Scale 'heat' down from 0-255 to 0-191, // which can then be easily divided into three // equal 'thirds' of 64 units each. uint8_t t192 = scale8_video( temperature, 192); - + // calculate a value that ramps up from // zero to 255 in each 'third' of the scale. uint8_t heatramp = t192 & 0x3F; // 0..63 heatramp <<= 2; // scale up to 0..252 - + // now figure out which third of the spectrum we're in: if( t192 & 0x80) { // we're in the hottest third heatcolor.r = 255; // full red heatcolor.g = 255; // full green heatcolor.b = heatramp; // ramp up blue - + } else if( t192 & 0x40 ) { // we're in the middle third heatcolor.r = 255; // full red heatcolor.g = heatramp; // ramp up green heatcolor.b = 0; // no blue - + } else { // we're in the coolest third heatcolor.r = heatramp; // ramp up red heatcolor.g = 0; // no green heatcolor.b = 0; // no blue } - + return heatcolor; } @@ -391,33 +390,33 @@ CRGB ColorFromPalette( const CRGBPalette16& pal, uint8_t index, uint8_t brightne { uint8_t hi4 = index >> 4; uint8_t lo4 = index & 0x0F; - + // CRGB rgb1 = pal[ hi4]; const CRGB* entry = &(pal[0]) + hi4; uint8_t red1 = entry->red; uint8_t green1 = entry->green; uint8_t blue1 = entry->blue; - + uint8_t blend = lo4 && (blendType != NOBLEND); - + if( blend ) { - + if( hi4 == 15 ) { entry = &(pal[0]); } else { entry++; } - + uint8_t f2 = lo4 << 4; uint8_t f1 = 256 - f2; - + // rgb1.nscale8(f1); red1 = scale8_LEAVING_R1_DIRTY( red1, f1); green1 = scale8_LEAVING_R1_DIRTY( green1, f1); blue1 = scale8_LEAVING_R1_DIRTY( blue1, f1); - + // cleanup_R1(); - + // CRGB rgb2 = pal[ hi4]; // rgb2.nscale8(f2); uint8_t red2 = entry->red; @@ -426,21 +425,21 @@ CRGB ColorFromPalette( const CRGBPalette16& pal, uint8_t index, uint8_t brightne red2 = scale8_LEAVING_R1_DIRTY( red2, f2); green2 = scale8_LEAVING_R1_DIRTY( green2, f2); blue2 = scale8_LEAVING_R1_DIRTY( blue2, f2); - + cleanup_R1(); - + // These sums can't overflow, so no qadd8 needed. red1 += red2; green1 += green2; blue1 += blue2; } - + if( brightness != 255) { nscale8x3_video( red1, green1, blue1, brightness); } - - return CRGB( red1, green1, blue1); + + return CRGB( red1, green1, blue1); } @@ -451,11 +450,11 @@ CRGB ColorFromPalette( const CRGBPalette256& pal, uint8_t index, uint8_t brightn uint8_t red = entry->red; uint8_t green = entry->green; uint8_t blue = entry->blue; - + if( brightness != 255) { nscale8x3_video( red, green, blue, brightness); } - + return CRGB( red, green, blue); } @@ -464,27 +463,27 @@ CHSV ColorFromPalette( const struct CHSVPalette16& pal, uint8_t index, uint8_t b { uint8_t hi4 = index >> 4; uint8_t lo4 = index & 0x0F; - + // CRGB rgb1 = pal[ hi4]; const CHSV* entry = &(pal[0]) + hi4; uint8_t hue1 = entry->hue; uint8_t sat1 = entry->sat; uint8_t val1 = entry->val; - + uint8_t blend = lo4 && (blendType != NOBLEND); - + if( blend ) { - + if( hi4 == 15 ) { entry = &(pal[0]); } else { entry++; } - + uint8_t f2 = lo4 << 4; uint8_t f1 = 256 - f2; - + uint8_t hue2 = entry->hue; uint8_t sat2 = entry->sat; uint8_t val2 = entry->val; @@ -497,26 +496,26 @@ CHSV ColorFromPalette( const struct CHSVPalette16& pal, uint8_t index, uint8_t b // of the other color, so that you get the expected // brightness or saturation ramp, with hue staying // constant: - + // If we are starting from white (sat=0) // or black (val=0), adopt the target hue. if( sat1 == 0 || val1 == 0) { hue1 = hue2; } - + // If we are ending at white (sat=0) // or black (val=0), adopt the starting hue. if( sat2 == 0 || val2 == 0) { hue2 = hue1; } - - + + sat1 = scale8_LEAVING_R1_DIRTY( sat1, f1); val1 = scale8_LEAVING_R1_DIRTY( val1, f1); - + sat2 = scale8_LEAVING_R1_DIRTY( sat2, f2); val2 = scale8_LEAVING_R1_DIRTY( val2, f2); - + // cleanup_R1(); // These sums can't overflow, so no qadd8 needed. @@ -531,15 +530,15 @@ CHSV ColorFromPalette( const struct CHSVPalette16& pal, uint8_t index, uint8_t b // go forwards hue1 += scale8( deltaHue, f2); } - + cleanup_R1(); } - + if( brightness != 255) { val1 = scale8_video( val1, brightness); } - - return CHSV( hue1, sat1, val1); + + return CHSV( hue1, sat1, val1); } @@ -550,7 +549,7 @@ CHSV ColorFromPalette( const struct CHSVPalette256& pal, uint8_t index, uint8_t if( brightness != 255) { hsv.value = scale8_video( hsv.value, brightness); } - + return hsv; } diff --git a/fastled_config.h b/fastled_config.h new file mode 100644 index 00000000..3e5a8c4e --- /dev/null +++ b/fastled_config.h @@ -0,0 +1,12 @@ +#ifndef __INC_FASTLED_CONFIG_H +#define __INC_FASTLED_CONFIG_H + +// Use this option only for debugging pin access and forcing software pin access. Note that +// software pin access only works in Arduino based environments. Forces use of digitalWrite +// methods for pin access vs. direct hardware port access +// #define FORCE_SOFTWARE_PINS + +// Use this option only for debugging bitbang'd spi access or to work around bugs in hardware +// spi access. Forces use of bit-banged spi, even on pins that has hardware SPI available. +// #define FORCE_SOFTWARE_SPI +#endif @@ -3,7 +3,7 @@ #include "led_sysdefs.h" -#define NO_PIN 255 +#define NO_PIN 255 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // @@ -18,13 +18,15 @@ public: virtual bool isSelected() = 0; }; -class Pin : public Selectable { +#if defined(ARDUINO) + +class Pin : public Selectable { volatile RwReg *mPort; volatile RoReg *mInPort; RwReg mPinMask; uint8_t mPin; - void _init() { + void _init() { mPinMask = digitalPinToBitMask(mPin); mPort = portOutputRegister(digitalPinToPort(mPin)); mInPort = portInputRegister(digitalPinToPort(mPin)); @@ -38,14 +40,14 @@ public: inline void setOutput() { pinMode(mPin, OUTPUT); } inline void setInput() { pinMode(mPin, INPUT); } - inline void hi() __attribute__ ((always_inline)) { *mPort |= mPinMask; } + inline void hi() __attribute__ ((always_inline)) { *mPort |= mPinMask; } inline void lo() __attribute__ ((always_inline)) { *mPort &= ~mPinMask; } inline void strobe() __attribute__ ((always_inline)) { toggle(); toggle(); } inline void toggle() __attribute__ ((always_inline)) { *mInPort = mPinMask; } - inline void hi(register port_ptr_t port) __attribute__ ((always_inline)) { *port |= mPinMask; } - inline void lo(register port_ptr_t port) __attribute__ ((always_inline)) { *port &= ~mPinMask; } + inline void hi(register port_ptr_t port) __attribute__ ((always_inline)) { *port |= mPinMask; } + inline void lo(register port_ptr_t port) __attribute__ ((always_inline)) { *port &= ~mPinMask; } inline void set(register port_t val) __attribute__ ((always_inline)) { *mPort = val; } inline void fastset(register port_ptr_t port, register port_t val) __attribute__ ((always_inline)) { *port = val; } @@ -75,20 +77,20 @@ public: /// will provide pin level access on pretty much all arduino environments. In addition, it includes some methods to help optimize access in /// various ways. Namely, the versions of hi, lo, and fastset that take the port register as a passed in register variable (saving a global /// dereference), since these functions are aggressively inlined, that can help collapse out a lot of extraneous memory loads/dereferences. -/// +/// /// In addition, if, while writing a bunch of data to a pin, you know no other pins will be getting written to, you can get/cache a value of /// the pin's port register and use that to do a full set to the register. This results in one being able to simply do a store to the register, /// vs. the load, and/or, and store that would be done normally. /// /// There are platform specific instantiations of this class that provide direct i/o register access to pins for much higher speed pin twiddling. /// -/// Note that these classes are all static functions. So the proper usage is Pin<13>::hi(); or such. Instantiating objects is not recommended, +/// Note that these classes are all static functions. So the proper usage is Pin<13>::hi(); or such. Instantiating objects is not recommended, /// as passing Pin objects around will likely -not- have the effect you're expecting. -template<uint8_t PIN> class FastPin { +template<uint8_t PIN> class FastPin { static RwReg sPinMask; static volatile RwReg *sPort; static volatile RoReg *sInPort; - static void _init() { + static void _init() { sPinMask = digitalPinToBitMask(PIN); sPort = portOutputRegister(digitalPinToPort(PIN)); sInPort = portInputRegister(digitalPinToPort(PIN)); @@ -100,15 +102,15 @@ public: inline static void setOutput() { _init(); pinMode(PIN, OUTPUT); } inline static void setInput() { _init(); pinMode(PIN, INPUT); } - inline static void hi() __attribute__ ((always_inline)) { *sPort |= sPinMask; } + inline static void hi() __attribute__ ((always_inline)) { *sPort |= sPinMask; } inline static void lo() __attribute__ ((always_inline)) { *sPort &= ~sPinMask; } inline static void strobe() __attribute__ ((always_inline)) { toggle(); toggle(); } inline static void toggle() __attribute__ ((always_inline)) { *sInPort = sPinMask; } - inline static void hi(register port_ptr_t port) __attribute__ ((always_inline)) { *port |= sPinMask; } - inline static void lo(register port_ptr_t port) __attribute__ ((always_inline)) { *port &= ~sPinMask; } + inline static void hi(register port_ptr_t port) __attribute__ ((always_inline)) { *port |= sPinMask; } + inline static void lo(register port_ptr_t port) __attribute__ ((always_inline)) { *port &= ~sPinMask; } inline static void set(register port_t val) __attribute__ ((always_inline)) { *sPort = val; } inline static void fastset(register port_ptr_t port, register port_t val) __attribute__ ((always_inline)) { *port = val; } @@ -124,37 +126,11 @@ template<uint8_t PIN> volatile RwReg *FastPin<PIN>::sPort; template<uint8_t PIN> volatile RoReg *FastPin<PIN>::sInPort; template<uint8_t PIN> class FastPinBB : public FastPin<PIN> {}; - +#endif // defined(ARDUINO) typedef volatile uint32_t & reg32_t; typedef volatile uint32_t * ptr_reg32_t; -/////////////////////////////////////////////////////////////////////////////////////////////////////////// -// -// Pin definitions for AVR and ARM. If there are pin definitions supplied below for the platform being -// built on, then much higher speed access will be possible, namely with direct GPIO register accesses. -// -/////////////////////////////////////////////////////////////////////////////////////////////////////////// -#if defined(FORCE_SOFTWARE_PINS) - -#warning "Softwrae pin support forced pin access will be slightly slower. See fastpin.h for info." -#define NO_HARDWARE_PIN_SUPPORT -#undef HAS_HARDWARE_PIN_SUPPORT - -#else - -// We want hardware pin support, include the hardware pin header files -#include "fastpin_avr.h" -#include "fastpin_arm_k20.h" -#include "fastpin_arm_sam.h" - -#ifndef HAS_HARDWARE_PIN_SUPPORT -#warning "No pin/port mappings found, pin access will be slightly slower. See fastpin.h for info." -#define NO_HARDWARE_PIN_SUPPORT -#endif - -#endif - -#endif +#endif // __INC_FASTPIN_H @@ -3,40 +3,9 @@ #include "controller.h" #include "lib8tion.h" -#include "delay.h" - -// Some helper macros for getting at mis-ordered byte values -#define SPI_B0 (RGB_BYTE0(RGB_ORDER) + (MASK_SKIP_BITS & SKIP)) -#define SPI_B1 (RGB_BYTE1(RGB_ORDER) + (MASK_SKIP_BITS & SKIP)) -#define SPI_B2 (RGB_BYTE2(RGB_ORDER) + (MASK_SKIP_BITS & SKIP)) -#define SPI_ADVANCE (3 + (MASK_SKIP_BITS & SKIP)) - -/// Some of the SPI controllers will need to perform a transform on each byte before doing -/// anyting with it. Creating a class of this form and passing it in as a template parameter to -/// writeBytes/writeBytes3 below will ensure that the body of this method will get called on every -/// byte worked on. Recommendation, make the adjust method aggressively inlined. -/// -/// 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) {} -}; - -#define FLAG_START_BIT 0x80 -#define MASK_SKIP_BITS 0x3F - -// Clock speed dividers -#define SPEED_DIV_2 2 -#define SPEED_DIV_4 4 -#define SPEED_DIV_8 8 -#define SPEED_DIV_16 16 -#define SPEED_DIV_32 32 -#define SPEED_DIV_64 64 -#define SPEED_DIV_128 128 - -#define MAX_DATA_RATE 0 + +#include "fastspi_bitbang.h" + #if (CLK_DBL == 1) #define DATA_RATE_MHZ(X) (((F_CPU / 1000000L) / X)/2) #define DATA_RATE_KHZ(X) (((F_CPU / 1000L) / X)/2) @@ -45,13 +14,6 @@ public: #define DATA_RATE_KHZ(X) ((F_CPU / 1000L) / X) #endif -// Include the various specific SPI implementations -#include "fastspi_bitbang.h" -#include "fastspi_arm_k20.h" -#include "fastspi_arm_sam.h" -#include "fastspi_avr.h" -#include "fastspi_dma.h" - ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // External SPI template definition with partial instantiation(s) to map to hardware SPI ports on platforms/builds where the pin diff --git a/fastspi_types.h b/fastspi_types.h new file mode 100644 index 00000000..e0de6de3 --- /dev/null +++ b/fastspi_types.h @@ -0,0 +1,37 @@ +#ifndef __INC_FASTSPI_TYPES_H +#define __INC_FASTSPI_TYPES_H + +// Some helper macros for getting at mis-ordered byte values +#define SPI_B0 (RGB_BYTE0(RGB_ORDER) + (MASK_SKIP_BITS & SKIP)) +#define SPI_B1 (RGB_BYTE1(RGB_ORDER) + (MASK_SKIP_BITS & SKIP)) +#define SPI_B2 (RGB_BYTE2(RGB_ORDER) + (MASK_SKIP_BITS & SKIP)) +#define SPI_ADVANCE (3 + (MASK_SKIP_BITS & SKIP)) + +/// Some of the SPI controllers will need to perform a transform on each byte before doing +/// anyting with it. Creating a class of this form and passing it in as a template parameter to +/// writeBytes/writeBytes3 below will ensure that the body of this method will get called on every +/// byte worked on. Recommendation, make the adjust method aggressively inlined. +/// +/// 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) {} +}; + +#define FLAG_START_BIT 0x80 +#define MASK_SKIP_BITS 0x3F + +// Clock speed dividers +#define SPEED_DIV_2 2 +#define SPEED_DIV_4 4 +#define SPEED_DIV_8 8 +#define SPEED_DIV_16 16 +#define SPEED_DIV_32 32 +#define SPEED_DIV_64 64 +#define SPEED_DIV_128 128 + +#define MAX_DATA_RATE 0 + +#endif diff --git a/hsv2rgb.cpp b/hsv2rgb.cpp index 0844d1f2..203d1db6 100644 --- a/hsv2rgb.cpp +++ b/hsv2rgb.cpp @@ -1,7 +1,6 @@ #include <stdint.h> -#include "lib8tion.h" -#include "hsv2rgb.h" +#include "FastLED.h" // Functions to convert HSV colors to RGB colors. // @@ -71,29 +70,29 @@ void hsv2rgb_raw_C (const struct CHSV & hsv, struct CRGB & rgb) // Convert hue, saturation and brightness ( HSV/HSB ) to RGB // "Dimming" is used on saturation and brightness to make // the output more visually linear. - + // Apply dimming curves uint8_t value = APPLY_DIMMING( hsv.val); uint8_t saturation = hsv.sat; - + // The brightness floor is minimum number that all of // R, G, and B will be set to. uint8_t invsat = APPLY_DIMMING( 255 - saturation); uint8_t brightness_floor = (value * invsat) / 256; - + // The color amplitude is the maximum amount of R, G, and B // that will be added on top of the brightness_floor to // create the specific hue desired. uint8_t color_amplitude = value - brightness_floor; - + // Figure out which section of the hue wheel we're in, // and how far offset we are withing that section uint8_t section = hsv.hue / HSV_SECTION_3; // 0..2 uint8_t offset = hsv.hue % HSV_SECTION_3; // 0..63 - + uint8_t rampup = offset; // 0..63 uint8_t rampdown = (HSV_SECTION_3 - 1) - offset; // 63..0 - + // We now scale rampup and rampdown to a 0-255 range -- at least // in theory, but here's where architecture-specific decsions // come in to play: @@ -113,25 +112,25 @@ void hsv2rgb_raw_C (const struct CHSV & hsv, struct CRGB & rgb) // faster to NOT multiply the ramp values by four, and just to // divide the resulting product by 64 (instead of 256). // Moral of the story: trust your profiler, not your insticts. - + // Since there's an AVR assembly version elsewhere, we'll // assume what we're on an architecture where any number of // bit shifts has roughly the same cost, and we'll remove the // redundant math at the source level: - + // // scale up to 255 range // //rampup *= 4; // 0..252 // //rampdown *= 4; // 0..252 - + // compute color-amplitude-scaled-down versions of rampup and rampdown uint8_t rampup_amp_adj = (rampup * color_amplitude) / (256 / 4); uint8_t rampdown_amp_adj = (rampdown * color_amplitude) / (256 / 4); - + // add brightness_floor offset to everything uint8_t rampup_adj_with_floor = rampup_amp_adj + brightness_floor; uint8_t rampdown_adj_with_floor = rampdown_amp_adj + brightness_floor; - - + + if( section ) { if( section == 1) { // section 1: 0x40..0x7F @@ -158,22 +157,22 @@ void hsv2rgb_raw_C (const struct CHSV & hsv, struct CRGB & rgb) void hsv2rgb_raw_avr(const struct CHSV & hsv, struct CRGB & rgb) { uint8_t hue, saturation, value; - + hue = hsv.hue; saturation = hsv.sat; value = hsv.val; - + // Saturation more useful the other way around saturation = 255 - saturation; uint8_t invsat = APPLY_DIMMING( saturation ); - + // Apply dimming curves value = APPLY_DIMMING( value ); - + // The brightness floor is minimum number that all of // R, G, and B will be set to, which is value * invsat uint8_t brightness_floor; - + asm volatile( "mul %[value], %[invsat] \n" "mov %[brightness_floor], r1 \n" @@ -182,22 +181,22 @@ void hsv2rgb_raw_avr(const struct CHSV & hsv, struct CRGB & rgb) [invsat] "r" (invsat) : "r0", "r1" ); - + // The color amplitude is the maximum amount of R, G, and B // that will be added on top of the brightness_floor to // create the specific hue desired. uint8_t color_amplitude = value - brightness_floor; - + // Figure how far we are offset into the section of the // color wheel that we're in uint8_t offset = hsv.hue & (HSV_SECTION_3 - 1); // 0..63 uint8_t rampup = offset * 4; // 0..252 - - + + // compute color-amplitude-scaled-down versions of rampup and rampdown uint8_t rampup_amp_adj; uint8_t rampdown_amp_adj; - + asm volatile( "mul %[rampup], %[color_amplitude] \n" "mov %[rampup_amp_adj], r1 \n" @@ -210,13 +209,13 @@ void hsv2rgb_raw_avr(const struct CHSV & hsv, struct CRGB & rgb) : [color_amplitude] "r" (color_amplitude) : "r0", "r1" ); - - + + // add brightness_floor offset to everything uint8_t rampup_adj_with_floor = rampup_amp_adj + brightness_floor; uint8_t rampdown_adj_with_floor = rampdown_amp_adj + brightness_floor; - - + + // keep gcc from using "X" as the index register for storing // results back in the return structure. AVR's X register can't // do "std X+q, rnn", but the Y and Z registers can. @@ -224,8 +223,8 @@ void hsv2rgb_raw_avr(const struct CHSV & hsv, struct CRGB & rgb) // extra instructions. Simply killing X here seems to help it // try Y or Z first. asm volatile( "" : : : "r26", "r27" ); - - + + if( hue & 0x80 ) { // section 2: 0x80..0xBF rgb.r = rampup_adj_with_floor; @@ -244,7 +243,7 @@ void hsv2rgb_raw_avr(const struct CHSV & hsv, struct CRGB & rgb) rgb.b = brightness_floor; } } - + cleanup_R1(); } // End of AVR asm implementation @@ -288,18 +287,18 @@ void hsv2rgb_rainbow( const CHSV& hsv, CRGB& rgb) // G2: Whether to divide all greens by two. // Depends GREATLY on your particular LEDs const uint8_t G2 = 0; - + // Gscale: what to scale green down by. // Depends GREATLY on your particular LEDs const uint8_t Gscale = 0; - + uint8_t hue = hsv.hue; uint8_t sat = hsv.sat; uint8_t val = hsv.val; - + uint8_t offset = hue & 0x1F; // 0..31 - + // offset8 = offset * 8 uint8_t offset8 = offset; { @@ -309,11 +308,11 @@ void hsv2rgb_rainbow( const CHSV& hsv, CRGB& rgb) asm volatile(""); offset8 <<= 1; } - + uint8_t third = scale8( offset8, (256 / 3)); - + uint8_t r, g, b; - + if( ! (hue & 0x80) ) { // 0XX if( ! (hue & 0x40) ) { @@ -417,12 +416,12 @@ void hsv2rgb_rainbow( const CHSV& hsv, CRGB& rgb) } } } - + // This is one of the good places to scale the green down, // although the client can scale green down as well. if( G2 ) g = g >> 1; if( Gscale ) g = scale8_video_LEAVING_R1_DIRTY( g, Gscale); - + // Scale down colors if we're desaturated at all // and add the brightness_floor to r, g, and b. if( sat != 255 ) { @@ -431,7 +430,7 @@ void hsv2rgb_rainbow( const CHSV& hsv, CRGB& rgb) uint8_t desat = 255 - sat; desat = scale8( desat, desat); - + uint8_t brightness_floor = desat; r += brightness_floor; g += brightness_floor; @@ -440,11 +439,11 @@ void hsv2rgb_rainbow( const CHSV& hsv, CRGB& rgb) // Now scale everything down if we're at value < 255. if( val != 255 ) { - + val = scale8_video_LEAVING_R1_DIRTY( val, val); nscale8x3_video( r, g, b, val); } - + // Here we have the old AVR "missing std X+n" problem again // It turns out that fixing it winds up costing more than // not fixing it. diff --git a/led_sysdefs.h b/led_sysdefs.h index e16ce2db..29bced42 100644 --- a/led_sysdefs.h +++ b/led_sysdefs.h @@ -2,91 +2,21 @@ #define __INC_LED_SYSDEFS_H #if defined(__MK20DX128__) || defined(__MK20DX256__) - -#define FASTLED_TEENSY3 -#define FASTLED_ARM -#define FASTLED_ACCURATE_CLOCK -#ifndef INTERRUPT_THRESHOLD -#define INTERRUPT_THRESHOLD 1 -#endif -#if (F_CPU == 96000000) -#define CLK_DBL 1 -#endif - +// Include k20/T3 headers +#include "platforms/arm/k20/led_sysdefs_arm_k20.h" #elif defined(__SAM3X8E__) - -#define FASTLED_ARM - -// Setup DUE timer defines/channels/etc... -#ifndef DUE_TIMER_CHANNEL -#define DUE_TIMER_GROUP 0 -#endif - -#ifndef DUE_TIMER_CHANNEL -#define DUE_TIMER_CHANNEL 0 -#endif - -#define DUE_TIMER ((DUE_TIMER_GROUP==0) ? TC0 : ((DUE_TIMER_GROUP==1) ? TC1 : TC2)) -#define DUE_TIMER_ID (ID_TC0 + (DUE_TIMER_GROUP*3) + DUE_TIMER_CHANNEL) -#define DUE_TIMER_VAL (DUE_TIMER->TC_CHANNEL[DUE_TIMER_CHANNEL].TC_CV << 1) -#define DUE_TIMER_RUNNING ((DUE_TIMER->TC_CHANNEL[DUE_TIMER_CHANNEL].TC_SR & TC_SR_CLKSTA) != 0) - +// Include sam/due headers +#include "platforms/arm/sam/led_sysdefs_arm_sam.h" #else - -#define FASTLED_AVR -#define FASTLED_ACCURATE_CLOCK -#ifndef INTERRUPT_THRESHOLD -#define INTERRUPT_THRESHOLD 2 +// AVR platforms +#include "platforms/avr/led_sysdefs_avr.h" #endif -#endif - -#ifndef CLK_DBL -#define CLK_DBL 0 -#endif -#if defined(FASTLED_AVR) || defined(FASTLED_TEENSY3) -#include <avr/io.h> -#include <avr/interrupt.h> // for cli/se definitions - -// Define the rgister 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) */ -#endif - -#else -// reuseing/abusing cli/sei defs for due -#define cli() __disable_irq(); __disable_fault_irq(); -#define sei() __enable_irq(); __enable_fault_irq(); - -#endif - -#if 0 -#if defined(ARDUINO) && defined(FASTLED_AVR) && ARDUINO >= 157 -#error Arduion versions 1.5.7 and later not yet supported by FastLED for AVR -#endif - -#if defined(ARDUINO) && defined (FASTLED_AVR) && (__GNUC__ == 4) && (__GNUC_MINOR__ > 7) -#error gcc versions 4.8 and above are not yet supported by FastLED for AVR -#endif -#endif // Arduino.h needed for convinience functions digitalPinToPort/BitMask/portOutputRegister and the pinMode methods. #include<Arduino.h> -// Scaling macro choice -#if defined(LIB8_ATTINY) -# define INLINE_SCALE(B, SCALE) delaycycles<3>() -# warning "No hardware multiply, inline brightness scaling disabled" -#else -# define INLINE_SCALE(B, SCALE) B = scale8_video(B, SCALE) -#endif - #define CLKS_PER_US (F_CPU/1000000) -#ifndef INTERRUPT_THRESHOLD -#define INTERRUPT_THRESHOLD 1 -#endif - #endif @@ -1,3 +1,7 @@ +#ifndef __INC_LED_SYSDEFS_H +#error WTH? led_sysdefs needs to be included first +#endif + #ifndef __INC_LIB8TION_H #define __INC_LIB8TION_H @@ -109,7 +113,7 @@ faster and five times smaller than Arduino's built-in generic 32-bit sqrt routine. sqrt16( uint16_t x ) == sqrt( x) - + - Dimming and brightening functions for 8-bit light values. dim8_video( x) == scale8_video( x, x) @@ -145,7 +149,7 @@ Sine wave beat generators can specify a low and high range for the output. Sawtooth wave beat generators always range 0-255 or 0-65535. - beatsin8( BPM, low8, high8) + beatsin8( BPM, low8, high8) = (sine(beatphase) * (high8-low8)) + low8 beatsin16( BPM, low16, high16) = (sine(beatphase) * (high16-low16)) + low16 @@ -1679,16 +1683,16 @@ LIB8STATIC uint8_t sqrt16(uint16_t x) if( x <= 1) { return x; } - + uint8_t low = 1; // lower bound uint8_t hi, mid; - + if( x > 7904) { hi = 255; } else { hi = (x >> 5) + 8; // initial estimate for upper bound } - + do { mid = (low + hi) >> 1; if ((uint16_t)(mid * mid) > x) { @@ -1700,7 +1704,7 @@ LIB8STATIC uint8_t sqrt16(uint16_t x) low = mid + 1; } } while (hi >= low); - + return low - 1; } @@ -1796,7 +1800,7 @@ LIB8STATIC uint16_t beat16( accum88 beats_per_minute) { // Convert simple 8-bit BPM's to full Q8.8 accum88's if needed if( beats_per_minute < 256) beats_per_minute <<= 8; - + // BPM is 'beats per minute', or 'beats per 60000ms'. // To avoid using the (slower) division operator, we // want to convert 'beats per 60000ms' to 'beats per 65536ms', diff --git a/platforms.h b/platforms.h new file mode 100644 index 00000000..9f1c7579 --- /dev/null +++ b/platforms.h @@ -0,0 +1,15 @@ +#ifndef __INC_PLATFORMS_H +#define __INC_PLATFORMS_H + +#if defined(__MK20DX128__) || defined(__MK20DX256__) +// Include k20/T3 headers +#include "platforms/arm/k20/fastled_arm_k20.h" +#elif defined(__SAM3X8E__) +// Include sam/due headers +#include "platforms/arm/sam/fastled_arm_sam.h" +#else +// AVR platforms +#include "platforms/avr/fastled_avr.h" +#endif + +#endif diff --git a/clockless_arm_k20.h b/platforms/arm/k20/clockless_arm_k20.h index d96c9bb2..d96c9bb2 100644 --- a/clockless_arm_k20.h +++ b/platforms/arm/k20/clockless_arm_k20.h diff --git a/clockless_block_arm_k20.h b/platforms/arm/k20/clockless_block_arm_k20.h index 63dc5030..63dc5030 100644 --- a/clockless_block_arm_k20.h +++ b/platforms/arm/k20/clockless_block_arm_k20.h diff --git a/platforms/arm/k20/fastled_arm_k20.h b/platforms/arm/k20/fastled_arm_k20.h new file mode 100644 index 00000000..48565ec5 --- /dev/null +++ b/platforms/arm/k20/fastled_arm_k20.h @@ -0,0 +1,14 @@ +#ifndef __INC_FASTLED_ARM_K20_H +#define __INC_FASTLED_ARM_K20_H + +// Include the k20 headers +#include "bitswap.h" +#include "delay.h" +#include "fastpin_arm_k20.h" +#include "fastspi_arm_k20.h" +#include "octows2811_controller.h" +#include "smartmatrix_t3.h" +#include "clockless_arm_k20.h" +#include "clockless_block_arm_k20.h" + +#endif diff --git a/fastpin_arm_k20.h b/platforms/arm/k20/fastpin_arm_k20.h index 2fb75fbd..edbbd5b9 100644 --- a/fastpin_arm_k20.h +++ b/platforms/arm/k20/fastpin_arm_k20.h @@ -1,6 +1,14 @@ #ifndef __FASTPIN_ARM_K20_H #define __FASTPIN_ARM_K20_H +#if defined(FORCE_SOFTWARE_PINS) +#warning "Software pin support forced, pin access will be sloightly slower." +#define NO_HARDWARE_PIN_SUPPORT +#undef HAS_HARDWARE_PIN_SUPPORT + +#else + + /// Template definition for teensy 3.0 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. @@ -65,6 +73,7 @@ public: #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))) +#define _R(T) struct __gen_struct_ ## T #define _RD32(T) struct __gen_struct_ ## T { static __attribute__((always_inline)) inline reg32_t r() { return T; } \ template<int BIT> static __attribute__((always_inline)) inline ptr_reg32_t rx() { return GPIO_BITBAND_PTR(T, BIT); } }; #define _IO32(L) _RD32(GPIO ## L ## _PDOR); _RD32(GPIO ## L ## _PSOR); _RD32(GPIO ## L ## _PCOR); _RD32(GPIO ## L ## _PTOR); _RD32(GPIO ## L ## _PDIR); _RD32(GPIO ## L ## _PDDR); @@ -104,4 +113,6 @@ _DEFPIN_ARM(32, 18, B); _DEFPIN_ARM(33, 4, A); #define HAS_HARDWARE_PIN_SUPPORT #endif -#endif +#endif // FORCE_SOFTWARE_PINS + +#endif // __INC_FASTPIN_ARM_K20 diff --git a/fastspi_arm_k20.h b/platforms/arm/k20/fastspi_arm_k20.h index ad9598ae..ad9598ae 100644 --- a/fastspi_arm_k20.h +++ b/platforms/arm/k20/fastspi_arm_k20.h diff --git a/platforms/arm/k20/led_sysdefs_arm_k20.h b/platforms/arm/k20/led_sysdefs_arm_k20.h new file mode 100644 index 00000000..abed80f9 --- /dev/null +++ b/platforms/arm/k20/led_sysdefs_arm_k20.h @@ -0,0 +1,26 @@ +#ifndef __INC_LED_SYSDEFS_ARM_K20_H +#define __INC_LED_SYSDEFS_ARM_K20_H + +#define FASTLED_TEENSY3 +#define FASTLED_ARM +#define FASTLED_ACCURATE_CLOCK + +#ifndef INTERRUPT_THRESHOLD +#define INTERRUPT_THRESHOLD 1 +#endif + +#if (F_CPU == 96000000) +#define CLK_DBL 1 +#endif + +// Get some system include files +#include <avr/io.h> +#include <avr/interrupt.h> // for cli/se definitions + +// Define the rgister 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) */ +#endif + +#endif diff --git a/octows2811_controller.h b/platforms/arm/k20/octows2811_controller.h index dd6c0b92..dd6c0b92 100644 --- a/octows2811_controller.h +++ b/platforms/arm/k20/octows2811_controller.h diff --git a/smartmatrix_t3.h b/platforms/arm/k20/smartmatrix_t3.h index ba77d149..ba77d149 100644 --- a/smartmatrix_t3.h +++ b/platforms/arm/k20/smartmatrix_t3.h diff --git a/clockless_arm_sam.h b/platforms/arm/sam/clockless_arm_sam.h index 6924cc9d..6924cc9d 100644 --- a/clockless_arm_sam.h +++ b/platforms/arm/sam/clockless_arm_sam.h diff --git a/clockless_block_arm_sam.h b/platforms/arm/sam/clockless_block_arm_sam.h index c75e3ce6..51eb1b92 100644 --- a/clockless_block_arm_sam.h +++ b/platforms/arm/sam/clockless_block_arm_sam.h @@ -1,11 +1,6 @@ #ifndef __INC_BLOCK_CLOCKLESS_H #define __INC_BLOCK_CLOCKLESS_H -#include "controller.h" -#include "lib8tion.h" -#include "led_sysdefs.h" -#include "delay.h" - ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // Base template for clockless controllers. These controllers have 3 control points in their cycle for each bit. The first point diff --git a/platforms/arm/sam/fastled_arm_sam.h b/platforms/arm/sam/fastled_arm_sam.h new file mode 100644 index 00000000..51e2f37c --- /dev/null +++ b/platforms/arm/sam/fastled_arm_sam.h @@ -0,0 +1,11 @@ +#ifndef __INC_FASTLED_ARM_SAM_H +#define __INC_FASTLED_ARM_SAM_H + +// Include the sam headers +#include "delay.h" +#include "fastpin_arm_sam.h" +#include "fastspi_arm_sam.h" +#include "clockless_arm_sam.h" +#include "clockless_block_arm_sam.h" + +#endif diff --git a/fastpin_arm_sam.h b/platforms/arm/sam/fastpin_arm_sam.h index 0296bd50..e1a36990 100644 --- a/fastpin_arm_sam.h +++ b/platforms/arm/sam/fastpin_arm_sam.h @@ -1,11 +1,19 @@ #ifndef __INC_FASTPIN_ARM_SAM_H #define __INC_FASTPIN_ARM_SAM_H +#if defined(FORCE_SOFTWARE_PINS) +#warning "Software pin support forced, pin access will be sloightly slower." +#define NO_HARDWARE_PIN_SUPPORT +#undef HAS_HARDWARE_PIN_SUPPORT + +#else + + /// Template definition for arduino due 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 register, set output register, clear output register, set data direction register -template<uint8_t PIN, uint32_t _MASK, typename _PDOR, typename _PSOR, typename _PCOR, typename _PDDR> class _DUEPIN { +template<uint8_t PIN, uint32_t _MASK, typename _PDOR, typename _PSOR, typename _PCOR, typename _PDDR> class _DUEPIN { public: typedef volatile uint32_t * port_ptr_t; typedef uint32_t port_t; @@ -18,7 +26,7 @@ public: inline static void set(register port_t val) __attribute__ ((always_inline)) { _PDOR::r() = val; } inline static void strobe() __attribute__ ((always_inline)) { toggle(); toggle(); } - + inline static void toggle() __attribute__ ((always_inline)) { _PDOR::r() ^= _MASK; } inline static void hi(register port_ptr_t port) __attribute__ ((always_inline)) { hi(); } @@ -34,9 +42,9 @@ public: }; -/// Template definition for DUE style ARM pins using bit banding, providing direct access to the various GPIO registers. GCC +/// Template definition for DUE 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, uint32_t _BIT, typename _PDOR, typename _PSOR, typename _PCOR, typename _PDDR> class _DUEPIN_BITBAND { +template<uint8_t PIN, uint32_t _BIT, typename _PDOR, typename _PSOR, typename _PCOR, typename _PDDR> class _DUEPIN_BITBAND { public: typedef volatile uint32_t * port_ptr_t; typedef uint32_t port_t; @@ -49,7 +57,7 @@ public: 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)) { *_PDOR::template rx<_BIT>() ^= 1; } inline static void hi(register port_ptr_t port) __attribute__ ((always_inline)) { hi(); } @@ -62,12 +70,18 @@ public: inline static port_t mask() __attribute__ ((always_inline)) { return 1; } }; +#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))) + +#define _R(T) struct __gen_struct_ ## T +#define _RD32(T) struct __gen_struct_ ## T { static __attribute__((always_inline)) inline reg32_t r() { return T; } \ + template<int BIT> static __attribute__((always_inline)) inline ptr_reg32_t rx() { return GPIO_BITBAND_PTR(T, BIT); } }; #define DUE_IO32(L) _RD32(REG_PIO ## L ## _ODSR); _RD32(REG_PIO ## L ## _SODR); _RD32(REG_PIO ## L ## _CODR); _RD32(REG_PIO ## L ## _OER); #define _DEFPIN_DUE(PIN, BIT, L) template<> class FastPin<PIN> : public _DUEPIN<PIN, 1 << BIT, _R(REG_PIO ## L ## _ODSR), _R(REG_PIO ## L ## _SODR), _R(REG_PIO ## L ## _CODR), \ _R(GPIO ## L ## _OER)> {}; \ template<> class FastPinBB<PIN> : public _DUEPIN_BITBAND<PIN, BIT, _R(REG_PIO ## L ## _ODSR), _R(REG_PIO ## L ## _SODR), _R(REG_PIO ## L ## _CODR), \ - _R(GPIO ## L ## _OER)> {}; + _R(GPIO ## L ## _OER)> {}; #if defined(__SAM3X8E__) @@ -113,5 +127,6 @@ _DEFPIN_DUE(110, 29, B); _DEFPIN_DUE(111, 30, B); _DEFPIN_DUE(112, 31, B); _DEFP #endif +#endif // FORCE_SOFTWARE_PINS -#endif +#endif // __INC_FASTPIN_ARM_SAM_H diff --git a/fastspi_arm_sam.h b/platforms/arm/sam/fastspi_arm_sam.h index d756c221..d756c221 100644 --- a/fastspi_arm_sam.h +++ b/platforms/arm/sam/fastspi_arm_sam.h diff --git a/platforms/arm/sam/led_sysdefs_arm_sam.h b/platforms/arm/sam/led_sysdefs_arm_sam.h new file mode 100644 index 00000000..e45f9609 --- /dev/null +++ b/platforms/arm/sam/led_sysdefs_arm_sam.h @@ -0,0 +1,30 @@ +#ifndef __INC_LED_SYSDEFS_ARM_SAM_H +#define __INC_LED_SYSDEFS_ARM_SAM_H + + +#define FASTLED_ARM + +// Setup DUE timer defines/channels/etc... +#ifndef DUE_TIMER_CHANNEL +#define DUE_TIMER_GROUP 0 +#endif + +#ifndef DUE_TIMER_CHANNEL +#define DUE_TIMER_CHANNEL 0 +#endif + +#define DUE_TIMER ((DUE_TIMER_GROUP==0) ? TC0 : ((DUE_TIMER_GROUP==1) ? TC1 : TC2)) +#define DUE_TIMER_ID (ID_TC0 + (DUE_TIMER_GROUP*3) + DUE_TIMER_CHANNEL) +#define DUE_TIMER_VAL (DUE_TIMER->TC_CHANNEL[DUE_TIMER_CHANNEL].TC_CV << 1) +#define DUE_TIMER_RUNNING ((DUE_TIMER->TC_CHANNEL[DUE_TIMER_CHANNEL].TC_SR & TC_SR_CLKSTA) != 0) + +#ifndef INTERRUPT_THRESHOLD +#define INTERRUPT_THRESHOLD 1 +#endif + +// reuseing/abusing cli/sei defs for due +#define cli() __disable_irq(); __disable_fault_irq(); +#define sei() __enable_irq(); __enable_fault_irq(); + + +#endif diff --git a/clockless_trinket.h b/platforms/avr/clockless_trinket.h index 592ea537..4630719d 100644 --- a/clockless_trinket.h +++ b/platforms/avr/clockless_trinket.h @@ -3,7 +3,6 @@ #include "controller.h" #include "lib8tion.h" -#include "delay.h" #include <avr/interrupt.h> // for cli/se definitions #if defined(FASTLED_AVR) diff --git a/platforms/avr/fastled_avr.h b/platforms/avr/fastled_avr.h new file mode 100644 index 00000000..4c9b842e --- /dev/null +++ b/platforms/avr/fastled_avr.h @@ -0,0 +1,9 @@ +#ifndef __INC_FASTLED_AVR_H +#define __INC_FASTLED_AVR_H + +#include "delay.h" +#include "fastpin_avr.h" +#include "fastspi_avr.h" +#include "clockless_trinket.h" + +#endif diff --git a/fastpin_avr.h b/platforms/avr/fastpin_avr.h index 103498c2..f5354a9d 100644 --- a/fastpin_avr.h +++ b/platforms/avr/fastpin_avr.h @@ -1,6 +1,13 @@ #ifndef __INC_FASTPIN_AVR_H #define __INC_FASTPIN_AVR_H +#if defined(FORCE_SOFTWARE_PINS) +#warning "Software pin support forced, pin access will be sloightly slower." +#define NO_HARDWARE_PIN_SUPPORT +#undef HAS_HARDWARE_PIN_SUPPORT + +#else + #if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) #define AVR_PIN_CYCLES(_PIN) (((_PIN >= 62 ) || (_PIN>=42 && _PIN<=49) || (_PIN>=14 && _PIN <=17) || (_PIN>=6 && _PIN <=9)) ? 2 : 1) #else @@ -9,12 +16,12 @@ /// Class definition for a Pin where we know the port registers at compile time for said pin. This allows us to make -/// a lot of optimizations, as the inlined hi/lo methods will devolve to a single io register write/bitset. -template<uint8_t PIN, uint8_t _MASK, typename _PORT, typename _DDR, typename _PIN> class _AVRPIN { +/// a lot of optimizations, as the inlined hi/lo methods will devolve to a single io register write/bitset. +template<uint8_t PIN, uint8_t _MASK, typename _PORT, typename _DDR, typename _PIN> class _AVRPIN { public: typedef volatile uint8_t * port_ptr_t; typedef uint8_t port_t; - + inline static void setOutput() { _DDR::r() |= _MASK; } inline static void setInput() { _DDR::r() &= ~_MASK; } @@ -23,7 +30,7 @@ public: inline static void set(register uint8_t val) __attribute__ ((always_inline)) { _PORT::r() = val; } inline static void strobe() __attribute__ ((always_inline)) { toggle(); toggle(); } - + inline static void toggle() __attribute__ ((always_inline)) { _PIN::r() = _MASK; } inline static void hi(register port_ptr_t port) __attribute__ ((always_inline)) { hi(); } @@ -55,7 +62,7 @@ _DEFPIN_AVR(4, 0x10, B); _DEFPIN_AVR(5, 0x20, B); #define HAS_HARDWARE_PIN_SUPPORT 1 -#elif defined(__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__) || defined(__AVR_ATtiny25__) +#elif defined(__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__) || defined(__AVR_ATtiny25__) _IO(A); _IO(B); _DEFPIN_AVR(0, 0x01, A); _DEFPIN_AVR(1, 0x02, A); _DEFPIN_AVR(2, 0x04, A); _DEFPIN_AVR(3, 0x08, A); @@ -106,24 +113,24 @@ _DEFPIN_AVR(28, 1<<6, C); _DEFPIN_AVR(29, 1<<7, C); _DEFPIN_AVR(30, 1<<4, D); _D _IO(A); _IO(B); _IO(C); _IO(D); _IO(E); _IO(F); _IO(G); _IO(H); _IO(J); _IO(K); _IO(L); #define MAX_PIN 69 -_DEFPIN_AVR(0, 1, E); _DEFPIN_AVR(1, 2, E); _DEFPIN_AVR(2, 16, E); _DEFPIN_AVR(3, 32, E); -_DEFPIN_AVR(4, 32, G); _DEFPIN_AVR(5, 8, E); _DEFPIN_AVR(6, 8, H); _DEFPIN_AVR(7, 16, H); -_DEFPIN_AVR(8, 32, H); _DEFPIN_AVR(9, 64, H); _DEFPIN_AVR(10, 16, B); _DEFPIN_AVR(11, 32, B); -_DEFPIN_AVR(12, 64, B); _DEFPIN_AVR(13, 128, B); _DEFPIN_AVR(14, 2, J); _DEFPIN_AVR(15, 1, J); -_DEFPIN_AVR(16, 2, H); _DEFPIN_AVR(17, 1, H); _DEFPIN_AVR(18, 8, D); _DEFPIN_AVR(19, 4, D); -_DEFPIN_AVR(20, 2, D); _DEFPIN_AVR(21, 1, D); _DEFPIN_AVR(22, 1, A); _DEFPIN_AVR(23, 2, A); -_DEFPIN_AVR(24, 4, A); _DEFPIN_AVR(25, 8, A); _DEFPIN_AVR(26, 16, A); _DEFPIN_AVR(27, 32, A); -_DEFPIN_AVR(28, 64, A); _DEFPIN_AVR(29, 128, A); _DEFPIN_AVR(30, 128, C); _DEFPIN_AVR(31, 64, C); -_DEFPIN_AVR(32, 32, C); _DEFPIN_AVR(33, 16, C); _DEFPIN_AVR(34, 8, C); _DEFPIN_AVR(35, 4, C); -_DEFPIN_AVR(36, 2, C); _DEFPIN_AVR(37, 1, C); _DEFPIN_AVR(38, 128, D); _DEFPIN_AVR(39, 4, G); -_DEFPIN_AVR(40, 2, G); _DEFPIN_AVR(41, 1, G); _DEFPIN_AVR(42, 128, L); _DEFPIN_AVR(43, 64, L); -_DEFPIN_AVR(44, 32, L); _DEFPIN_AVR(45, 16, L); _DEFPIN_AVR(46, 8, L); _DEFPIN_AVR(47, 4, L); -_DEFPIN_AVR(48, 2, L); _DEFPIN_AVR(49, 1, L); _DEFPIN_AVR(50, 8, B); _DEFPIN_AVR(51, 4, B); -_DEFPIN_AVR(52, 2, B); _DEFPIN_AVR(53, 1, B); _DEFPIN_AVR(54, 1, F); _DEFPIN_AVR(55, 2, F); -_DEFPIN_AVR(56, 4, F); _DEFPIN_AVR(57, 8, F); _DEFPIN_AVR(58, 16, F); _DEFPIN_AVR(59, 32, F); -_DEFPIN_AVR(60, 64, F); _DEFPIN_AVR(61, 128, F); _DEFPIN_AVR(62, 1, K); _DEFPIN_AVR(63, 2, K); -_DEFPIN_AVR(64, 4, K); _DEFPIN_AVR(65, 8, K); _DEFPIN_AVR(66, 16, K); _DEFPIN_AVR(67, 32, K); -_DEFPIN_AVR(68, 64, K); _DEFPIN_AVR(69, 128, K); +_DEFPIN_AVR(0, 1, E); _DEFPIN_AVR(1, 2, E); _DEFPIN_AVR(2, 16, E); _DEFPIN_AVR(3, 32, E); +_DEFPIN_AVR(4, 32, G); _DEFPIN_AVR(5, 8, E); _DEFPIN_AVR(6, 8, H); _DEFPIN_AVR(7, 16, H); +_DEFPIN_AVR(8, 32, H); _DEFPIN_AVR(9, 64, H); _DEFPIN_AVR(10, 16, B); _DEFPIN_AVR(11, 32, B); +_DEFPIN_AVR(12, 64, B); _DEFPIN_AVR(13, 128, B); _DEFPIN_AVR(14, 2, J); _DEFPIN_AVR(15, 1, J); +_DEFPIN_AVR(16, 2, H); _DEFPIN_AVR(17, 1, H); _DEFPIN_AVR(18, 8, D); _DEFPIN_AVR(19, 4, D); +_DEFPIN_AVR(20, 2, D); _DEFPIN_AVR(21, 1, D); _DEFPIN_AVR(22, 1, A); _DEFPIN_AVR(23, 2, A); +_DEFPIN_AVR(24, 4, A); _DEFPIN_AVR(25, 8, A); _DEFPIN_AVR(26, 16, A); _DEFPIN_AVR(27, 32, A); +_DEFPIN_AVR(28, 64, A); _DEFPIN_AVR(29, 128, A); _DEFPIN_AVR(30, 128, C); _DEFPIN_AVR(31, 64, C); +_DEFPIN_AVR(32, 32, C); _DEFPIN_AVR(33, 16, C); _DEFPIN_AVR(34, 8, C); _DEFPIN_AVR(35, 4, C); +_DEFPIN_AVR(36, 2, C); _DEFPIN_AVR(37, 1, C); _DEFPIN_AVR(38, 128, D); _DEFPIN_AVR(39, 4, G); +_DEFPIN_AVR(40, 2, G); _DEFPIN_AVR(41, 1, G); _DEFPIN_AVR(42, 128, L); _DEFPIN_AVR(43, 64, L); +_DEFPIN_AVR(44, 32, L); _DEFPIN_AVR(45, 16, L); _DEFPIN_AVR(46, 8, L); _DEFPIN_AVR(47, 4, L); +_DEFPIN_AVR(48, 2, L); _DEFPIN_AVR(49, 1, L); _DEFPIN_AVR(50, 8, B); _DEFPIN_AVR(51, 4, B); +_DEFPIN_AVR(52, 2, B); _DEFPIN_AVR(53, 1, B); _DEFPIN_AVR(54, 1, F); _DEFPIN_AVR(55, 2, F); +_DEFPIN_AVR(56, 4, F); _DEFPIN_AVR(57, 8, F); _DEFPIN_AVR(58, 16, F); _DEFPIN_AVR(59, 32, F); +_DEFPIN_AVR(60, 64, F); _DEFPIN_AVR(61, 128, F); _DEFPIN_AVR(62, 1, K); _DEFPIN_AVR(63, 2, K); +_DEFPIN_AVR(64, 4, K); _DEFPIN_AVR(65, 8, K); _DEFPIN_AVR(66, 16, K); _DEFPIN_AVR(67, 32, K); +_DEFPIN_AVR(68, 64, K); _DEFPIN_AVR(69, 128, K); #define SPI_DATA 51 #define SPI_CLOCK 52 @@ -135,15 +142,15 @@ _DEFPIN_AVR(68, 64, K); _DEFPIN_AVR(69, 128, K); #elif defined(__AVR_ATmega32U4__) && defined(CORE_TEENSY) // teensy defs -_IO(B); _IO(C); _IO(D); _IO(E); _IO(F); +_IO(B); _IO(C); _IO(D); _IO(E); _IO(F); #define MAX_PIN 23 -_DEFPIN_AVR(0, 1, B); _DEFPIN_AVR(1, 2, B); _DEFPIN_AVR(2, 4, B); _DEFPIN_AVR(3, 8, B); -_DEFPIN_AVR(4, 128, B); _DEFPIN_AVR(5, 1, D); _DEFPIN_AVR(6, 2, D); _DEFPIN_AVR(7, 4, D); -_DEFPIN_AVR(8, 8, D); _DEFPIN_AVR(9, 64, C); _DEFPIN_AVR(10, 128, C); _DEFPIN_AVR(11, 64, D); -_DEFPIN_AVR(12, 128, D); _DEFPIN_AVR(13, 16, B); _DEFPIN_AVR(14, 32, B); _DEFPIN_AVR(15, 64, B); -_DEFPIN_AVR(16, 128, F); _DEFPIN_AVR(17, 64, F); _DEFPIN_AVR(18, 32, F); _DEFPIN_AVR(19, 16, F); -_DEFPIN_AVR(20, 2, F); _DEFPIN_AVR(21, 1, F); _DEFPIN_AVR(22, 16, D); _DEFPIN_AVR(23, 32, D); +_DEFPIN_AVR(0, 1, B); _DEFPIN_AVR(1, 2, B); _DEFPIN_AVR(2, 4, B); _DEFPIN_AVR(3, 8, B); +_DEFPIN_AVR(4, 128, B); _DEFPIN_AVR(5, 1, D); _DEFPIN_AVR(6, 2, D); _DEFPIN_AVR(7, 4, D); +_DEFPIN_AVR(8, 8, D); _DEFPIN_AVR(9, 64, C); _DEFPIN_AVR(10, 128, C); _DEFPIN_AVR(11, 64, D); +_DEFPIN_AVR(12, 128, D); _DEFPIN_AVR(13, 16, B); _DEFPIN_AVR(14, 32, B); _DEFPIN_AVR(15, 64, B); +_DEFPIN_AVR(16, 128, F); _DEFPIN_AVR(17, 64, F); _DEFPIN_AVR(18, 32, F); _DEFPIN_AVR(19, 16, F); +_DEFPIN_AVR(20, 2, F); _DEFPIN_AVR(21, 1, F); _DEFPIN_AVR(22, 16, D); _DEFPIN_AVR(23, 32, D); #define SPI_DATA 2 #define SPI_CLOCK 1 @@ -154,21 +161,21 @@ _DEFPIN_AVR(20, 2, F); _DEFPIN_AVR(21, 1, F); _DEFPIN_AVR(22, 16, D); _DEFPIN_AV #elif defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__) // teensy++ 2 defs -_IO(A); _IO(B); _IO(C); _IO(D); _IO(E); _IO(F); +_IO(A); _IO(B); _IO(C); _IO(D); _IO(E); _IO(F); #define MAX_PIN 45 -_DEFPIN_AVR(0, 1, D); _DEFPIN_AVR(1, 2, D); _DEFPIN_AVR(2, 4, D); _DEFPIN_AVR(3, 8, D); -_DEFPIN_AVR(4, 16, D); _DEFPIN_AVR(5, 32, D); _DEFPIN_AVR(6, 64, D); _DEFPIN_AVR(7, 128, D); -_DEFPIN_AVR(8, 1, E); _DEFPIN_AVR(9, 2, E); _DEFPIN_AVR(10, 1, C); _DEFPIN_AVR(11, 2, C); -_DEFPIN_AVR(12, 4, C); _DEFPIN_AVR(13, 8, C); _DEFPIN_AVR(14, 16, C); _DEFPIN_AVR(15, 32, C); -_DEFPIN_AVR(16, 64, C); _DEFPIN_AVR(17, 128, C); _DEFPIN_AVR(18, 64, E); _DEFPIN_AVR(19, 128, E); -_DEFPIN_AVR(20, 1, B); _DEFPIN_AVR(21, 2, B); _DEFPIN_AVR(22, 4, B); _DEFPIN_AVR(23, 8, B); -_DEFPIN_AVR(24, 16, B); _DEFPIN_AVR(25, 32, B); _DEFPIN_AVR(26, 64, B); _DEFPIN_AVR(27, 128, B); -_DEFPIN_AVR(28, 1, A); _DEFPIN_AVR(29, 2, A); _DEFPIN_AVR(30, 4, A); _DEFPIN_AVR(31, 8, A); -_DEFPIN_AVR(32, 16, A); _DEFPIN_AVR(33, 32, A); _DEFPIN_AVR(34, 64, A); _DEFPIN_AVR(35, 128, A); -_DEFPIN_AVR(36, 16, E); _DEFPIN_AVR(37, 32, E); _DEFPIN_AVR(38, 1, F); _DEFPIN_AVR(39, 2, F); -_DEFPIN_AVR(40, 4, F); _DEFPIN_AVR(41, 8, F); _DEFPIN_AVR(42, 16, F); _DEFPIN_AVR(43, 32, F); -_DEFPIN_AVR(44, 64, F); _DEFPIN_AVR(45, 128, F); +_DEFPIN_AVR(0, 1, D); _DEFPIN_AVR(1, 2, D); _DEFPIN_AVR(2, 4, D); _DEFPIN_AVR(3, 8, D); +_DEFPIN_AVR(4, 16, D); _DEFPIN_AVR(5, 32, D); _DEFPIN_AVR(6, 64, D); _DEFPIN_AVR(7, 128, D); +_DEFPIN_AVR(8, 1, E); _DEFPIN_AVR(9, 2, E); _DEFPIN_AVR(10, 1, C); _DEFPIN_AVR(11, 2, C); +_DEFPIN_AVR(12, 4, C); _DEFPIN_AVR(13, 8, C); _DEFPIN_AVR(14, 16, C); _DEFPIN_AVR(15, 32, C); +_DEFPIN_AVR(16, 64, C); _DEFPIN_AVR(17, 128, C); _DEFPIN_AVR(18, 64, E); _DEFPIN_AVR(19, 128, E); +_DEFPIN_AVR(20, 1, B); _DEFPIN_AVR(21, 2, B); _DEFPIN_AVR(22, 4, B); _DEFPIN_AVR(23, 8, B); +_DEFPIN_AVR(24, 16, B); _DEFPIN_AVR(25, 32, B); _DEFPIN_AVR(26, 64, B); _DEFPIN_AVR(27, 128, B); +_DEFPIN_AVR(28, 1, A); _DEFPIN_AVR(29, 2, A); _DEFPIN_AVR(30, 4, A); _DEFPIN_AVR(31, 8, A); +_DEFPIN_AVR(32, 16, A); _DEFPIN_AVR(33, 32, A); _DEFPIN_AVR(34, 64, A); _DEFPIN_AVR(35, 128, A); +_DEFPIN_AVR(36, 16, E); _DEFPIN_AVR(37, 32, E); _DEFPIN_AVR(38, 1, F); _DEFPIN_AVR(39, 2, F); +_DEFPIN_AVR(40, 4, F); _DEFPIN_AVR(41, 8, F); _DEFPIN_AVR(42, 16, F); _DEFPIN_AVR(43, 32, F); +_DEFPIN_AVR(44, 64, F); _DEFPIN_AVR(45, 128, F); #define SPI_DATA 22 #define SPI_CLOCK 21 @@ -179,15 +186,15 @@ _DEFPIN_AVR(44, 64, F); _DEFPIN_AVR(45, 128, F); #elif defined(__AVR_ATmega32U4__) // leonard defs -_IO(B); _IO(C); _IO(D); _IO(E); _IO(F); +_IO(B); _IO(C); _IO(D); _IO(E); _IO(F); #define MAX_PIN 23 -_DEFPIN_AVR(0, 4, D); _DEFPIN_AVR(1, 8, D); _DEFPIN_AVR(2, 2, D); _DEFPIN_AVR(3, 1, D); -_DEFPIN_AVR(4, 16, D); _DEFPIN_AVR(5, 64, C); _DEFPIN_AVR(6, 128, D); _DEFPIN_AVR(7, 64, E); -_DEFPIN_AVR(8, 16, B); _DEFPIN_AVR(9, 32, B); _DEFPIN_AVR(10, 64, B); _DEFPIN_AVR(11, 128, B); -_DEFPIN_AVR(12, 64, D); _DEFPIN_AVR(13, 128, C); _DEFPIN_AVR(14, 8, B); _DEFPIN_AVR(15, 2, B); -_DEFPIN_AVR(16, 4, B); _DEFPIN_AVR(17, 1, B); _DEFPIN_AVR(18, 128, F); _DEFPIN_AVR(19, 64, F); -_DEFPIN_AVR(20, 32, F); _DEFPIN_AVR(21, 16, F); _DEFPIN_AVR(22, 2, F); _DEFPIN_AVR(23, 0, F); +_DEFPIN_AVR(0, 4, D); _DEFPIN_AVR(1, 8, D); _DEFPIN_AVR(2, 2, D); _DEFPIN_AVR(3, 1, D); +_DEFPIN_AVR(4, 16, D); _DEFPIN_AVR(5, 64, C); _DEFPIN_AVR(6, 128, D); _DEFPIN_AVR(7, 64, E); +_DEFPIN_AVR(8, 16, B); _DEFPIN_AVR(9, 32, B); _DEFPIN_AVR(10, 64, B); _DEFPIN_AVR(11, 128, B); +_DEFPIN_AVR(12, 64, D); _DEFPIN_AVR(13, 128, C); _DEFPIN_AVR(14, 8, B); _DEFPIN_AVR(15, 2, B); +_DEFPIN_AVR(16, 4, B); _DEFPIN_AVR(17, 1, B); _DEFPIN_AVR(18, 128, F); _DEFPIN_AVR(19, 64, F); +_DEFPIN_AVR(20, 32, F); _DEFPIN_AVR(21, 16, F); _DEFPIN_AVR(22, 2, F); _DEFPIN_AVR(23, 0, F); #define SPI_DATA 16 #define SPI_CLOCK 15 @@ -196,4 +203,6 @@ _DEFPIN_AVR(20, 32, F); _DEFPIN_AVR(21, 16, F); _DEFPIN_AVR(22, 2, F); _DEFPIN_A #endif -#endif +#endif // FORCE_SOFTWARE_PINS + +#endif // __INC_FASTPIN_AVR_H diff --git a/fastspi_avr.h b/platforms/avr/fastspi_avr.h index 6470f37d..6470f37d 100644 --- a/fastspi_avr.h +++ b/platforms/avr/fastspi_avr.h diff --git a/platforms/avr/led_sysdefs_avr.h b/platforms/avr/led_sysdefs_avr.h new file mode 100644 index 00000000..19cfabee --- /dev/null +++ b/platforms/avr/led_sysdefs_avr.h @@ -0,0 +1,21 @@ +#ifndef __INC_LED_SYSDEFS_AVR_H +#define __INC_LED_SYSDEFS_AVR_H + +#define FASTLED_AVR +#define FASTLED_ACCURATE_CLOCK + +#ifndef INTERRUPT_THRESHOLD +#define INTERRUPT_THRESHOLD 2 +#endif + +#include <avr/io.h> +#include <avr/interrupt.h> // for cli/se definitions + +// Define the rgister 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) */ +#endif + + +#endif diff --git a/preview_changes.txt b/preview_changes.txt index 84407524..e69dd3cb 100644 --- a/preview_changes.txt +++ b/preview_changes.txt @@ -6,4 +6,4 @@ FastLED 3.1 preview changes: * interrupt friendly code on teensy 3/3.1 * interrupt friendly code on AVR * interrupt friendly code on the due - +* code re-org for future wider platform support @@ -1,6 +1,7 @@ #include "FastLED.h" -#ifdef FASTLED_AVR + +#if defined(FASTLED_AVR) && !defined(TEENSYDUINO) && !defined(LIB8_ATTINY) extern "C" { // the prescaler is set so that timer0 ticks every 64 clock cycles, and the // the overflow handler is called every 256 ticks. |