diff options
author | danielgarcia@gmail.com <danielgarcia@gmail.com@4ad4ec5c-605d-bd5c-5796-512c9b60011b> | 2013-06-19 10:35:20 +0400 |
---|---|---|
committer | danielgarcia@gmail.com <danielgarcia@gmail.com@4ad4ec5c-605d-bd5c-5796-512c9b60011b> | 2013-06-19 10:35:20 +0400 |
commit | ae8c92019f7fda09df0522ee35dad8be7e58d181 (patch) | |
tree | dc2602844e17c56440761f10211a44d4355cae0d | |
parent | 1bd88e84936470887f60c1927a2bbc32e6c76eed (diff) |
Preliminary support for due - only tested with clockless chips at the moment. If the SPI chipsets work, they will be using bit bang'd output.
-rw-r--r-- | FastSPI_LED2.cpp | 3 | ||||
-rw-r--r-- | clockless.h | 11 | ||||
-rw-r--r-- | clockless2.h | 265 | ||||
-rw-r--r-- | controller.h | 2 | ||||
-rw-r--r-- | delay.h | 5 | ||||
-rw-r--r-- | examples/Fast2Dev/Fast2Dev.ino | 9 | ||||
-rw-r--r-- | fastpin.h | 96 | ||||
-rw-r--r-- | led_sysdefs.h | 30 |
8 files changed, 393 insertions, 28 deletions
diff --git a/FastSPI_LED2.cpp b/FastSPI_LED2.cpp index b8e46e4d..34849fa1 100644 --- a/FastSPI_LED2.cpp +++ b/FastSPI_LED2.cpp @@ -1,5 +1,8 @@ #include "FastSPI_LED2.h" +#if defined(__SAM3X8E__) +volatile uint32_t fuckit; +#endif CFastSPI_LED2 LEDS; CFastSPI_LED2 & FastSPI_LED = LEDS; diff --git a/clockless.h b/clockless.h index b7f8a0fe..2bd449bc 100644 --- a/clockless.h +++ b/clockless.h @@ -3,7 +3,7 @@ #include "controller.h" #include "lib8tion.h" -#include <avr/interrupt.h> // for cli/se definitions +#include "led_sysdefs.h" // Macro to convert from nano-seconds to clocks and clocks to nano-seconds // #define NS(_NS) (_NS / (1000 / (F_CPU / 1000000L))) @@ -21,6 +21,9 @@ #if defined(__MK20DX128__) extern volatile uint32_t systick_millis_count; # define MS_COUNTER systick_millis_count +#elif defined(__SAM3X8E__) + extern volatile uint32_t fuckit; +# define MS_COUNTER fuckit #else # if defined(CORE_TEENSY) extern volatile unsigned long timer0_millis_count; @@ -58,9 +61,7 @@ public: mPort = FastPin<DATA_PIN>::port(); } -#if defined(__MK20DX128__) - // We don't use the bitSetFast methods for ARM. -#else +#if defined(FASTLED_AVR) template <int N>inline static void bitSetFast(register data_ptr_t port, register data_t hi, register data_t lo, register uint8_t b) { // First cycle SET_HI; // 1/2 clock cycle if using out @@ -152,7 +153,7 @@ public: register data_t lo = *port & ~mask; *port = lo; -#if defined(__MK20DX128__) +#if defined(FASTLED_ARM) register uint32_t b; if(ADVANCE) { b = data[SKIP + RGB_BYTE0(RGB_ORDER)]; diff --git a/clockless2.h b/clockless2.h new file mode 100644 index 00000000..e6823447 --- /dev/null +++ b/clockless2.h @@ -0,0 +1,265 @@ +#ifndef __INC_CLOCKLESS2_H +#define __INC_CLOCKLESS2_H + +#include "controller.h" +#include "lib8tion.h" +#include "led_sysdefs.h" + +// Macro to convert from nano-seconds to clocks and clocks to nano-seconds +// #define NS(_NS) (_NS / (1000 / (F_CPU / 1000000L))) +#if F_CPU < 96000000 +#define NS(_NS) ( (_NS * (F_CPU / 1000000L))) / 1000 +#define CLKS_TO_MICROS(_CLKS) _CLKS / (F_CPU / 1000000L) +#else +#define NS(_NS) ( (_NS * (F_CPU / 2000000L))) / 1000 +#define CLKS_TO_MICROS(_CLKS) _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) + +#if defined(__MK20DX128__) + extern volatile uint32_t systick_millis_count; +# define MS_COUNTER systick_millis_count +#else +# if defined(CORE_TEENSY) + extern volatile unsigned long timer0_millis_count; +# define MS_COUNTER timer0_millis_count +# else + extern volatile unsigned long timer0_millis; +# define MS_COUNTER timer0_millis +# endif +#endif + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// +// 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 SET2_LO FLIP ? FastPin<DATA_PIN>::hi() : FastPin<DATA_PIN>::lo() +#define SET2_HI FLIP ? FastPin<DATA_PIN>::lo() : FastPin<DATA_PIN>::hi() + +#define SET2_LO2 FLIP ? FastPin<DATA_PIN2>::hi() : FastPin<DATA_PIN2>::lo() +#define SET2_HI2 FLIP ? FastPin<DATA_PIN2>::lo() : FastPin<DATA_PIN2>::hi() + + +template <uint8_t DATA_PIN, uint8_t DATA_PIN2, int T1, int T2, int T3, EOrder RGB_ORDER = RGB, bool FLIP = false, int WAIT_TIME = 50> +class ClocklessController2 : public CLEDController { + typedef typename FastPin<DATA_PIN>::port_ptr_t data_ptr_t; + typedef typename FastPin<DATA_PIN>::port_t data_t; + + CMinWait<WAIT_TIME> mWait; +public: + virtual void init() { + FastPin<DATA_PIN>::setOutput(); + FastPin<DATA_PIN2>::setOutput(); + } + + + virtual void clearLeds(int nLeds) { + showColor(CRGB(0, 0, 0), nLeds, 0); + } + + // set all the leds on the controller to a given color + virtual void showColor(const struct CRGB & data, int nLeds, uint8_t scale = 255) { + mWait.wait(); + cli(); + + showRGBInternal<0, false>(nLeds, scale, (const byte*)&data, (const byte*)&data); + + // Adjust the timer + long microsTaken = CLKS_TO_MICROS(nLeds * 8 * (T1 + T2 + T3)); + MS_COUNTER += (microsTaken / 1000); + sei(); + mWait.mark(); + } + + virtual void show(const struct CRGB *rgbdata, int nLeds, uint8_t scale = 255) { + mWait.wait(); + cli(); + + showRGBInternal<0, true>(nLeds, scale, (const byte*)rgbdata, (const byte*)rgbdata); + + // Adjust the timer + long microsTaken = CLKS_TO_MICROS(nLeds * 8 * (T1 + T2 + T3)); + MS_COUNTER += (microsTaken / 1000); + sei(); + mWait.mark(); + } + + virtual void show(const struct CRGB *rgbdata, const struct CRGB *rgbdata2, int nLeds, uint8_t scale = 255) { + mWait.wait(); + cli(); + + showRGBInternal<0, true>(nLeds, scale, (const byte*)rgbdata, (const byte*)rgbdata2 ); + + // Adjust the timer + long microsTaken = CLKS_TO_MICROS(nLeds * 8 * (T1 + T2 + T3)); + MS_COUNTER += (microsTaken / 1000); + sei(); + mWait.mark(); + } + +#ifdef SUPPORT_ARGB + virtual void show(const struct CARGB *rgbdata, int nLeds, uint8_t scale = 255) { + mWait.wait(); + cli(); + + showRGBInternal<1, true>(nLeds, scale, (const byte*)rgbdata); + + // Adjust the timer + long microsTaken = CLKS_TO_MICROS(nLeds * 8 * (T1 + T2 + T3)); + MS_COUNTER += (microsTaken / 1000); + sei(); + mWait.mark(); + } +#endif + + // This method is made static to force making register Y available to use for data on AVR - if the method is non-static, then + // gcc will use register Y for the this pointer. + template<int SKIP, bool ADVANCE> static void showRGBInternal(register int nLeds, register uint8_t scale, register const byte *rgbdata, register const byte *rgbdata2) { + register byte *data = (byte*)rgbdata; + register byte *data2 = (byte*)rgbdata2; + + nLeds *= (3 + SKIP); + register uint8_t *end = data + nLeds; + +#if defined(__MK20DX128__) + register uint32_t b; + register uint32_t c; + if(ADVANCE) { + b = data[SKIP + RGB_BYTE0(RGB_ORDER)]; + c = data2[SKIP + RGB_BYTE0(RGB_ORDER)]; + } else { + b = rgbdata[SKIP + RGB_BYTE0(RGB_ORDER)]; + c = rgbdata2[SKIP + RGB_BYTE0(RGB_ORDER)]; + } + b = scale8(b, scale); + c = scale8(c, scale); + + while(data < end) { + // TODO: hand rig asm version of this method. The timings are based on adjusting/studying GCC compiler ouptut. This + // will bite me in the ass at some point, I know it. + for(register uint32_t i = 7; i > 0; i--) { + SET2_HI; delaycycles<3>(); SET2_HI2; + delaycycles<T1 - 6>(); // 6 cycles - 1/1 store, 1/1 test, 1/1 if, 1/1 port lookup + if(b & 0x80) { SET2_HI; } else { SET2_LO; } + if(c & 0x80) { SET2_HI2; } else { SET2_LO2; } + b <<= 1; c <<=1; + delaycycles<T2 - 8>(); // 3 cycles, 1/1 store, 1/1 store/skip, 1/1 shift , 1/1 port lookup + SET2_LO; SET2_LO2; + delaycycles<T3 - 6>(); // 4 cycles, 1/1 store, 1 sub, 1 branch backwards, 1/1 port lookup + } + // extra delay because branch is faster falling through + delaycycles<1>(); + + // 8th bit, interleave loading rest of data + SET2_HI; delaycycles<3>(); SET2_HI2; + delaycycles<T1 - 6>(); + if(b & 0x80) { SET2_HI; } else { SET2_LO; } + if(c & 0x80) { SET2_HI2; } else { SET2_LO2; } + delaycycles<T2 - 6>(); // 4 cycles, 2/2 store, 1/1 store/skip, 1/1 port lookup + SET2_LO; SET2_LO2; + + if(ADVANCE) { + b = data[SKIP + RGB_BYTE1(RGB_ORDER)]; + c = data2[SKIP + RGB_BYTE1(RGB_ORDER)]; + } else { + b = rgbdata[SKIP + RGB_BYTE1(RGB_ORDER)]; + c = rgbdata2[SKIP + RGB_BYTE1(RGB_ORDER)]; + } + b = scale8(b, scale); + c = scale8(c, scale); + + delaycycles<T3 - 12>(); // 1/1 store, 2/2 load, 1/1 mul, 1/1 shift, , 1/1 port lookup + + for(register uint32_t i = 7; i > 0; i--) { + SET2_HI; delaycycles<3>(); SET2_HI2; + delaycycles<T1 - 6>(); // 3 cycles - 1 store, 1 test, 1 if + if(b & 0x80) { SET2_HI; } else { SET2_LO; } + if(c & 0x80) { SET2_HI2; } else { SET2_LO2; } + b <<= 1; c <<= 1; + delaycycles<T2 - 8>(); // 6 cycles, 1/1 store, 1/1 store/skip, 1/1 shift , 1/1 port lookup + SET2_LO; SET2_LO2; + delaycycles<T3 - 6>(); // 4 cycles, 1/1 store, 1 sub, 1 branch backwards, 1/1 port lookup + } + // extra delay because branch is faster falling through + delaycycles<1>(); + + // 8th bit, interleave loading rest of data + SET2_HI; delaycycles<3>(); SET2_HI2; + delaycycles<T1 - 6>(); + if(b & 0x80) { SET2_HI; } else { SET2_LO; } + if(b & 0x80) { SET2_HI2; } else { SET2_LO2; } + delaycycles<T2 - 6>(); // 4 cycles, 2 store, store/skip, 1/1 port lookup + SET2_LO; SET2_LO2; + + if(ADVANCE) { + b = data[SKIP + RGB_BYTE2(RGB_ORDER)]; + c = data2[SKIP + RGB_BYTE2(RGB_ORDER)]; + } else { + b = rgbdata[SKIP + RGB_BYTE2(RGB_ORDER)]; + c = rgbdata2[SKIP + RGB_BYTE2(RGB_ORDER)]; + } + b = scale8(b, scale); + c = scale8(c, scale); + + data += 3 + SKIP; data2 += 3 + SKIP; + if((RGB_ORDER & 0070) == 0) { + delaycycles<T3 - 14>(); // 1/1 store, 2/2 load, 1/1 mul, 1/1 shift, 1/1 adds if BRG or GRB, 1/1 port lookup + } else { + delaycycles<T3 - 12>(); // 1/1 store, 2/2 load, 1/1 mul, 1/1 shift, , 1/1 port lookup + } + + for(register uint32_t i = 7; i > 0; i--) { + SET2_HI; delaycycles<3>(); SET2_HI2; + delaycycles<T1 - 6>(); // 3 cycles - 1 store, 1 test, 1 if + if(b & 0x80) { SET2_HI; } else { SET2_LO; } + if(c & 0x80) { SET2_HI2; } else { SET2_LO2; } + b <<= 1; c <<= 1; + delaycycles<T2 - 8>(); // 3 cycles, 1 store, 1 store/skip, 1 shift , 1/1 port lookup + SET2_LO; SET2_LO2; + delaycycles<T3 - 6>(); // 3 cycles, 1/1 store, 1 sub, 1 branch backwards, 1/1 port lookup + } + // extra delay because branch is faster falling through + delaycycles<1>(); + + // 8th bit, interleave loading rest of data + SET2_HI; delaycycles<3>(); SET2_HI2; + delaycycles<T1 - 6>(); + if(b & 0x80) { SET2_HI; } else { SET2_LO; } + if(c & 0x80) { SET2_HI2; } else { SET2_LO2; } + delaycycles<T2 - 6>(); // 4 cycles, 2/2 store, store/skip, 1/1 port lookup + SET2_LO; SET2_LO2; + + if(ADVANCE) { + b = data[SKIP + RGB_BYTE0(RGB_ORDER)]; + c = data2[SKIP + RGB_BYTE0(RGB_ORDER)]; + } else { + b = rgbdata[SKIP + RGB_BYTE0(RGB_ORDER)]; + c = rgbdata2[SKIP + RGB_BYTE0(RGB_ORDER)]; + } + b = scale8(b, scale); + c = scale8(c, scale); + delaycycles<T3 - 15>(); // 1/1 store, 2/2 load (with increment), 1/1 mul, 1/1 shift, 1 cmp, 1 branch backwards, 1 movim, 1/1 port lookup + }; +#endif + } + +#ifdef SUPPORT_ARGB + virtual void showARGB(struct CARGB *data, int nLeds) { + // TODO: IMPLEMENTME + } +#endif +}; + +#undef SET2_HI +#undef SET2_HI2 +#undef SET2_LO +#undef SET2_LO2 + +#endif
\ No newline at end of file diff --git a/controller.h b/controller.h index 2c703f00..dd07130a 100644 --- a/controller.h +++ b/controller.h @@ -1,7 +1,7 @@ #ifndef __INC_CONTROLLER_H #define __INC_CONTROLLER_H -#include <avr/io.h> +#include "led_sysdefs.h" #include "pixeltypes.h" @@ -17,6 +17,9 @@ 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>(); @@ -33,8 +36,6 @@ template<int LOOP, int PAD> inline void _delaycycles_AVR() { ); } -// usable definition -#if !defined(__MK20DX128__) template<int CYCLES> __attribute__((always_inline)) inline void delaycycles() { _delaycycles_AVR<CYCLES / 3, CYCLES % 3>(); } diff --git a/examples/Fast2Dev/Fast2Dev.ino b/examples/Fast2Dev/Fast2Dev.ino index 52ee867d..e8dd6742 100644 --- a/examples/Fast2Dev/Fast2Dev.ino +++ b/examples/Fast2Dev/Fast2Dev.ino @@ -16,7 +16,7 @@ // ////////////////////////////////////////////////// -#define NUM_LEDS 15 +#define NUM_LEDS 256 CRGB leds[NUM_LEDS]; @@ -28,8 +28,8 @@ void setup() { // setting brightness to 25% brightness LEDS.setBrightness(64); - // LEDS.addLeds<WS2811, 13>(leds, NUM_LEDS); - LEDS.addLeds<TM1809, 13>(leds, NUM_LEDS); + LEDS.addLeds<WS2811, 13, BRG>(leds, NUM_LEDS); + // LEDS.addLeds<TM1809, 13, BRG>(leds, NUM_LEDS); // LEDS.addLeds<UCS1903, 13>(leds, NUM_LEDS); // LEDS.addLeds<TM1803, 13>(leds, NUM_LEDS); // LEDS.addLeds<TM1829, 13>(leds, NUM_LEDS); @@ -75,6 +75,9 @@ void loop() { delay(10); } + // leave the last pixel lit for a bit + delay(2000); + // fade up for(int x = 0; x < 128; x++) { // The showColor method sets all the leds in the strip to the same color @@ -1,10 +1,7 @@ #ifndef __INC_FASTPIN_H #define __INC_FASTPIN_H -#include<avr/io.h> - -// Arduino.h needed for convinience functions digitalPinToPort/BitMask/portOutputRegister and the pinMode methods. -#include<Arduino.h> +#include "led_sysdefs.h" #define NO_PIN 255 @@ -41,10 +38,10 @@ public: }; class Pin : public Selectable { - uint8_t mPinMask; + RwReg mPinMask; uint8_t mPin; - volatile uint8_t *mPort; - volatile uint8_t *mInPort; + volatile RwReg *mPort; + volatile RoReg *mInPort; void _init() { mPinMask = digitalPinToBitMask(mPin); @@ -54,8 +51,8 @@ class Pin : public Selectable { public: Pin(int pin) : mPin(pin) { _init(); } - typedef volatile uint8_t * port_ptr_t; - typedef uint8_t port_t; + typedef volatile RwReg * port_ptr_t; + typedef RwReg port_t; inline void setOutput() { pinMode(mPin, OUTPUT); } inline void setInput() { pinMode(mPin, INPUT); } @@ -107,17 +104,17 @@ public: /// 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 { - static uint8_t sPinMask; - static volatile uint8_t *sPort; - static volatile uint8_t *sInPort; + static RwReg sPinMask; + static volatile RwReg *sPort; + static volatile RoReg *sInPort; static void _init() { sPinMask = digitalPinToBitMask(PIN); sPort = portOutputRegister(digitalPinToPort(PIN)); sInPort = portInputRegister(digitalPinToPort(PIN)); } public: - typedef volatile uint8_t * port_ptr_t; - typedef uint8_t port_t; + typedef volatile RwReg * port_ptr_t; + typedef RwReg port_t; inline static void setOutput() { _init(); pinMode(PIN, OUTPUT); } inline static void setInput() { _init(); pinMode(PIN, INPUT); } @@ -141,8 +138,9 @@ public: static port_t mask() __attribute__ ((always_inline)) { return sPinMask; } }; -template<uint8_t PIN> uint8_t FastPin<PIN>::sPinMask; -template<uint8_t PIN> volatile uint8_t *FastPin<PIN>::sPort; +template<uint8_t PIN> RwReg FastPin<PIN>::sPinMask; +template<uint8_t PIN> volatile RwReg *FastPin<PIN>::sPort; +template<uint8_t PIN> volatile RoReg *FastPin<PIN>::sInPort; /// 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. @@ -172,9 +170,40 @@ public: inline static port_t mask() __attribute__ ((always_inline)) { return _MASK; } }; +/// 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 { +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)) { _PSOR::r() = _MASK; } + inline static void lo() __attribute__ ((always_inline)) { _PCOR::r() = _MASK; } + 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(); } + inline static void lo(register port_ptr_t port) __attribute__ ((always_inline)) { lo(); } + inline static void fastset(register port_ptr_t port, register port_t val) __attribute__ ((always_inline)) { *port = val; } + + inline static port_t hival() __attribute__ ((always_inline)) { return _PDOR::r() | _MASK; } + inline static port_t loval() __attribute__ ((always_inline)) { return _PDOR::r() & ~_MASK; } + inline static port_ptr_t port() __attribute__ ((always_inline)) { return &_PDOR::r(); } + inline static port_t mask() __attribute__ ((always_inline)) { return _MASK; } +}; + /// 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. +/// The registers are data output, set output, clear output, toggle output, input, and direction template<uint8_t PIN, uint32_t _MASK, typename _PDOR, typename _PSOR, typename _PCOR, typename _PTOR, typename _PDIR, typename _PDDR> class _ARMPIN { public: typedef volatile uint32_t * port_ptr_t; @@ -249,8 +278,12 @@ typedef volatile uint32_t * ptr_reg32_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); -#define USE_BITBAND 1 +#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 USE_BITBAND 0 #if USE_BITBAND == 0 + #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)> {}; #define _DEFPIN_ARM(PIN, BIT, L) template<> class FastPin<PIN> : public _ARMPIN<PIN, 1 << BIT, _R(GPIO ## L ## _PDOR), _R(GPIO ## L ## _PSOR), _R(GPIO ## L ## _PCOR), \ _R(GPIO ## L ## _PTOR), _R(GPIO ## L ## _PDIR), _R(GPIO ## L ## _PDDR)> {}; #else @@ -382,6 +415,35 @@ _DEFPIN_ARM(32, 18, B); _DEFPIN_ARM(33, 4, A); #define SPI_DATA 11 #define SPI_CLOCK 13 #define ARM_HARDWARE_SPI + +#elif defined(__SAM3X8E__) + +DUE_IO32(A); +DUE_IO32(B); +DUE_IO32(C); +DUE_IO32(D); + +_DEFPIN_DUE(0, 8, A); _DEFPIN_DUE(1, 9, A); _DEFPIN_DUE(2, 25, B); _DEFPIN_DUE(3, 28, C); +_DEFPIN_DUE(4, 29, A); _DEFPIN_DUE(5, 25, C); _DEFPIN_DUE(6, 24, C); _DEFPIN_DUE(7, 23, C); +_DEFPIN_DUE(8, 22, C); _DEFPIN_DUE(9, 21, C); _DEFPIN_DUE(10, 28, A); _DEFPIN_DUE(11, 7, D); +_DEFPIN_DUE(12, 8, D); _DEFPIN_DUE(13, 27, B); _DEFPIN_DUE(14, 4, D); _DEFPIN_DUE(15, 5, D); +_DEFPIN_DUE(16, 13, A); _DEFPIN_DUE(17, 12, A); _DEFPIN_DUE(18, 11, A); _DEFPIN_DUE(19, 10, A); +_DEFPIN_DUE(20, 12, B); _DEFPIN_DUE(21, 13, B); _DEFPIN_DUE(22, 26, B); _DEFPIN_DUE(23, 14, A); +_DEFPIN_DUE(24, 15, A); _DEFPIN_DUE(25, 0, D); _DEFPIN_DUE(26, 1, D); _DEFPIN_DUE(27, 2, D); +_DEFPIN_DUE(28, 3, D); _DEFPIN_DUE(29, 6, D); _DEFPIN_DUE(30, 9, D); _DEFPIN_DUE(31, 7, A); +_DEFPIN_DUE(32, 10, D); _DEFPIN_DUE(33, 1, C); _DEFPIN_DUE(34, 2, C); _DEFPIN_DUE(35, 3, C); +_DEFPIN_DUE(36, 4, C); _DEFPIN_DUE(37, 5, C); _DEFPIN_DUE(38, 6, C); _DEFPIN_DUE(39, 7, C); +_DEFPIN_DUE(40, 8, C); _DEFPIN_DUE(41, 9, C); _DEFPIN_DUE(42, 19, A); _DEFPIN_DUE(43, 20, A); +_DEFPIN_DUE(44, 19, C); _DEFPIN_DUE(45, 18, C); _DEFPIN_DUE(46, 17, C); _DEFPIN_DUE(47, 16, C); +_DEFPIN_DUE(48, 15, C); _DEFPIN_DUE(49, 14, C); _DEFPIN_DUE(50, 13, C); _DEFPIN_DUE(51, 12, C); +_DEFPIN_DUE(52, 21, B); _DEFPIN_DUE(53, 14, B); _DEFPIN_DUE(54, 16, A); _DEFPIN_DUE(55, 24, A); +_DEFPIN_DUE(56, 23, A); _DEFPIN_DUE(57, 22, A); _DEFPIN_DUE(58, 6, A); _DEFPIN_DUE(59, 4, A); +_DEFPIN_DUE(60, 3, A); _DEFPIN_DUE(61, 2, A); _DEFPIN_DUE(62, 17, B); _DEFPIN_DUE(63, 18, B); +_DEFPIN_DUE(64, 19, B); _DEFPIN_DUE(65, 20, B); _DEFPIN_DUE(66, 15, B); _DEFPIN_DUE(67, 16, B); +_DEFPIN_DUE(68, 1, A); _DEFPIN_DUE(69, 0, A); _DEFPIN_DUE(70, 17, A); _DEFPIN_DUE(71, 18, A); +_DEFPIN_DUE(72, 30, C); _DEFPIN_DUE(73, 21, A); _DEFPIN_DUE(74, 25, A); _DEFPIN_DUE(75, 26, A); +_DEFPIN_DUE(76, 27, A); _DEFPIN_DUE(77, 28, A); _DEFPIN_DUE(78, 23, B); + #else #warning "No pin/port mappings found, pin access will be slightly slower. See fastpin.h for info." diff --git a/led_sysdefs.h b/led_sysdefs.h new file mode 100644 index 00000000..83fe3122 --- /dev/null +++ b/led_sysdefs.h @@ -0,0 +1,30 @@ +#ifndef __INC_LED_SYSDEFS_H +#define __INC_LED_SYSDEFS_H + +#ifndef __SAM3X8E__ +#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() +#define sei() __enable_irq() + +#endif + +#if defined(__MK20DX128__) || defined(__SAM3X8E__) +#define FASTLED_ARM +#else +#define FASTLED_AVR +#endif + +// Arduino.h needed for convinience functions digitalPinToPort/BitMask/portOutputRegister and the pinMode methods. +#include<Arduino.h> + +#endif
\ No newline at end of file |