|
21 | 21 |
|
22 | 22 | portMUX_TYPE mySpinlock = portMUX_INITIALIZER_UNLOCKED; |
23 | 23 |
|
24 | | - void IRAM_ATTR setColor(uint32_t color, uint8_t pin, uint8_t time1H, uint8_t time1L, uint8_t time0H, uint8_t time0L) { |
25 | | - uint32_t bitmask = 0x800000; |
26 | | - volatile uint8_t count = 24; |
27 | | - uint32_t start; |
| 24 | + void IRAM_ATTR setColor(uint32_t color, uint8_t pin, uint8_t time1H, uint8_t time1L, uint8_t time0H, uint8_t time0L, uint8_t count) { |
28 | 25 | uint32_t tc_reg = GPIO_OUT_W1TC_REG; |
29 | 26 | uint32_t ts_reg = GPIO_OUT_W1TS_REG; |
30 | | - uint32_t cycles; |
31 | 27 |
|
32 | 28 | if(pin > 32) { |
33 | 29 | tc_reg = GPIO_OUT1_W1TC_REG; |
|
37 | 33 | uint32_t reg_val = (1UL << (pin)); |
38 | 34 |
|
39 | 35 | vPortEnterCritical(&mySpinlock); // Interrupts off on current core |
40 | | - |
41 | 36 | while(count--) { |
42 | | - cycles = (color & bitmask) ? time1H : time0H; |
43 | | - WRITE_PERI_REG(ts_reg, reg_val); |
44 | | - start = GET_CPU_CYCLES(); |
45 | | - while (GET_CPU_CYCLES() - start < cycles) { __asm__ __volatile__("nop"); } |
46 | | - |
47 | | - cycles = (color & bitmask) ? time1L : time0L; |
48 | | - bitmask = bitmask >> 1; |
49 | | - WRITE_PERI_REG(tc_reg, reg_val); |
50 | | - start = GET_CPU_CYCLES(); |
51 | | - while (GET_CPU_CYCLES() - start < cycles) { __asm__ __volatile__("nop"); } |
| 37 | + uint32_t bitmask = 0x800000; |
| 38 | + uint32_t start; |
| 39 | + uint32_t cycles; |
| 40 | + while(bitmask) { |
| 41 | + cycles = (color & bitmask) ? time1H : time0H; |
| 42 | + WRITE_PERI_REG(ts_reg, reg_val); |
| 43 | + start = GET_CPU_CYCLES(); |
| 44 | + while (GET_CPU_CYCLES() - start < cycles) { __asm__ __volatile__("nop"); } |
| 45 | + |
| 46 | + cycles = (color & bitmask) ? time1L : time0L; |
| 47 | + bitmask = bitmask >> 1; |
| 48 | + WRITE_PERI_REG(tc_reg, reg_val); |
| 49 | + start = GET_CPU_CYCLES(); |
| 50 | + while (GET_CPU_CYCLES() - start < cycles) { __asm__ __volatile__("nop"); } |
| 51 | + } |
52 | 52 | } |
53 | | - |
54 | 53 | vPortExitCritical(&mySpinlock); // Interrupts on |
55 | 54 |
|
56 | 55 | } |
|
63 | 62 |
|
64 | 63 | #define GET_CPU_CYCLES() esp_get_cycle_count() |
65 | 64 |
|
66 | | - void IRAM_ATTR setColor(uint32_t color, uint8_t pin, uint8_t time1H, uint8_t time1L, uint8_t time0H, uint8_t time0L) { |
67 | | - uint32_t bitmask = 0x800000; |
68 | | - volatile uint8_t count = 24; |
69 | | - uint32_t start; |
70 | | - uint32_t cycles; |
71 | | - |
| 65 | + void IRAM_ATTR setColor(uint32_t color, uint8_t pin, uint8_t time1H, uint8_t time1L, uint8_t time0H, uint8_t time0L, uint8_t count) { |
72 | 66 | if(pin > 32) return; |
73 | 67 | uint32_t reg_val = (1UL << (pin)); |
74 | 68 |
|
75 | 69 | ETS_INTR_LOCK(); // Interrupts off |
76 | | - |
77 | 70 | while(count--) { |
78 | | - cycles = (color & bitmask) ? time1H : time0H; |
79 | | - GPIO_REG_WRITE(GPIO_OUT_W1TS_ADDRESS, reg_val); |
80 | | - start = GET_CPU_CYCLES(); |
81 | | - while (GET_CPU_CYCLES() - start < cycles) { __asm__ __volatile__("nop"); } |
82 | | - |
83 | | - cycles = (color & bitmask) ? time1L : time0L; |
84 | | - bitmask = bitmask >> 1; |
85 | | - GPIO_REG_WRITE(GPIO_OUT_W1TC_ADDRESS, reg_val); |
86 | | - start = GET_CPU_CYCLES(); |
87 | | - while (GET_CPU_CYCLES() - start < cycles) { __asm__ __volatile__("nop"); } |
| 71 | + uint32_t bitmask = 0x800000; |
| 72 | + uint32_t start; |
| 73 | + uint32_t cycles; |
| 74 | + while(bitmask) { |
| 75 | + cycles = (color & bitmask) ? time1H : time0H; |
| 76 | + GPIO_REG_WRITE(GPIO_OUT_W1TS_ADDRESS, reg_val); |
| 77 | + start = GET_CPU_CYCLES(); |
| 78 | + while (GET_CPU_CYCLES() - start < cycles) { __asm__ __volatile__("nop"); } |
| 79 | + |
| 80 | + cycles = (color & bitmask) ? time1L : time0L; |
| 81 | + bitmask = bitmask >> 1; |
| 82 | + GPIO_REG_WRITE(GPIO_OUT_W1TC_ADDRESS, reg_val); |
| 83 | + start = GET_CPU_CYCLES(); |
| 84 | + while (GET_CPU_CYCLES() - start < cycles) { __asm__ __volatile__("nop"); } |
| 85 | + } |
88 | 86 | } |
89 | | - |
90 | 87 | ETS_INTR_UNLOCK(); // Interrupts on |
91 | 88 | } |
92 | 89 |
|
93 | 90 | #else |
94 | | - #error Target CONFIG_IDF_TARGET is not supported |
| 91 | + #error Target is not yet supported |
95 | 92 | #endif |
96 | 93 |
|
97 | 94 |
|
98 | 95 |
|
99 | 96 |
|
100 | | -void ws2812Write(uint8_t pin, uint32_t color_rgb, ws2812_write_led_type_t led_type) |
| 97 | +void ws2812Write(uint8_t pin, uint32_t color_rgb, uint8_t led_count, ws2812_write_led_type_t led_type) |
101 | 98 | { |
102 | 99 | pinMode(pin, OUTPUT); |
103 | 100 |
|
@@ -129,44 +126,44 @@ void ws2812Write(uint8_t pin, uint32_t color_rgb, ws2812_write_led_type_t led_ty |
129 | 126 | uint32_t Freq; |
130 | 127 | uint8_t time1H, time1L, time0H, time0L; |
131 | 128 |
|
132 | | - // WS2812B: 1: H_800ns L_450ns (Send a '1' bit) |
133 | | - // 0: H_400ns L_850ns (Send a '0' bit) |
| 129 | + // WS2812B: 1: H_800ns L_450ns (Send a '1' bit) +/-150ns |
| 130 | + // 0: H_400ns L_850ns (Send a '0' bit) +/-150ns |
134 | 131 |
|
135 | 132 | #ifdef ARDUINO_ARCH_ESP32 |
136 | 133 | Freq = getCpuFrequencyMhz(); |
137 | 134 | #if defined(CONFIG_IDF_TARGET_ESP32) |
138 | | - // Tested for ESP32 |
139 | | - time1H = (800 * Freq) / 1000 - 11; |
140 | | - time0H = (400 * Freq) / 1000 - 15; |
141 | | - time1L = (450 * Freq) / 1000 - 25; |
142 | | - time0L = (850 * Freq) / 1000 - 28; |
| 135 | + // Tested for ESP32 ns @ MHz 240 160 80 |
| 136 | + time1H = (800 * Freq) / 1000 - 15; // 800 774 836 |
| 137 | + time0H = (400 * Freq) / 1000 - 15; // 400 424 312 |
| 138 | + time1L = (450 * Freq) / 1000 - 25; // 426 464 402 |
| 139 | + time0L = (850 * Freq) / 1000 - 28; // 838 812 920 |
143 | 140 | if(Freq <= 80) { |
144 | 141 | // Adjust timing for 80 MHz |
145 | | - time1L -= 4; |
146 | | - time0L -= 4; |
| 142 | + time0H -= 2; |
| 143 | + time0L += 4; |
147 | 144 | } |
148 | 145 | #else |
149 | | - // Tested for ESP32-S3 80/160/240 MHz |
150 | | - time1H = (800 * Freq) / 1000 - 11; |
151 | | - time0H = (400 * Freq) / 1000 - 15; |
152 | | - time1L = (450 * Freq) / 1000 - 18; |
153 | | - time0L = (850 * Freq) / 1000 - 26; |
| 146 | + // Tested for ESP32-S3 ns @ MHz 240 160 80 |
| 147 | + time1H = (800 * Freq) / 1000 - 11; // 812 824 774 |
| 148 | + time0H = (400 * Freq) / 1000 - 15; // 400 412 400 |
| 149 | + time1L = (450 * Freq) / 1000 - 15; // 450 438 450 |
| 150 | + time0L = (850 * Freq) / 1000 - 24; // 814 838 788 |
154 | 151 | #endif |
155 | 152 | #elif defined(ARDUINO_ARCH_ESP8266) |
156 | 153 | Freq = (uint32_t)system_get_cpu_freq(); |
157 | 154 | // Tested ESP8266 at 80 and 160 MHz |
158 | | - time1H = (800 * Freq) / 1000 - 11; |
159 | | - time0H = (400 * Freq) / 1000 - 15; |
160 | | - time1L = (450 * Freq) / 1000 - 21; |
161 | | - time0L = (850 * Freq) / 1000 - 24; |
| 155 | + time1H = (800 * Freq) / 1000 - 13; // 850 824 |
| 156 | + time0H = (400 * Freq) / 1000 - 15; // 350 374 |
| 157 | + time1L = (450 * Freq) / 1000 - 21; // 424 438 |
| 158 | + time0L = (850 * Freq) / 1000 - 21; // 876 830 |
162 | 159 | #else |
163 | 160 | return; // Unsupported architecture |
164 | 161 | #endif |
165 | 162 |
|
166 | 163 | //Serial.printf("ws2812Write: %u MHz, time1H=%u, time1L=%u, time0H=%u, time0L=%u\r\n", |
167 | 164 | // (unsigned int)Freq, (unsigned int)time1H, (unsigned int)time1L, |
168 | 165 | // (unsigned int)time0H, (unsigned int)time0L); |
169 | | - setColor(tx_color, pin, time1H, time1L, time0H, time0L); |
| 166 | + setColor(tx_color, pin, time1H, time1L, time0H, time0L, led_count); |
170 | 167 |
|
171 | 168 |
|
172 | 169 |
|
|
0 commit comments