Krolyxon
Commit 3120783

Branches

Tags

Refs →

orion-rf.piolibdepsesp32-s3-n16r8Adafruit NeoPixelesp8266.c

91 lines · 2.5 KB · C

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
5#if defined(ESP8266)
6
7#include <Arduino.h>
8#ifdef ESP8266
9#include <eagle_soc.h>
10#endif
11
12static uint32_t _getCycleCount(void) __attribute__((always_inline));
13static inline uint32_t _getCycleCount(void) {
14 uint32_t ccount;
15 __asm__ __volatile__("rsr %0,ccount" : "=a"(ccount));
16 return ccount;
17}
18
19#ifdef ESP8266
20IRAM_ATTR void espShow(uint8_t pin, uint8_t *pixels, uint32_t numBytes,
21 __attribute__((unused)) boolean is800KHz) {
22#else
23void espShow(uint8_t pin, uint8_t *pixels, uint32_t numBytes,
24 boolean is800KHz) {
25#endif
26
27#define CYCLES_800_T0H (F_CPU / 2500001) // 0.4us
28#define CYCLES_800_T1H (F_CPU / 1250001) // 0.8us
29#define CYCLES_800 (F_CPU / 800001) // 1.25us per bit
30#define CYCLES_400_T0H (F_CPU / 2000000) // 0.5uS
31#define CYCLES_400_T1H (F_CPU / 833333) // 1.2us
32#define CYCLES_400 (F_CPU / 400000) // 2.5us per bit
33
34 uint8_t *p, *end, pix, mask;
35 uint32_t t, time0, time1, period, c, startTime;
36
37#ifdef ESP8266
38 uint32_t pinMask;
39 pinMask = _BV(pin);
40#endif
41
42 p = pixels;
43 end = p + numBytes;
44 pix = *p++;
45 mask = 0x80;
46 startTime = 0;
47
48#ifdef NEO_KHZ400
49 if (is800KHz) {
50#endif
51 time0 = CYCLES_800_T0H;
52 time1 = CYCLES_800_T1H;
53 period = CYCLES_800;
54#ifdef NEO_KHZ400
55 } else { // 400 KHz bitstream
56 time0 = CYCLES_400_T0H;
57 time1 = CYCLES_400_T1H;
58 period = CYCLES_400;
59 }
60#endif
61
62 for (t = time0;; t = time0) {
63 if (pix & mask)
64 t = time1; // Bit high duration
65 while (((c = _getCycleCount()) - startTime) < period)
66 ; // Wait for bit start
67#ifdef ESP8266
68 GPIO_REG_WRITE(GPIO_OUT_W1TS_ADDRESS, pinMask); // Set high
69#else
70 gpio_set_level(pin, HIGH);
71#endif
72 startTime = c; // Save start time
73 while (((c = _getCycleCount()) - startTime) < t)
74 ; // Wait high duration
75#ifdef ESP8266
76 GPIO_REG_WRITE(GPIO_OUT_W1TC_ADDRESS, pinMask); // Set low
77#else
78 gpio_set_level(pin, LOW);
79#endif
80 if (!(mask >>= 1)) { // Next bit/byte
81 if (p >= end)
82 break;
83 pix = *p++;
84 mask = 0x80;
85 }
86 }
87 while ((_getCycleCount() - startTime) < period)
88 ; // Wait for last bit
89}
90
91#endif // ESP8266