| 1 | // This is a mash-up of the Due show() code + insights from Michael Miller's |
| 2 | // ESP8266 work for the NeoPixelBus library: github.com/Makuna/NeoPixelBus |
| 3 | // Needs to be a separate .c file to enforce ICACHE_RAM_ATTR execution. |
| 4 | #if defined(K210) |
| 5 | #define KENDRYTE_K210 1 |
| 6 | #endif |
| 7 | |
| 8 | #if defined(KENDRYTE_K210) |
| 9 | |
| 10 | #include "sysctl.h" |
| 11 | #include <Arduino.h> |
| 12 | |
| 13 | void k210Show(uint8_t pin, uint8_t *pixels, uint32_t numBytes, |
| 14 | boolean is800KHz) { |
| 15 | |
| 16 | #define CYCLES_800_T0H \ |
| 17 | (sysctl_clock_get_freq(SYSCTL_CLOCK_CPU) / 2500000) // 0.4us |
| 18 | #define CYCLES_800_T1H \ |
| 19 | (sysctl_clock_get_freq(SYSCTL_CLOCK_CPU) / 1250000) // 0.8us |
| 20 | #define CYCLES_800 \ |
| 21 | (sysctl_clock_get_freq(SYSCTL_CLOCK_CPU) / 800000) // 1.25us per bit |
| 22 | #define CYCLES_400_T0H \ |
| 23 | (sysctl_clock_get_freq(SYSCTL_CLOCK_CPU) / 2000000) // 0.5uS |
| 24 | #define CYCLES_400_T1H \ |
| 25 | (sysctl_clock_get_freq(SYSCTL_CLOCK_CPU) / 833333) // 1.2us |
| 26 | #define CYCLES_400 \ |
| 27 | (sysctl_clock_get_freq(SYSCTL_CLOCK_CPU) / 400000) // 2.5us per bit |
| 28 | |
| 29 | uint8_t *p, *end, pix, mask; |
| 30 | uint32_t t, time0, time1, period, c, startTime; |
| 31 | |
| 32 | p = pixels; |
| 33 | end = p + numBytes; |
| 34 | pix = *p++; |
| 35 | mask = 0x80; |
| 36 | startTime = 0; |
| 37 | |
| 38 | #ifdef NEO_KHZ400 |
| 39 | if (is800KHz) { |
| 40 | #endif |
| 41 | time0 = CYCLES_800_T0H; |
| 42 | time1 = CYCLES_800_T1H; |
| 43 | period = CYCLES_800; |
| 44 | #ifdef NEO_KHZ400 |
| 45 | } else { // 400 KHz bitstream |
| 46 | time0 = CYCLES_400_T0H; |
| 47 | time1 = CYCLES_400_T1H; |
| 48 | period = CYCLES_400; |
| 49 | } |
| 50 | #endif |
| 51 | |
| 52 | for (t = time0;; t = time0) { |
| 53 | if (pix & mask) |
| 54 | t = time1; // Bit high duration |
| 55 | while (((c = read_cycle()) - startTime) < period) |
| 56 | ; // Wait for bit start |
| 57 | digitalWrite(pin, HIGH); |
| 58 | startTime = c; // Save start time |
| 59 | while (((c = read_cycle()) - startTime) < t) |
| 60 | ; // Wait high duration |
| 61 | digitalWrite(pin, LOW); |
| 62 | |
| 63 | if (!(mask >>= 1)) { // Next bit/byte |
| 64 | if (p >= end) |
| 65 | break; |
| 66 | pix = *p++; |
| 67 | mask = 0x80; |
| 68 | } |
| 69 | } |
| 70 | while ((read_cycle() - startTime) < period) |
| 71 | ; // Wait for last bit |
| 72 | } |
| 73 | |
| 74 | #endif // KENDRYTE_K210 |