Damien George
9 years ago
committed by
Paul Sokolovsky
5 changed files with 79 additions and 0 deletions
@ -0,0 +1,64 @@ |
|||
// Original version from https://github.com/adafruit/Adafruit_NeoPixel
|
|||
// Modifications by dpgeorge to support auto-CPU-frequency detection
|
|||
|
|||
// This is a mash-up of the Due show() code + insights from Michael Miller's
|
|||
// ESP8266 work for the NeoPixelBus library: github.com/Makuna/NeoPixelBus
|
|||
// Needs to be a separate .c file to enforce ICACHE_RAM_ATTR execution.
|
|||
|
|||
#include "c_types.h" |
|||
#include "eagle_soc.h" |
|||
#include "user_interface.h" |
|||
#include "espneopixel.h" |
|||
|
|||
#define NEO_KHZ400 (1) |
|||
|
|||
static uint32_t _getCycleCount(void) __attribute__((always_inline)); |
|||
static inline uint32_t _getCycleCount(void) { |
|||
uint32_t ccount; |
|||
__asm__ __volatile__("rsr %0,ccount":"=a" (ccount)); |
|||
return ccount; |
|||
} |
|||
|
|||
void /*ICACHE_RAM_ATTR*/ esp_neopixel_write(uint8_t pin, uint8_t *pixels, uint32_t numBytes, bool is800KHz) { |
|||
|
|||
uint8_t *p, *end, pix, mask; |
|||
uint32_t t, time0, time1, period, c, startTime, pinMask; |
|||
|
|||
pinMask = 1 << pin; |
|||
p = pixels; |
|||
end = p + numBytes; |
|||
pix = *p++; |
|||
mask = 0x80; |
|||
startTime = 0; |
|||
|
|||
uint32_t fcpu = system_get_cpu_freq() * 1000000; |
|||
|
|||
#ifdef NEO_KHZ400 |
|||
if(is800KHz) { |
|||
#endif |
|||
time0 = fcpu / 2500000; // 0.4us
|
|||
time1 = fcpu / 1250000; // 0.8us
|
|||
period = fcpu / 800000; // 1.25us per bit
|
|||
#ifdef NEO_KHZ400 |
|||
} else { // 400 KHz bitstream
|
|||
time0 = fcpu / 2000000; // 0.5uS
|
|||
time1 = fcpu / 833333; // 1.2us
|
|||
period = fcpu / 400000; // 2.5us per bit
|
|||
} |
|||
#endif |
|||
|
|||
for(t = time0;; t = time0) { |
|||
if(pix & mask) t = time1; // Bit high duration
|
|||
while(((c = _getCycleCount()) - startTime) < period); // Wait for bit start
|
|||
GPIO_REG_WRITE(GPIO_OUT_W1TS_ADDRESS, pinMask); // Set high
|
|||
startTime = c; // Save start time
|
|||
while(((c = _getCycleCount()) - startTime) < t); // Wait high duration
|
|||
GPIO_REG_WRITE(GPIO_OUT_W1TC_ADDRESS, pinMask); // Set low
|
|||
if(!(mask >>= 1)) { // Next bit/byte
|
|||
if(p >= end) break; |
|||
pix = *p++; |
|||
mask = 0x80; |
|||
} |
|||
} |
|||
while((_getCycleCount() - startTime) < period); // Wait for last bit
|
|||
} |
@ -0,0 +1 @@ |
|||
void esp_neopixel_write(uint8_t pin, uint8_t *pixels, uint32_t numBytes, bool is800KHz); |
Loading…
Reference in new issue