diff options
author | danielgarcia@gmail.com <danielgarcia@gmail.com@4ad4ec5c-605d-bd5c-5796-512c9b60011b> | 2013-10-08 14:09:27 +0400 |
---|---|---|
committer | danielgarcia@gmail.com <danielgarcia@gmail.com@4ad4ec5c-605d-bd5c-5796-512c9b60011b> | 2013-10-08 14:09:27 +0400 |
commit | c780742d0f1071f7e6f5e3218eb6bd2b540c2c0f (patch) | |
tree | c35f883134d0f5b698733610184e0607c72e436d | |
parent | b121c4ae03eaa001829b77aa19e28ce49499e6ff (diff) |
Tweak AVR timings - still not fully hand done asm - but unlikely to get to that for 2.0, more likely 2.1. Also fix cycle defs for arduino mega pins.
-rw-r--r-- | chipsets.h | 10 | ||||
-rw-r--r-- | clockless.h | 21 | ||||
-rw-r--r-- | fastpin.h | 4 | ||||
-rw-r--r-- | preview_changes.txt | 1 |
4 files changed, 28 insertions, 8 deletions
@@ -242,11 +242,19 @@ class TM1809Controller800Khz : public ClocklessController<DATA_PIN, NS(350), NS( #warning "No enough clock cycles available for the UCS103" #endif -// WS2811 - 350n, 350ns, 550ns +// WS2811 - 400ns, 400ns, 450ns (n.b. the teensy3 defs down below are vestigal, and the teensy 3 timings should be fixed/cleaned up) +#if !defined(__MK20DX128__) +template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB> +class WS2811Controller800Mhz : public ClocklessController<DATA_PIN, NS(400), NS(400), NS(450), RGB_ORDER> {}; +template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB> +class WS2811Controller800Khz : public ClocklessController<DATA_PIN, NS(400), NS(400), NS(450), RGB_ORDER> {}; +#else template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB> class WS2811Controller800Mhz : public ClocklessController<DATA_PIN, NS(320), NS(320), NS(550), RGB_ORDER> {}; template <uint8_t DATA_PIN, EOrder RGB_ORDER = RGB> class WS2811Controller800Khz : public ClocklessController<DATA_PIN, NS(320), NS(320), NS(550), RGB_ORDER> {}; +#endif + #if NO_TIME(320, 320, 550) #warning "No enough clock cycles available for the UCS103" #endif diff --git a/clockless.h b/clockless.h index f2aec88e..eb3cb072 100644 --- a/clockless.h +++ b/clockless.h @@ -77,12 +77,12 @@ public: template <int N, int ADJ>inline static void bitSetLast(register data_ptr_t port, register data_t hi, register data_t lo, register uint8_t b) { // First cycle FastPin<DATA_PIN>::fastset(port, hi); // 1 clock cycle if using out, 2 otherwise - delaycycles<T1 - (_CYCLES(DATA_PIN) + 1)>(); // 1st cycle length minus 1 clock for out, 1 clock for sbrs + delaycycles<T1 - (_CYCLES(DATA_PIN))>(); // 1st cycle length minus 1 clock for out, 1 clock for sbrs __asm__ __volatile__ ("sbrs %0, %1" :: "r" (b), "M" (N) :); // 1 clock for check (+1 if skipping, next op is also 1 clock) // Second cycle FastPin<DATA_PIN>::fastset(port, lo); // 1/2 clock cycle if using out - delaycycles<T2 - _CYCLES(DATA_PIN)>(); // 2nd cycle length minus 1/2 clock for out + delaycycles<T2 - (_CYCLES(DATA_PIN))>(); // 2nd cycle length minus 1/2 clock for out // Third cycle FastPin<DATA_PIN>::fastset(port, lo); // 1/2 clock cycle if using out @@ -285,13 +285,16 @@ public: } delaycycles<1>(); // Leave an extra 2 clocks for the next byte load - bitSetLast<7, 0>(port, hi, lo, b); + bitSetLast<7, 1>(port, hi, lo, b); + delaycycles<1>(); + // Leave an extra 4 clocks for the scale - bitSetLast<6, 5>(port, hi, lo, b); + bitSetLast<6, 6>(port, hi, lo, b); if(ADVANCE) { c = data[SKIP + RGB_BYTE1(RGB_ORDER)]; } else { c = rgbdata[SKIP + RGB_BYTE1(RGB_ORDER)]; + delaycycles<1>(); } c = scale8_LEAVING_R1_DIRTY(c, scale); bitSetLast<5, 1>(port, hi, lo, b); @@ -302,13 +305,16 @@ public: } delaycycles<1>(); // Leave an extra 2 clocks for the next byte load - bitSetLast<7, 0>(port, hi, lo, c); + bitSetLast<7, 1>(port, hi, lo, c); + delaycycles<1>(); + // Leave an extra 4 clocks for the scale - bitSetLast<6, 5>(port, hi, lo, c); + bitSetLast<6, 6>(port, hi, lo, c); if(ADVANCE) { d = data[SKIP + RGB_BYTE2(RGB_ORDER)]; } else { d = rgbdata[SKIP + RGB_BYTE2(RGB_ORDER)]; + delaycycles<1>(); } d = scale8_LEAVING_R1_DIRTY(d, scale); bitSetLast<5, 1>(port, hi, lo, c); @@ -322,11 +328,12 @@ public: bitSetLast<7, 2>(port, hi, lo, d); data += (SKIP + 3); // Leave an extra 4 clocks for the scale - bitSetLast<6, 5>(port, hi, lo, d); + bitSetLast<6, 6>(port, hi, lo, d); if(ADVANCE) { b = data[SKIP + RGB_BYTE0(RGB_ORDER)]; } else { b = rgbdata[SKIP + RGB_BYTE0(RGB_ORDER)]; + delaycycles<1>(); } b = scale8_LEAVING_R1_DIRTY(b, scale); bitSetLast<5, 6>(port, hi, lo, d); @@ -31,7 +31,11 @@ public: // ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) +#define _CYCLES(_PIN) (((_PIN >= 62 ) || (_PIN>=42 && _PIN<=49) || (_PIN>=14 && _PIN <=17) || (_PIN>=6 && _PIN <=9)) ? 2 : 1) +#else #define _CYCLES(_PIN) ((_PIN >= 24) ? 2 : 1) +#endif class Selectable { public: diff --git a/preview_changes.txt b/preview_changes.txt index ccf4bafc..7a071587 100644 --- a/preview_changes.txt +++ b/preview_changes.txt @@ -1,5 +1,6 @@ (Post RC3) * Added NEOPIXEL as a synonym for WS2811 +* Fix WS2811/WS2812B timings, bring it in line to exactly 1.25ns/bit. Release Candidate 3 * Fixed bug when Clock and Data were on the same port |