Merge pull request #11289 from s-hadinger/ws2812_esp32

ESP32 support for WS2812 hardware driver via RMT or I2S
This commit is contained in:
Theo Arends 2021-03-11 08:21:29 +01:00 committed by GitHub
commit bc7101dfc4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 96 additions and 69 deletions

View File

@ -16,8 +16,12 @@ All notable changes to this project will be documented in this file.
- Crash protection in ext_vnsprintf_P (#11202)
- Extent compile time SetOptions support (#11204)
- ESP32 Extent BLE (#11212)
- ESP32 support for WS2812 hardware driver via RMT or I2S
- ESP32 support for secondary I2C controller
### Changed
- ESP32 core library from v1.0.5-rc6 to v1.0.5
- TasmotaSerial library from v3.2.0 to v3.3.0

View File

@ -114,10 +114,6 @@ typedef int SerConfu8;
typedef int SerialConfig;
//#define analogWrite(a, b)
//
// WS2812
//
#define NeoEsp8266BitBang800KbpsMethod NeoEsp32BitBang800KbpsMethod
//
// UDP
//

View File

@ -494,7 +494,9 @@
// -- Optional light modules ----------------------
#define USE_WS2812 // WS2812 Led string using library NeoPixelBus (+5k code, +1k mem, 232 iram) - Disable by //
// #define USE_WS2812_DMA // DMA supports only GPIO03 (= Serial RXD) (+1k mem). When USE_WS2812_DMA is enabled expect Exceptions on Pow
// #define USE_WS2812_DMA // ESP8266 only, DMA supports only GPIO03 (= Serial RXD) (+1k mem). When USE_WS2812_DMA is enabled expect Exceptions on Pow
#define USE_WS2812_RMT 0 // ESP32 only, hardware RMT support (default). Specify the RMT channel 0..7. This should be preferred to software bit bang.
// #define USE_WS2812_I2S 0 // ESP32 only, hardware I2S support. Specify the I2S channel 0..2. This is exclusive from RMT. By default, prefer RMT support
// #define USE_WS2812_INVERTED // Use inverted data signal
#define USE_WS2812_HARDWARE NEO_HW_WS2812 // Hardware type (NEO_HW_WS2812, NEO_HW_WS2812X, NEO_HW_WS2813, NEO_HW_SK6812, NEO_HW_LC8812, NEO_HW_APA106, NEO_HW_P9813)
#define USE_WS2812_CTYPE NEO_GRB // Color type (NEO_RGB, NEO_GRB, NEO_BRG, NEO_RBG, NEO_RGBW, NEO_GRBW)

View File

@ -47,81 +47,106 @@ void (* const Ws2812Command[])(void) PROGMEM = {
#include <NeoPixelBus.h>
#if (USE_WS2812_HARDWARE == NEO_HW_P9813)
typedef P9813BgrFeature selectedNeoFeatureType;
#undef USE_WS2812_DMA
#undef USE_WS2812_INVERTED
#elif (USE_WS2812_CTYPE == NEO_GRB)
typedef NeoGrbFeature selectedNeoFeatureType;
#elif (USE_WS2812_CTYPE == NEO_BRG)
typedef NeoBrgFeature selectedNeoFeatureType;
#elif (USE_WS2812_CTYPE == NEO_RBG)
typedef NeoRbgFeature selectedNeoFeatureType;
#elif (USE_WS2812_CTYPE == NEO_RGBW)
typedef NeoRgbwFeature selectedNeoFeatureType;
#elif (USE_WS2812_CTYPE == NEO_GRBW)
typedef NeoGrbwFeature selectedNeoFeatureType;
#else // USE_WS2812_CTYPE
typedef NeoRgbFeature selectedNeoFeatureType;
#endif // USE_WS2812_CTYPE
#ifdef USE_WS2812_DMA
#ifdef USE_WS2812_INVERTED
// See NeoEspDmaMethod.h for available options
#if (USE_WS2812_HARDWARE == NEO_HW_WS2812X)
typedef NeoEsp8266DmaInvertedWs2812xMethod selectedNeoSpeedType;
#elif (USE_WS2812_HARDWARE == NEO_HW_SK6812)
typedef NeoEsp8266DmaInvertedSk6812Method selectedNeoSpeedType;
#elif (USE_WS2812_HARDWARE == NEO_HW_APA106)
typedef NeoEsp8266DmaInvertedApa106Method selectedNeoSpeedType;
#else // USE_WS2812_HARDWARE
typedef NeoEsp8266DmaInverted800KbpsMethod selectedNeoSpeedType;
#endif // USE_WS2812_HARDWARE
#else // No USE_WS2812_INVERTED
#if (USE_WS2812_HARDWARE == NEO_HW_WS2812X)
typedef NeoEsp8266DmaWs2812xMethod selectedNeoSpeedType;
#elif (USE_WS2812_HARDWARE == NEO_HW_SK6812)
typedef NeoEsp8266DmaSk6812Method selectedNeoSpeedType;
#elif (USE_WS2812_HARDWARE == NEO_HW_APA106)
typedef NeoEsp8266DmaApa106Method selectedNeoSpeedType;
#else // USE_WS2812_HARDWARE
typedef NeoEsp8266Dma800KbpsMethod selectedNeoSpeedType;
#endif // USE_WS2812_HARDWARE
#endif // No USE_WS2812_INVERTED
#else // No USE_WS2812_DMA
#ifdef USE_WS2812_INVERTED
// See NeoEspBitBangMethod.h for available options
// Build `selectedNeoFeatureType` as Neo-Rgb-Feature
// parametrized as: NEO_FEATURE_NEO+NEO_FEATURE_TYPE+NEO_FEATURE_FEATURE
#define CONCAT2(A,B) CONCAT2_(A,B) // ensures expansion first, see https://stackoverflow.com/questions/3221896/how-can-i-guarantee-full-macro-expansion-of-a-parameter-before-paste
#define CONCAT2_(A,B) A ## B
#define CONCAT3(A,B,C) CONCAT3_(A,B,C) // ensures expansion first, see https://stackoverflow.com/questions/3221896/how-can-i-guarantee-full-macro-expansion-of-a-parameter-before-paste
#define CONCAT3_(A,B,C) A ## B ## C
#define NEO_FEATURE_NEO Neo
#define NEO_FEATURE_FEATURE Feature
// select the right Neo feature based on USE_WS2812_CTYPE
// NEO_FEATURE_TYPE can be one of: Rgb (default), Grb, Brg, Rgb, Rgbw, Grbw
#if (USE_WS2812_CTYPE == NEO_GRB)
#define NEO_FEATURE_TYPE Grb
#elif (USE_WS2812_CTYPE == NEO_BRG)
#define NEO_FEATURE_TYPE Brg
#elif (USE_WS2812_CTYPE == NEO_RBG)
#define NEO_FEATURE_TYPE Rbg
#elif (USE_WS2812_CTYPE == NEO_RGBW)
#define NEO_FEATURE_TYPE Rbgw
#elif (USE_WS2812_CTYPE == NEO_GRBW)
#define NEO_FEATURE_TYPE Grbw
#else
#define NEO_FEATURE_TYPE Rgb
#endif
// Exception for NEO_HW_P9813
#if (USE_WS2812_HARDWARE == NEO_HW_P9813)
#undef NEO_FEATURE_NEO
#undef NEO_FEATURE_TYPE
#define NEO_FEATURE_NEO P9813 // P9813BgrFeature
#define NEO_FEATURE_TYPE Bgr
#undef USE_WS2812_DMA
#undef USE_WS2812_INVERTED
#endif // USE_WS2812_CTYPE
typedef CONCAT3(NEO_FEATURE_NEO,NEO_FEATURE_TYPE,NEO_FEATURE_FEATURE) selectedNeoFeatureType;
// selectedNeoSpeedType is built as Neo+Esp8266+Dma+Inverted+Ws2812x+Method
// Or NEO_NEO+NEO_CHIP+NEO_PROTO+NEO_INV+NEO_HW+Method
#define CONCAT6(A,B,C,D,E,F) CONCAT6_(A,B,C,D,E,F) // ensures expansion first, see https://stackoverflow.com/questions/3221896/how-can-i-guarantee-full-macro-expansion-of-a-parameter-before-paste
#define CONCAT6_(A,B,C,D,E,F) A ## B ## C ## D ## E ## F
#define NEO_NEO Neo
#ifdef ESP32
#define NEO_CHIP Esp32
#else
#define NEO_CHIP Esp8266
#endif
// Proto = DMA or BigBang
#if defined(USE_WS2812_DMA) && defined(ESP8266)
#define NEO_PROTO Dma
#elif defined(USE_WS2812_RMT) && defined(ESP32)
#define NEO_PROTO CONCAT2(Rmt,USE_WS2812_RMT)
#elif defined(USE_WS2812_I2S) && defined(ESP32)
#define NEO_PROTO CONCAT2(I2s,USE_WS2812_I2S)
#else
#define NEO_PROTO BitBang
#endif
#ifdef USE_WS2812_INVERTED
#define NEO_INV Inverted
#else
#define NEO_INV
#endif
#if (USE_WS2812_HARDWARE == NEO_HW_WS2812X)
typedef NeoEsp8266BitBangWs2812xInvertedMethod selectedNeoSpeedType;
#define NEO_HW Ws2812x
#elif (USE_WS2812_HARDWARE == NEO_HW_SK6812)
typedef NeoEsp8266BitBangSk6812InvertedMethod selectedNeoSpeedType;
#define NEO_HW Sk6812
#elif (USE_WS2812_HARDWARE == NEO_HW_APA106)
#define NEO_HW Apa106
#else // USE_WS2812_HARDWARE
typedef NeoEsp8266BitBang400KbpsInvertedMethod selectedNeoSpeedType;
#define NEO_HW 800Kbps
#endif // USE_WS2812_HARDWARE
#else // No USE_WS2812_INVERTED
#if (USE_WS2812_HARDWARE == NEO_HW_P9813)
typedef P9813Method selectedNeoSpeedType;
#elif (USE_WS2812_HARDWARE == NEO_HW_WS2812X)
typedef NeoEsp8266BitBangWs2812xMethod selectedNeoSpeedType;
#elif (USE_WS2812_HARDWARE == NEO_HW_SK6812)
typedef NeoEsp8266BitBangSk6812Method selectedNeoSpeedType;
#else // USE_WS2812_HARDWARE
typedef NeoEsp8266BitBang800KbpsMethod selectedNeoSpeedType;
#endif // USE_WS2812_HARDWARE
#undef NEO_NEO
#define NEO_NEO
#undef NEO_CHIP
#define NEO_CHIP
#undef NEO_PROTO
#define NEO_PROTO
#undef NEO_INV
#define NEO_INV
#undef NEO_HW
#define NEO_HW P9813 // complete driver is P9813Method
#endif
#endif // No USE_WS2812_INVERTED
#endif // No USE_WS2812_DMA
#if defined(ESP8266) && defined(USE_WS2812_DMA)
typedef CONCAT6(NEO_NEO,NEO_CHIP,NEO_PROTO,NEO_INV,NEO_HW,Method) selectedNeoSpeedType;
#else // Dma : different naming scheme
typedef CONCAT6(NEO_NEO,NEO_CHIP,NEO_PROTO,NEO_HW,NEO_INV,Method) selectedNeoSpeedType;
#endif
NeoPixelBus<selectedNeoFeatureType, selectedNeoSpeedType> *strip = nullptr;