UART driven neopixels using Serial1

This commit is contained in:
Andrew Melvin
2015-08-24 18:30:50 +01:00
parent 870b148ce4
commit bca827145d
2 changed files with 75 additions and 10 deletions

View File

@@ -32,12 +32,28 @@ License along with NeoPixel. If not, see
#include "NeoPixelBus.h"
#if defined(ESP8266)
// due to linker overriding the ICACHE_RAM_ATTR for cpp files, these methods are
// moved into a C file so the attribute will be applied correctly
extern "C" void ICACHE_RAM_ATTR send_pixels_800(uint8_t* pixels, uint8_t* end, uint8_t pin);
extern "C" void ICACHE_RAM_ATTR send_pixels_400(uint8_t* pixels, uint8_t* end, uint8_t pin);
#ifdef ESPUARTWS2812
extern "C" {
#include "eagle_soc.h"
#include "uart_register.h"
#include <Arduino.h>
}
#define UART_INV_MASK (0x3f<<19)
#define UART 1
#else
// due to linker overriding the ICACHE_RAM_ATTR for cpp files, these methods are
// moved into a C file so the attribute will be applied correctly
extern "C" void ICACHE_RAM_ATTR send_pixels_800(uint8_t* pixels, uint8_t* end, uint8_t pin);
extern "C" void ICACHE_RAM_ATTR send_pixels_400(uint8_t* pixels, uint8_t* end, uint8_t pin);
#endif
#endif
NeoPixelBus::NeoPixelBus(uint16_t n, uint8_t p, uint8_t t) :
_countPixels(n),
_sizePixels(n * 3),
@@ -46,7 +62,11 @@ NeoPixelBus::NeoPixelBus(uint16_t n, uint8_t p, uint8_t t) :
_activeAnimations(0),
_flagsPixels(t)
{
#ifndef ESPUARTWS2812
setPin(p);
#endif
_pixels = (uint8_t *)malloc(_sizePixels);
if (_pixels)
@@ -69,16 +89,28 @@ NeoPixelBus::~NeoPixelBus()
if (_animations)
free(_animations);
#ifndef ESPUARTWS2812
pinMode(_pin, INPUT);
#endif
}
void NeoPixelBus::Begin(void)
{
pinMode(_pin, OUTPUT);
digitalWrite(_pin, LOW);
void NeoPixelBus::Begin(void)
{
#ifdef ESPUARTWS2812
/* Serial rate is 4x 800KHz for WS2811 */
Serial1.begin(3200000, SERIAL_6N1, SERIAL_TX_ONLY);
CLEAR_PERI_REG_MASK(UART_CONF0(UART), UART_INV_MASK);
//SET_PERI_REG_MASK(UART_CONF0(UART), UART_TXD_INV);
SET_PERI_REG_MASK(UART_CONF0(UART), (BIT(22)));
#else
pinMode(_pin, OUTPUT);
digitalWrite(_pin, LOW);
#endif
Dirty();
}
Dirty();
}
void NeoPixelBus::Show(void)
{
@@ -111,7 +143,9 @@ void NeoPixelBus::Show(void)
// state, computes 'pin high' and 'pin low' values, and writes these back
// to the PORT register as needed.
#ifndef ESPUARTWS2812
noInterrupts(); // Need 100% focus on instruction timing
#endif
#ifdef __AVR__
@@ -724,8 +758,28 @@ void NeoPixelBus::Show(void)
if ((_flagsPixels & NEO_SPDMASK) == NEO_KHZ800)
{
#endif
#ifndef ESPUARTWS2812
// 800 KHz bitstream
send_pixels_800(p, end, _pin);
#else
char buff[4];
do
{
uint8_t subpix = *p++;
buff[0] = data[(subpix >> 6) & 3];
buff[1] = data[(subpix >> 4) & 3];
buff[2] = data[(subpix >> 2) & 3];
buff[3] = data[subpix & 3];
Serial1.write(buff, sizeof(buff));
} while (p < end);
#endif
#ifdef INCLUDE_NEO_KHZ400_SUPPORT
}
@@ -973,7 +1027,10 @@ void NeoPixelBus::Show(void)
#endif // end Architecture select
#ifndef ESPUARTWS2812
interrupts();
#endif
ResetDirty();
_endTime = micros(); // Save EOD time for latch on next call
}

View File

@@ -20,6 +20,8 @@ License along with NeoPixel. If not, see
#include <Arduino.h>
#include "RgbColor.h"
#define ESPUARTWS2812 // drive neopixels by UART on GPIO2 on ESP8266 thanks to Forkineye. https://github.com/forkineye/ESPixelStick
// '_flagsPixels' flags for LED _pixels (third parameter to constructor):
#define NEO_RGB 0x00 // Wired for RGB data order
#define NEO_GRB 0x01 // Wired for GRB data order
@@ -120,6 +122,12 @@ private:
uint8_t _pinMask; // Output PORT bitmask
#endif
#ifdef ESPUARTWS2812
/* 6 bit UART lookup table, first 2 bits ignored. Start and stop bits are part of the pixel stream. */
const char data[4] = { 0b00110111, 0b00000111, 0b00110100, 0b00000100 };
#endif
struct FadeAnimation
{
uint16_t time;