From db6193dc8014765d7eaf668476d738231b4641ba Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Wed, 23 Aug 2023 14:52:58 +0200 Subject: [PATCH] Phase 2 support C2/C6 --- lib/lib_basic/NeoPixelBus/src/NeoPixelBus.h | 5 +- .../src/internal/DotStarEsp32DmaSpiMethod.h | 16 +- .../NeoPixelBus/src/internal/Esp32_i2s.c | 2 + .../NeoPixelBus/src/internal/Esp32_i2s.h | 5 +- .../NeoPixelBus/src/internal/NeoBusChannel.h | 4 +- .../src/internal/NeoEsp32I2sMethod.h | 6 +- .../src/internal/NeoEsp32RmtMethod.cpp | 2 +- .../src/internal/NeoEsp32RmtMethod.h | 7 +- .../src/internal/NeoEsp32RmtMethod_idf5.h | 899 ++++++++++++++++++ .../src/internal/NeoEspBitBangMethod.cpp | 9 +- .../src/internal/NeoEspBitBangMethod.h | 4 +- 11 files changed, 938 insertions(+), 21 deletions(-) create mode 100644 lib/lib_basic/NeoPixelBus/src/internal/NeoEsp32RmtMethod_idf5.h diff --git a/lib/lib_basic/NeoPixelBus/src/NeoPixelBus.h b/lib/lib_basic/NeoPixelBus/src/NeoPixelBus.h index 1f06ef52c..3b6918318 100644 --- a/lib/lib_basic/NeoPixelBus/src/NeoPixelBus.h +++ b/lib/lib_basic/NeoPixelBus/src/NeoPixelBus.h @@ -101,9 +101,12 @@ License along with NeoPixel. If not, see #include "internal/NeoEspBitBangMethod.h" #elif defined(ARDUINO_ARCH_ESP32) - +#if ESP_IDF_VERSION_MAJOR < 5 #include "internal/NeoEsp32I2sMethod.h" #include "internal/NeoEsp32RmtMethod.h" +#else +#include "internal/NeoEsp32RmtMethod_idf5.h" +#endif // ESP_IDF_VERSION_MAJOR #include "internal/NeoEspBitBangMethod.h" #include "internal/DotStarEsp32DmaSpiMethod.h" diff --git a/lib/lib_basic/NeoPixelBus/src/internal/DotStarEsp32DmaSpiMethod.h b/lib/lib_basic/NeoPixelBus/src/internal/DotStarEsp32DmaSpiMethod.h index a9d149b71..953a216e7 100644 --- a/lib/lib_basic/NeoPixelBus/src/internal/DotStarEsp32DmaSpiMethod.h +++ b/lib/lib_basic/NeoPixelBus/src/internal/DotStarEsp32DmaSpiMethod.h @@ -29,12 +29,12 @@ License along with NeoPixel. If not, see #include "driver/spi_master.h" -#if defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(HSPI_HOST) +#if (defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32C2) || defined(CONFIG_IDF_TARGET_ESP32C6)) && !defined(HSPI_HOST) // HSPI_HOST depreciated in C3 #define HSPI_HOST SPI2_HOST #endif -#if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) +#if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32C2) && !defined(CONFIG_IDF_TARGET_ESP32C6) class Esp32VspiBus { public: @@ -52,7 +52,7 @@ public: const static int ParallelBits = 1; }; -#if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) +#if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32C2) && !defined(CONFIG_IDF_TARGET_ESP32C6) class Esp32Vspi2BitBus { public: @@ -70,7 +70,7 @@ public: const static int ParallelBits = 2; }; -#if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) +#if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32C2) && !defined(CONFIG_IDF_TARGET_ESP32C6) class Esp32Vspi4BitBus { public: @@ -174,7 +174,7 @@ public: // If pins aren't specified, initialize bus with just the default SCK and MOSI pins for the SPI peripheral (no SS, no >1-bit pins) void Initialize() { -#if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) +#if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32C2) && !defined(CONFIG_IDF_TARGET_ESP32C6) if (T_SPIBUS::SpiHostDevice == VSPI_HOST) { Initialize(SCK, -1, MOSI, -1, -1, -1); @@ -277,7 +277,7 @@ private: int8_t _ssPin; }; -#if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) +#if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32C2) && !defined(CONFIG_IDF_TARGET_ESP32C6) // Clock Speed and Default Definitions for DotStarEsp32DmaVspi typedef DotStarEsp32DmaSpiMethod DotStarEsp32DmaVspi40MhzMethod; typedef DotStarEsp32DmaSpiMethod DotStarEsp32DmaVspi20MhzMethod; @@ -303,7 +303,7 @@ typedef DotStarEsp32DmaSpiMethod DotStarEsp32DmaHspiHz typedef DotStarEsp32DmaHspi10MhzMethod DotStarEsp32DmaHspiMethod; -#if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) +#if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32C2) && !defined(CONFIG_IDF_TARGET_ESP32C6) // Clock Speed and Default Definitions for DotStarEsp32DmaVspi2Bit typedef DotStarEsp32DmaSpiMethod DotStarEsp32DmaVspi2Bit40MhzMethod; typedef DotStarEsp32DmaSpiMethod DotStarEsp32DmaVspi2Bit20MhzMethod; @@ -329,7 +329,7 @@ typedef DotStarEsp32DmaSpiMethod DotStarEsp32DmaHsp typedef DotStarEsp32DmaHspi2Bit10MhzMethod DotStarEsp32DmaHspi2BitMethod; -#if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) +#if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32C2) && !defined(CONFIG_IDF_TARGET_ESP32C6) // Clock Speed and Default Definitions for DotStarEsp32DmaVspi4Bit typedef DotStarEsp32DmaSpiMethod DotStarEsp32DmaVspi4Bit40MhzMethod; typedef DotStarEsp32DmaSpiMethod DotStarEsp32DmaVspi4Bit20MhzMethod; diff --git a/lib/lib_basic/NeoPixelBus/src/internal/Esp32_i2s.c b/lib/lib_basic/NeoPixelBus/src/internal/Esp32_i2s.c index 0f100cb41..5c1943ec9 100644 --- a/lib/lib_basic/NeoPixelBus/src/internal/Esp32_i2s.c +++ b/lib/lib_basic/NeoPixelBus/src/internal/Esp32_i2s.c @@ -20,6 +20,7 @@ #include "sdkconfig.h" // this sets useful config symbols, like CONFIG_IDF_TARGET_ESP32C3 // ESP32C3/S3 I2S is not supported yet due to significant changes to interface +#ifndef CONFIG_SOC_RMT_TX_CANDIDATES_PER_GROUP // turn this off with something new from idf5.1 #if !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32S3) #include @@ -495,5 +496,6 @@ size_t i2sWrite(uint8_t bus_num, uint8_t* data, size_t len, bool copy, bool free } #endif // !defined(CONFIG_IDF_TARGET_ESP32C3) +#endif //ESP_IDF_VERSION_MAJOR < 5 #endif // defined(ARDUINO_ARCH_ESP32) diff --git a/lib/lib_basic/NeoPixelBus/src/internal/Esp32_i2s.h b/lib/lib_basic/NeoPixelBus/src/internal/Esp32_i2s.h index 1249d2e11..b9ab41920 100644 --- a/lib/lib_basic/NeoPixelBus/src/internal/Esp32_i2s.h +++ b/lib/lib_basic/NeoPixelBus/src/internal/Esp32_i2s.h @@ -1,5 +1,8 @@ #pragma once +#include "sdkconfig.h" // this sets useful config symbols, like CONFIG_IDF_TARGET_ESP32C3 + +#ifndef CONFIG_SOC_RMT_TX_CANDIDATES_PER_GROUP // turn this off with something new from idf5.1 // ESP32C3 I2S is not supported yet due to significant changes to interface #if defined(ARDUINO_ARCH_ESP32) && !defined(CONFIG_IDF_TARGET_ESP32C3) @@ -38,5 +41,5 @@ bool i2sWriteDone(uint8_t bus_num); #ifdef __cplusplus } #endif - #endif +#endif // ESP_IDF_VERSION_MAJOR < 5 diff --git a/lib/lib_basic/NeoPixelBus/src/internal/NeoBusChannel.h b/lib/lib_basic/NeoPixelBus/src/internal/NeoBusChannel.h index 6f4b3c66f..5fdb131bf 100644 --- a/lib/lib_basic/NeoPixelBus/src/internal/NeoBusChannel.h +++ b/lib/lib_basic/NeoPixelBus/src/internal/NeoBusChannel.h @@ -12,7 +12,7 @@ enum NeoBusChannel NeoBusChannel_0, NeoBusChannel_1, -#if !defined(CONFIG_IDF_TARGET_ESP32C3) +#if !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32C2) && !defined(CONFIG_IDF_TARGET_ESP32C6) NeoBusChannel_2, @@ -35,7 +35,7 @@ enum NeoBusChannel NeoBusChannel_7, #endif // !defined(CONFIG_IDF_TARGET_ESP32S2) -#endif // !defined(CONFIG_IDF_TARGET_ESP32C3) +#endif // !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32C2) && !defined(CONFIG_IDF_TARGET_ESP32C6) #endif // ARDUINO_ARCH_ESP32 diff --git a/lib/lib_basic/NeoPixelBus/src/internal/NeoEsp32I2sMethod.h b/lib/lib_basic/NeoPixelBus/src/internal/NeoEsp32I2sMethod.h index 9dbaa7fe7..2afe6d5aa 100644 --- a/lib/lib_basic/NeoPixelBus/src/internal/NeoEsp32I2sMethod.h +++ b/lib/lib_basic/NeoPixelBus/src/internal/NeoEsp32I2sMethod.h @@ -26,12 +26,16 @@ License along with NeoPixel. If not, see #pragma once +#if ESP_IDF_VERSION_MAJOR <= 4 // ESP32C3 I2S is not supported yet due to significant changes to interface #if defined(ARDUINO_ARCH_ESP32) && !defined(CONFIG_IDF_TARGET_ESP32C3) extern "C" { #include +#if ESP_IDF_VERSION_MAJOR >= 5 +#include +#endif #include "Esp32_i2s.h" } @@ -376,5 +380,5 @@ typedef NeoEsp32I2s1Ws2812xInvertedMethod Neo800KbpsInvertedMethod; typedef NeoEsp32I2s1400KbpsInvertedMethod Neo400KbpsInvertedMethod; #endif // !defined(NEOPIXEL_ESP32_RMT_DEFAULT) && !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) - #endif +#endif // ESP_IDF_VERSION_MAJOR < 5 diff --git a/lib/lib_basic/NeoPixelBus/src/internal/NeoEsp32RmtMethod.cpp b/lib/lib_basic/NeoPixelBus/src/internal/NeoEsp32RmtMethod.cpp index f25d20d8f..fd94321ea 100644 --- a/lib/lib_basic/NeoPixelBus/src/internal/NeoEsp32RmtMethod.cpp +++ b/lib/lib_basic/NeoPixelBus/src/internal/NeoEsp32RmtMethod.cpp @@ -32,7 +32,7 @@ License along with NeoPixel. If not, see #include "NeoBusChannel.h" #include "NeoEsp32RmtMethod.h" -#ifdef ARDUINO_ARCH_ESP32 +#if defined(ARDUINO_ARCH_ESP32) && !defined(CONFIG_IDF_TARGET_ESP32C6) // translate NeoPixelBuffer into RMT buffer diff --git a/lib/lib_basic/NeoPixelBus/src/internal/NeoEsp32RmtMethod.h b/lib/lib_basic/NeoPixelBus/src/internal/NeoEsp32RmtMethod.h index 2ed7e4a0e..faded6b3f 100644 --- a/lib/lib_basic/NeoPixelBus/src/internal/NeoEsp32RmtMethod.h +++ b/lib/lib_basic/NeoPixelBus/src/internal/NeoEsp32RmtMethod.h @@ -29,7 +29,7 @@ License along with NeoPixel. If not, see #pragma once -#ifdef ARDUINO_ARCH_ESP32 +#if defined(ARDUINO_ARCH_ESP32) && !defined(CONFIG_IDF_TARGET_ESP32C6) /* General Reference documentation for the APIs used in this implementation LOW LEVEL: (what is actually used) @@ -47,6 +47,9 @@ Esp32-hal-rmt.c extern "C" { +#if ESP_IDF_VERSION_MAJOR >= 5 +#include +#endif #include } @@ -451,7 +454,7 @@ public: const static rmt_channel_t RmtChannelNumber = RMT_CHANNEL_3; }; -#if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) +#if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32C6) class NeoEsp32RmtChannel4 { diff --git a/lib/lib_basic/NeoPixelBus/src/internal/NeoEsp32RmtMethod_idf5.h b/lib/lib_basic/NeoPixelBus/src/internal/NeoEsp32RmtMethod_idf5.h new file mode 100644 index 000000000..a7bfa3c72 --- /dev/null +++ b/lib/lib_basic/NeoPixelBus/src/internal/NeoEsp32RmtMethod_idf5.h @@ -0,0 +1,899 @@ +/*------------------------------------------------------------------------- +NeoPixel library helper functions for Esp32. + +A BIG thanks to Andreas Merkle for the investigation and implementation of +a workaround to the GCC bug that drops method attributes from template methods + +Written by Michael C. Miller. + +I invest time and resources providing this open source code, +please support me by dontating (see https://github.com/Makuna/NeoPixelBus) + +------------------------------------------------------------------------- +This file is part of the Makuna/NeoPixelBus library. + +NeoPixelBus is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as +published by the Free Software Foundation, either version 3 of +the License, or (at your option) any later version. + +NeoPixelBus is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with NeoPixel. If not, see +. +-------------------------------------------------------------------------*/ + +#pragma once + +#if defined(ARDUINO_ARCH_ESP32) && !defined(CONFIG_IDF_TARGET_ESP32C2) + +/* General Reference documentation for the APIs used in this implementation +LOW LEVEL: (what is actually used) +DOCS: https://docs.espressif.com/projects/esp-idf/en/latest/api-reference/peripherals/rmt.html +EXAMPLE: https://github.com/espressif/esp-idf/blob/826ff7186ae07dc81e960a8ea09ebfc5304bfb3b/examples/peripherals/rmt_tx/main/rmt_tx_main.c + +HIGHER LEVEL: +NO TRANSLATE SUPPORT so this was not used +NOTE: https://github.com/espressif/arduino-esp32/commit/50d142950d229b8fabca9b749dc4a5f2533bc426 +Esp32-hal-rmt.h +Esp32-hal-rmt.c +*/ + +#include + +// extern void AddLog(uint32_t loglevel, PGM_P formatP, ...); + +extern "C" +{ +#include +#include "driver/rmt_tx.h" +#include "driver/rmt_encoder.h" +#include "esp_check.h" +} + +#define RMT_LED_STRIP_RESOLUTION_HZ 10000000 // 10MHz resolution, 1 tick = 0.1us (led strip needs a high resolution) + +typedef struct { + uint32_t resolution; /*!< Encoder resolution, in Hz */ +} led_strip_encoder_config_t; + +typedef struct { + rmt_encoder_t base; + rmt_encoder_t *bytes_encoder; + rmt_encoder_t *copy_encoder; + int state; + rmt_symbol_word_t reset_code; +} rmt_led_strip_encoder_t; + +static size_t rmt_encode_led_strip(rmt_encoder_t *encoder, rmt_channel_handle_t channel, const void *primary_data, size_t data_size, rmt_encode_state_t *ret_state) +{ + rmt_led_strip_encoder_t *led_encoder = __containerof(encoder, rmt_led_strip_encoder_t, base); + rmt_encoder_handle_t bytes_encoder = led_encoder->bytes_encoder; + rmt_encoder_handle_t copy_encoder = led_encoder->copy_encoder; + rmt_encode_state_t session_state = RMT_ENCODING_RESET; + rmt_encode_state_t state = RMT_ENCODING_RESET; + size_t encoded_symbols = 0; + switch (led_encoder->state) { + case 0: // send RGB data + encoded_symbols += bytes_encoder->encode(bytes_encoder, channel, primary_data, data_size, &session_state); + if (session_state & RMT_ENCODING_COMPLETE) { + led_encoder->state = 1; // switch to next state when current encoding session finished + } + if (session_state & RMT_ENCODING_MEM_FULL) { + // static_cast(static_cast(a) | static_cast(b)); + state = static_cast(static_cast(state) | static_cast(RMT_ENCODING_MEM_FULL)); + goto out; // yield if there's no free space for encoding artifacts + } + // fall-through + case 1: // send reset code + encoded_symbols += copy_encoder->encode(copy_encoder, channel, &led_encoder->reset_code, + sizeof(led_encoder->reset_code), &session_state); + if (session_state & RMT_ENCODING_COMPLETE) { + led_encoder->state = RMT_ENCODING_RESET; // back to the initial encoding session + state = static_cast(static_cast(state) | static_cast(RMT_ENCODING_COMPLETE)); + } + if (session_state & RMT_ENCODING_MEM_FULL) { + state = static_cast(static_cast(state) | static_cast(RMT_ENCODING_MEM_FULL)); + goto out; // yield if there's no free space for encoding artifacts + } + } +out: + *ret_state = state; + return encoded_symbols; +} + +static esp_err_t rmt_del_led_strip_encoder(rmt_encoder_t *encoder) +{ + rmt_led_strip_encoder_t *led_encoder = __containerof(encoder, rmt_led_strip_encoder_t, base); + rmt_del_encoder(led_encoder->bytes_encoder); + rmt_del_encoder(led_encoder->copy_encoder); + delete led_encoder; + return ESP_OK; +} + +static esp_err_t rmt_led_strip_encoder_reset(rmt_encoder_t *encoder) +{ + rmt_led_strip_encoder_t *led_encoder = __containerof(encoder, rmt_led_strip_encoder_t, base); + rmt_encoder_reset(led_encoder->bytes_encoder); + rmt_encoder_reset(led_encoder->copy_encoder); + led_encoder->state = RMT_ENCODING_RESET; + return ESP_OK; +} + +esp_err_t rmt_new_led_strip_encoder(const led_strip_encoder_config_t *config, rmt_encoder_handle_t *ret_encoder/*, uint32_t bit0, uint32_t bit1*/) +{ + const char* TAG = "TEST_RMT"; + esp_err_t ret = ESP_OK; + rmt_led_strip_encoder_t *led_encoder = NULL; + uint32_t reset_ticks = config->resolution / 1000000 * 50 / 2; // reset code duration defaults to 50us + rmt_bytes_encoder_config_t bytes_encoder_config; + rmt_copy_encoder_config_t copy_encoder_config = {}; + rmt_symbol_word_t reset_code_config; + + + ESP_GOTO_ON_FALSE(config && ret_encoder, ESP_ERR_INVALID_ARG, err, TAG, "invalid argument"); + led_encoder = new rmt_led_strip_encoder_t(); + ESP_GOTO_ON_FALSE(led_encoder, ESP_ERR_NO_MEM, err, TAG, "no mem for led strip encoder"); + led_encoder->base.encode = rmt_encode_led_strip; + led_encoder->base.del = rmt_del_led_strip_encoder; + led_encoder->base.reset = rmt_led_strip_encoder_reset; + // different led strip might have its own timing requirements, following parameter is for WS2812 + bytes_encoder_config.bit0.level0 = 1; + bytes_encoder_config.bit0.duration0 = 0.3 * config->resolution / 1000000; // T0H=0.3us + bytes_encoder_config.bit0.level1 = 0; + bytes_encoder_config.bit0.duration1 = 0.9 * config->resolution / 1000000; // T0L=0.9us + bytes_encoder_config.bit1.level0 = 1; + bytes_encoder_config.bit1.duration0 = 0.9 * config->resolution / 1000000; // T0H=0.3us + bytes_encoder_config.bit1.level1 = 0; + bytes_encoder_config.bit1.duration1 = 0.3 * config->resolution / 1000000; // T0L=0.9us + bytes_encoder_config.flags.msb_first = 1; // WS2812 transfer bit order: G7...G0R7...R0B7...B0 + + ESP_GOTO_ON_ERROR(rmt_new_bytes_encoder(&bytes_encoder_config, &led_encoder->bytes_encoder), err, TAG, "create bytes encoder failed"); + ESP_GOTO_ON_ERROR(rmt_new_copy_encoder(©_encoder_config, &led_encoder->copy_encoder), err, TAG, "create copy encoder failed"); + + reset_code_config.level0 = 0; + reset_code_config.duration0 = reset_ticks; + reset_code_config.level1 = 0; + reset_code_config.duration1 = reset_ticks; + led_encoder->reset_code = reset_code_config; + *ret_encoder = &led_encoder->base; + return ret; +err: + // AddLog(2,"RMT:could not init led decoder"); + if (led_encoder) { + if (led_encoder->bytes_encoder) { + rmt_del_encoder(led_encoder->bytes_encoder); + } + if (led_encoder->copy_encoder) { + rmt_del_encoder(led_encoder->copy_encoder); + } + delete led_encoder; + } + return ret; +} + +#define NEOPIXELBUS_RMT_INT_FLAGS (ESP_INTR_FLAG_LOWMED) + +class NeoEsp32RmtSpeed +{ +public: +// next section is probably not needed anymore for IDF 5.1 + // ClkDiv of 2 provides for good resolution and plenty of reset resolution; but + // a ClkDiv of 1 will provide enough space for the longest reset and does show + // little better pulse accuracy + const static uint8_t RmtClockDivider = 2; + + inline constexpr static uint32_t FromNs(uint32_t ns) + { + return ns / NsPerRmtTick; + } + +protected: + const static uint32_t RmtCpu = 80000000L; // 80 mhz RMT clock + const static uint32_t NsPerSecond = 1000000000L; + const static uint32_t RmtTicksPerSecond = (RmtCpu / RmtClockDivider); + const static uint32_t NsPerRmtTick = (NsPerSecond / RmtTicksPerSecond); // about 25 +// end of deprecated section + +}; + +class NeoEsp32RmtSpeedBase : public NeoEsp32RmtSpeed +{ +public: + // this is used rather than the rmt_symbol_word_t as you can't correctly initialize + // it as a static constexpr within the template + inline constexpr static uint32_t Item32Val(uint16_t nsHigh, uint16_t nsLow) + { + return (FromNs(nsLow) << 16) | (1 << 15) | (FromNs(nsHigh)); + } +}; + +class NeoEsp32RmtInvertedSpeedBase : public NeoEsp32RmtSpeed +{ +public: + // this is used rather than the rmt_symbol_word_t as you can't correctly initialize + // it as a static constexpr within the template + inline constexpr static uint32_t Item32Val(uint16_t nsHigh, uint16_t nsLow) + { + return (FromNs(nsLow) << 16) | (1 << 31) | (FromNs(nsHigh)); + } +}; + +class NeoEsp32RmtSpeedWs2811 : public NeoEsp32RmtSpeedBase +{ +public: + const static DRAM_ATTR uint32_t RmtBit0 = Item32Val(300, 950); + const static DRAM_ATTR uint32_t RmtBit1 = Item32Val(900, 350); + const static DRAM_ATTR uint16_t RmtDurationReset = FromNs(300000); // 300us +}; + +class NeoEsp32RmtSpeedWs2812x : public NeoEsp32RmtSpeedBase +{ +public: + const uint32_t RmtBit0 = Item32Val(400, 850); + const uint32_t RmtBit1 = Item32Val(800, 450); + const static DRAM_ATTR uint16_t RmtDurationReset = FromNs(300000); // 300us +}; + +class NeoEsp32RmtSpeedSk6812 : public NeoEsp32RmtSpeedBase +{ +public: + const static DRAM_ATTR uint32_t RmtBit0 = Item32Val(400, 850); + const static DRAM_ATTR uint32_t RmtBit1 = Item32Val(800, 450); + const static DRAM_ATTR uint16_t RmtDurationReset = FromNs(80000); // 80us +}; + +// normal is inverted signal +class NeoEsp32RmtSpeedTm1814 : public NeoEsp32RmtInvertedSpeedBase +{ +public: + const static DRAM_ATTR uint32_t RmtBit0 = Item32Val(360, 890); + const static DRAM_ATTR uint32_t RmtBit1 = Item32Val(720, 530); + const static DRAM_ATTR uint16_t RmtDurationReset = FromNs(200000); // 200us +}; + +// normal is inverted signal +class NeoEsp32RmtSpeedTm1829 : public NeoEsp32RmtInvertedSpeedBase +{ +public: + const static DRAM_ATTR uint32_t RmtBit0 = Item32Val(300, 900); + const static DRAM_ATTR uint32_t RmtBit1 = Item32Val(800, 400); + const static DRAM_ATTR uint16_t RmtDurationReset = FromNs(200000); // 200us +}; + +// normal is inverted signal +class NeoEsp32RmtSpeedTm1914 : public NeoEsp32RmtInvertedSpeedBase +{ +public: + const static DRAM_ATTR uint32_t RmtBit0 = Item32Val(360, 890); + const static DRAM_ATTR uint32_t RmtBit1 = Item32Val(720, 530); + const static DRAM_ATTR uint16_t RmtDurationReset = FromNs(200000); // 200us +}; + +class NeoEsp32RmtSpeed800Kbps : public NeoEsp32RmtSpeedBase +{ +public: + const static DRAM_ATTR uint32_t RmtBit0 = Item32Val(400, 850); + const static DRAM_ATTR uint32_t RmtBit1 = Item32Val(800, 450); + const static DRAM_ATTR uint16_t RmtDurationReset = FromNs(50000); // 50us +}; + +class NeoEsp32RmtSpeed400Kbps : public NeoEsp32RmtSpeedBase +{ +public: + const static DRAM_ATTR uint32_t RmtBit0 = Item32Val(800, 1700); + const static DRAM_ATTR uint32_t RmtBit1 = Item32Val(1600, 900); + const static DRAM_ATTR uint16_t RmtDurationReset = FromNs(50000); // 50us +}; + +class NeoEsp32RmtSpeedApa106 : public NeoEsp32RmtSpeedBase +{ +public: + const static DRAM_ATTR uint32_t RmtBit0 = Item32Val(350, 1350); + const static DRAM_ATTR uint32_t RmtBit1 = Item32Val(1350, 350); + const static DRAM_ATTR uint16_t RmtDurationReset = FromNs(50000); // 50us +}; + +class NeoEsp32RmtSpeedTx1812 : public NeoEsp32RmtSpeedBase +{ +public: + const static DRAM_ATTR uint32_t RmtBit0 = Item32Val(300, 600); + const static DRAM_ATTR uint32_t RmtBit1 = Item32Val(600, 300); + const static DRAM_ATTR uint16_t RmtDurationReset = FromNs(80000); // 80us +}; + +class NeoEsp32RmtInvertedSpeedWs2811 : public NeoEsp32RmtInvertedSpeedBase +{ +public: + const static DRAM_ATTR uint32_t RmtBit0 = Item32Val(300, 950); + const static DRAM_ATTR uint32_t RmtBit1 = Item32Val(900, 350); + const static DRAM_ATTR uint16_t RmtDurationReset = FromNs(300000); // 300us +}; + +class NeoEsp32RmtInvertedSpeedWs2812x : public NeoEsp32RmtInvertedSpeedBase +{ +public: + const static DRAM_ATTR uint32_t RmtBit0 = Item32Val(400, 850); + const static DRAM_ATTR uint32_t RmtBit1 = Item32Val(800, 450); + const static DRAM_ATTR uint16_t RmtDurationReset = FromNs(300000); // 300us +}; + +class NeoEsp32RmtInvertedSpeedSk6812 : public NeoEsp32RmtInvertedSpeedBase +{ +public: + const static DRAM_ATTR uint32_t RmtBit0 = Item32Val(400, 850); + const static DRAM_ATTR uint32_t RmtBit1 = Item32Val(800, 450); + const static DRAM_ATTR uint16_t RmtDurationReset = FromNs(80000); // 80us +}; + +// normal is inverted signal +class NeoEsp32RmtInvertedSpeedTm1814 : public NeoEsp32RmtSpeedBase +{ +public: + const static DRAM_ATTR uint32_t RmtBit0 = Item32Val(360, 890); + const static DRAM_ATTR uint32_t RmtBit1 = Item32Val(720, 530); + const static DRAM_ATTR uint16_t RmtDurationReset = FromNs(200000); // 200us +}; + +// normal is inverted signal +class NeoEsp32RmtInvertedSpeedTm1829 : public NeoEsp32RmtSpeedBase +{ +public: + const static DRAM_ATTR uint32_t RmtBit0 = Item32Val(300, 900); + const static DRAM_ATTR uint32_t RmtBit1 = Item32Val(800, 400); + const static DRAM_ATTR uint16_t RmtDurationReset = FromNs(200000); // 200us +}; + +// normal is inverted signal +class NeoEsp32RmtInvertedSpeedTm1914 : public NeoEsp32RmtSpeedBase +{ +public: + const static DRAM_ATTR uint32_t RmtBit0 = Item32Val(360, 890); + const static DRAM_ATTR uint32_t RmtBit1 = Item32Val(720, 530); + const static DRAM_ATTR uint16_t RmtDurationReset = FromNs(200000); // 200us +}; + +class NeoEsp32RmtInvertedSpeed800Kbps : public NeoEsp32RmtInvertedSpeedBase +{ +public: + const static DRAM_ATTR uint32_t RmtBit0 = Item32Val(400, 850); + const static DRAM_ATTR uint32_t RmtBit1 = Item32Val(800, 450); + const static DRAM_ATTR uint16_t RmtDurationReset = FromNs(50000); // 50us +}; + +class NeoEsp32RmtInvertedSpeed400Kbps : public NeoEsp32RmtInvertedSpeedBase +{ +public: + const static DRAM_ATTR uint32_t RmtBit0 = Item32Val(800, 1700); + const static DRAM_ATTR uint32_t RmtBit1 = Item32Val(1600, 900); + const static DRAM_ATTR uint16_t RmtDurationReset = FromNs(50000); // 50us +}; + +class NeoEsp32RmtInvertedSpeedApa106 : public NeoEsp32RmtInvertedSpeedBase +{ +public: + const static DRAM_ATTR uint32_t RmtBit0 = Item32Val(350, 1350); + const static DRAM_ATTR uint32_t RmtBit1 = Item32Val(1350, 350); + const static DRAM_ATTR uint16_t RmtDurationReset = FromNs(50000); // 50us +}; + +class NeoEsp32RmtInvertedSpeedTx1812 : public NeoEsp32RmtInvertedSpeedBase +{ +public: + const static DRAM_ATTR uint32_t RmtBit0 = Item32Val(300, 600); + const static DRAM_ATTR uint32_t RmtBit1 = Item32Val(600, 300); + const static DRAM_ATTR uint16_t RmtDurationReset = FromNs(80000); // 80us +}; + +class NeoEsp32RmtChannel0 +{ +public: + NeoEsp32RmtChannel0() {}; + rmt_channel_handle_t RmtChannelNumber = NULL; +}; + +class NeoEsp32RmtChannel1 +{ +public: + NeoEsp32RmtChannel1() {}; + + rmt_channel_handle_t RmtChannelNumber = NULL; +}; + +#if !defined(CONFIG_IDF_TARGET_ESP32C6) // C6 only 2 RMT channels ?? +class NeoEsp32RmtChannel2 +{ +public: + NeoEsp32RmtChannel2() {}; + + rmt_channel_handle_t RmtChannelNumber = NULL; +}; + +class NeoEsp32RmtChannel3 +{ +public: + NeoEsp32RmtChannel3() {}; + +protected: + rmt_channel_handle_t RmtChannelNumber = NULL; +}; +#endif // !defined(CONFIG_IDF_TARGET_ESP32C6) +#if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32C6) + +class NeoEsp32RmtChannel4 +{ +public: + NeoEsp32RmtChannel4() {}; + + rmt_channel_handle_t RmtChannelNumber = NULL; +}; + +class NeoEsp32RmtChannel5 +{ +public: + NeoEsp32RmtChannel5() {}; + + rmt_channel_handle_t RmtChannelNumber = NULL; +}; + +class NeoEsp32RmtChannel6 +{ +public: + NeoEsp32RmtChannel6() {}; + + rmt_channel_handle_t RmtChannelNumber = NULL; +}; + +class NeoEsp32RmtChannel7 +{ +public: + NeoEsp32RmtChannel7() {}; + + rmt_channel_handle_t RmtChannelNumber = NULL; +}; + +#endif + +// dynamic channel support +class NeoEsp32RmtChannelN +{ +public: + NeoEsp32RmtChannelN(NeoBusChannel channel) : + RmtChannelNumber(RmtChannelNumber) + { + RmtChannelNumber = NULL; + }; + NeoEsp32RmtChannelN() = delete; // no default constructor + rmt_channel_handle_t RmtChannelNumber = NULL; +}; + +template class NeoEsp32RmtMethodBase +{ +public: + typedef NeoNoSettings SettingsObject; + + NeoEsp32RmtMethodBase(uint8_t pin, uint16_t pixelCount, size_t elementSize, size_t settingsSize) : + _sizeData(pixelCount * elementSize + settingsSize), + _pin(pin) + { + construct(); + } + + NeoEsp32RmtMethodBase(uint8_t pin, uint16_t pixelCount, size_t elementSize, size_t settingsSize, NeoBusChannel channel) : + _sizeData(pixelCount* elementSize + settingsSize), + _pin(pin), + _channel(channel) + { + construct(); + } + + ~NeoEsp32RmtMethodBase() + { + // wait until the last send finishes before destructing everything + // arbitrary time out of 10 seconds + + ESP_ERROR_CHECK_WITHOUT_ABORT(rmt_tx_wait_all_done(_channel.RmtChannelNumber, 10000 / portTICK_PERIOD_MS)); + ESP_ERROR_CHECK( rmt_del_channel(_channel.RmtChannelNumber)); + + gpio_matrix_out(_pin, 0x100, false, false); + pinMode(_pin, INPUT); + + free(_dataEditing); + free(_dataSending); + } + + + bool IsReadyToUpdate() const + { + return (ESP_OK == rmt_tx_wait_all_done(_channel.RmtChannelNumber, 0)); + } + + void Initialize() + { + esp_err_t ret = ESP_OK; + rmt_tx_channel_config_t config = {}; + config.clk_src = RMT_CLK_SRC_DEFAULT; + config.gpio_num = static_cast(_pin); + config.mem_block_symbols = 64; // memory block size, 64 * 4 = 256 Bytes + config.resolution_hz = RMT_LED_STRIP_RESOLUTION_HZ; // 1 MHz tick resolution, i.e., 1 tick = 1 µs + config.trans_queue_depth = 4; // set the number of transactions that can pend in the background + config.flags.invert_out = false; // do not invert output signal + config.flags.with_dma = false; // do not need DMA backend + + ret += rmt_new_tx_channel(&config,&_channel.RmtChannelNumber); + led_strip_encoder_config_t encoder_config = {}; + encoder_config.resolution = RMT_LED_STRIP_RESOLUTION_HZ; + + _tx_config.loop_count = 0; //no loop + + ret += rmt_new_led_strip_encoder(&encoder_config, &_led_encoder); + + // ESP_LOGI(TAG, "Enable RMT TX channel"); + ret += rmt_enable(_channel.RmtChannelNumber); + // AddLog(2,"RMT:initialized with error code: %u on pin: %u",ret, _pin); + } + + void Update(bool maintainBufferConsistency) + { + // AddLog(2,".."); + // wait for not actively sending data + // this will time out at 10 seconds, an arbitrarily long period of time + // and do nothing if this happens + + if (ESP_OK == ESP_ERROR_CHECK_WITHOUT_ABORT(rmt_tx_wait_all_done(_channel.RmtChannelNumber, 10000 / portTICK_PERIOD_MS))) + { + // AddLog(2,"__ %u", _sizeData); + // now start the RMT transmit with the editing buffer before we swap + // const uint8_t pixels[3] = {100,100,100}; + esp_err_t ret = rmt_transmit(_channel.RmtChannelNumber, _led_encoder, _dataEditing, _sizeData, &_tx_config); // 3 for _sizeData + // esp_err_t ret = rmt_transmit(_channel.RmtChannelNumber, _led_encoder, pixels, 3, &_tx_config); + // AddLog(2,"rmt_transmit: %u", ret); + if (maintainBufferConsistency) + { + // copy editing to sending, + // this maintains the contract that "colors present before will + // be the same after", otherwise GetPixelColor will be inconsistent + memcpy(_dataSending, _dataEditing, _sizeData); + } + + // swap so the user can modify without affecting the async operation + std::swap(_dataSending, _dataEditing); + } + } + + uint8_t* getData() const + { + return _dataEditing; + }; + + size_t getDataSize() const + { + return _sizeData; + } + + void applySettings(const SettingsObject& settings) + { + } + +private: + const size_t _sizeData; // Size of '_data*' buffers + const uint8_t _pin; // output pin number + + rmt_transmit_config_t _tx_config = {}; + rmt_encoder_handle_t _led_encoder = nullptr; + + T_CHANNEL _channel; // holds instance for multi channel support + + + // Holds data stream which include LED color values and other settings as needed + uint8_t* _dataEditing; // exposed for get and set + uint8_t* _dataSending; // used for async send using RMT + + + void construct() + { + // AddLog(2,"RMT:construct"); + _dataEditing = static_cast(malloc(_sizeData)); + // data cleared later in Begin() + + _dataSending = static_cast(malloc(_sizeData)); + // no need to initialize it, it gets overwritten on every send + } +}; + +// normal +typedef NeoEsp32RmtMethodBase NeoEsp32RmtNWs2811Method; +typedef NeoEsp32RmtMethodBase NeoEsp32RmtNWs2812xMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32RmtNSk6812Method; +typedef NeoEsp32RmtMethodBase NeoEsp32RmtNTm1814Method; +typedef NeoEsp32RmtMethodBase NeoEsp32RmtNTm1829Method; +typedef NeoEsp32RmtMethodBase NeoEsp32RmtNTm1914Method; +typedef NeoEsp32RmtMethodBase NeoEsp32RmtNApa106Method; +typedef NeoEsp32RmtMethodBase NeoEsp32RmtNTx1812Method; +typedef NeoEsp32RmtMethodBase NeoEsp32RmtN800KbpsMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32RmtN400KbpsMethod; + +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt0Ws2811Method; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt0Ws2812xMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt0Sk6812Method; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt0Tm1814Method; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt0Tm1829Method; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt0Tm1914Method; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt0Apa106Method; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt0Tx1812Method; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt0800KbpsMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt0400KbpsMethod; + +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt1Ws2811Method; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt1Ws2812xMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt1Sk6812Method; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt1Tm1814Method; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt1Tm1829Method; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt1Tm1914Method; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt1Apa106Method; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt1Tx1812Method; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt1800KbpsMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt1400KbpsMethod; + +#if !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32C6) + +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt2Ws2811Method; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt2Ws2812xMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt2Sk6812Method; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt2Tm1814Method; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt2Tm1829Method; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt2Tm1914Method; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt2Apa106Method; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt2Tx1812Method; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt2800KbpsMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt2400KbpsMethod; + +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt3Ws2811Method; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt3Ws2812xMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt3Sk6812Method; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt3Tm1814Method; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt3Tm1829Method; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt3Tm1914Method; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt3Apa106Method; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt3Tx1812Method; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt3800KbpsMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt3400KbpsMethod; + +#if !defined(CONFIG_IDF_TARGET_ESP32S2) + +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt4Ws2811Method; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt4Ws2812xMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt4Sk6812Method; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt4Tm1814Method; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt4Tm1829Method; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt4Tm1914Method; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt4Apa106Method; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt4Tx1812Method; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt4800KbpsMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt4400KbpsMethod; + +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt5Ws2811Method; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt5Ws2812xMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt5Sk6812Method; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt5Tm1814Method; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt5Tm1829Method; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt5Tm1914Method; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt5Apa106Method; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt5Tx1812Method; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt5800KbpsMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt5400KbpsMethod; + +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt6Ws2811Method; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt6Ws2812xMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt6Sk6812Method; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt6Tm1814Method; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt6Tm1829Method; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt6Tm1914Method; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt6Apa106Method; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt6Tx1812Method; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt6800KbpsMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt6400KbpsMethod; + +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt7Ws2811Method; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt7Ws2812xMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt7Sk6812Method; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt7Tm1814Method; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt7Tm1829Method; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt7Tm1914Method; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt7Apa106Method; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt7Tx1812Method; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt7800KbpsMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt7400KbpsMethod; + +#endif // !defined(CONFIG_IDF_TARGET_ESP32S2) +#endif // !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32C3) + +// inverted +typedef NeoEsp32RmtMethodBase NeoEsp32RmtNWs2811InvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32RmtNWs2812xInvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32RmtNSk6812InvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32RmtNTm1814InvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32RmtNTm1829InvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32RmtNTm1914InvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32RmtNApa106InvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32RmtNTx1812InvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32RmtN800KbpsInvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32RmtN400KbpsInvertedMethod; + +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt0Ws2811InvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt0Ws2812xInvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt0Sk6812InvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt0Tm1814InvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt0Tm1829InvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt0Tm1914InvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt0Apa106InvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt0Tx1812InvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt0800KbpsInvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt0400KbpsInvertedMethod; + +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt1Ws2811InvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt1Ws2812xInvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt1Sk6812InvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt1Tm1814InvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt1Tm1829InvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt1Tm1914InvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt1Apa106InvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt1Tx1812InvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt1800KbpsInvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt1400KbpsInvertedMethod; + +#if !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32C6) + +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt2Ws2811InvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt2Ws2812xInvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt2Sk6812InvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt2Tm1814InvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt2Tm1829InvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt2Tm1914InvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt2Apa106InvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt2Tx1812InvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt2800KbpsInvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt2400KbpsInvertedMethod; + +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt3Ws2811InvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt3Ws2812xInvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt3Sk6812InvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt3Tm1814InvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt3Tm1829InvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt3Tm1914InvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt3Apa106InvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt3Tx1812InvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt3800KbpsInvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt3400KbpsInvertedMethod; + +#if !defined(CONFIG_IDF_TARGET_ESP32S2) + +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt4Ws2811InvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt4Ws2812xInvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt4Sk6812InvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt4Tm1814InvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt4Tm1829InvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt4Tm1914InvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt4Apa106InvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt4Tx1812InvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt4800KbpsInvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt4400KbpsInvertedMethod; + +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt5Ws2811InvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt5Ws2812xInvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt5Sk6812InvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt5Tm1814InvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt5Tm1829InvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt5Tm1914InvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt5Apa106InvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt5Tx1812InvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt5800KbpsInvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt5400KbpsInvertedMethod; + +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt6Ws2811InvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt6Ws2812xInvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt6Sk6812InvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt6Tm1814InvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt6Tm1829InvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt6Tm1914InvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt6Apa106InvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt6Tx1812InvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt6800KbpsInvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt6400KbpsInvertedMethod; + +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt7Ws2811InvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt7Ws2812xInvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt7Sk6812InvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt7Tm1814InvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt7Tm1829InvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt7Tm1914InvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt7Apa106InvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt7Tx1812InvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt7800KbpsInvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt7400KbpsInvertedMethod; + +#endif // !defined(CONFIG_IDF_TARGET_ESP32S2) +#endif // !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32C6) + + +#if defined(NEOPIXEL_ESP32_RMT_DEFAULT) || defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32C6) + +// Normally I2s method is the default, defining NEOPIXEL_ESP32_RMT_DEFAULT +// will switch to use RMT as the default method +// The ESP32S2 & ESP32C3 will always defualt to RMT + +#if defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32C6) + +// RMT channel 1 method is the default method for Esp32S2 & Esp32C3 +typedef NeoEsp32Rmt1Ws2812xMethod NeoWs2813Method; +typedef NeoEsp32Rmt1Ws2812xMethod NeoWs2812xMethod; +typedef NeoEsp32Rmt1800KbpsMethod NeoWs2812Method; +typedef NeoEsp32Rmt1Ws2812xMethod NeoWs2811Method; +typedef NeoEsp32Rmt1Sk6812Method NeoSk6812Method; +typedef NeoEsp32Rmt1Tm1814Method NeoTm1814Method; +typedef NeoEsp32Rmt1Tm1829Method NeoTm1829Method; +typedef NeoEsp32Rmt1Tm1914Method NeoTm1914Method; +typedef NeoEsp32Rmt1Sk6812Method NeoLc8812Method; +typedef NeoEsp32Rmt1Apa106Method NeoApa106Method; +typedef NeoEsp32Rmt1Tx1812Method NeoTx1812Method; + +typedef NeoEsp32Rmt1Ws2812xMethod Neo800KbpsMethod; +typedef NeoEsp32Rmt1400KbpsMethod Neo400KbpsMethod; + +typedef NeoEsp32Rmt1Ws2812xInvertedMethod NeoWs2813InvertedMethod; +typedef NeoEsp32Rmt1Ws2812xInvertedMethod NeoWs2812xInvertedMethod; +typedef NeoEsp32Rmt1Ws2812xInvertedMethod NeoWs2811InvertedMethod; +typedef NeoEsp32Rmt1800KbpsInvertedMethod NeoWs2812InvertedMethod; +typedef NeoEsp32Rmt1Sk6812InvertedMethod NeoSk6812InvertedMethod; +typedef NeoEsp32Rmt1Tm1814InvertedMethod NeoTm1814InvertedMethod; +typedef NeoEsp32Rmt1Tm1829InvertedMethod NeoTm1829InvertedMethod; +typedef NeoEsp32Rmt1Tm1914InvertedMethod NeoTm1914InvertedMethod; +typedef NeoEsp32Rmt1Sk6812InvertedMethod NeoLc8812InvertedMethod; +typedef NeoEsp32Rmt1Apa106InvertedMethod NeoApa106InvertedMethod; +typedef NeoEsp32Rmt1Tx1812InvertedMethod NeoTx1812InvertedMethod; + +typedef NeoEsp32Rmt1Ws2812xInvertedMethod Neo800KbpsInvertedMethod; +typedef NeoEsp32Rmt1400KbpsInvertedMethod Neo400KbpsInvertedMethod; + +#else // defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32C3) + +// RMT channel 6 method is the default method for Esp32 +typedef NeoEsp32Rmt6Ws2812xMethod NeoWs2813Method; +typedef NeoEsp32Rmt6Ws2812xMethod NeoWs2812xMethod; +typedef NeoEsp32Rmt6800KbpsMethod NeoWs2812Method; +typedef NeoEsp32Rmt6Ws2812xMethod NeoWs2811Method; +typedef NeoEsp32Rmt6Sk6812Method NeoSk6812Method; +typedef NeoEsp32Rmt6Tm1814Method NeoTm1814Method; +typedef NeoEsp32Rmt6Tm1829Method NeoTm1829Method; +typedef NeoEsp32Rmt6Tm1914Method NeoTm1914Method; +typedef NeoEsp32Rmt6Sk6812Method NeoLc8812Method; +typedef NeoEsp32Rmt6Apa106Method NeoApa106Method; +typedef NeoEsp32Rmt6Tx1812Method NeoTx1812Method; + +typedef NeoEsp32Rmt6Ws2812xMethod Neo800KbpsMethod; +typedef NeoEsp32Rmt6400KbpsMethod Neo400KbpsMethod; + +typedef NeoEsp32Rmt6Ws2812xInvertedMethod NeoWs2813InvertedMethod; +typedef NeoEsp32Rmt6Ws2812xInvertedMethod NeoWs2812xInvertedMethod; +typedef NeoEsp32Rmt6Ws2812xInvertedMethod NeoWs2811InvertedMethod; +typedef NeoEsp32Rmt6800KbpsInvertedMethod NeoWs2812InvertedMethod; +typedef NeoEsp32Rmt6Sk6812InvertedMethod NeoSk6812InvertedMethod; +typedef NeoEsp32Rmt6Tm1814InvertedMethod NeoTm1814InvertedMethod; +typedef NeoEsp32Rmt6Tm1829InvertedMethod NeoTm1829InvertedMethod; +typedef NeoEsp32Rmt6Tm1914InvertedMethod NeoTm1914InvertedMethod; +typedef NeoEsp32Rmt6Sk6812InvertedMethod NeoLc8812InvertedMethod; +typedef NeoEsp32Rmt6Apa106InvertedMethod NeoApa106InvertedMethod; +typedef NeoEsp32Rmt6Tx1812InvertedMethod NeoTx1812InvertedMethod; + +typedef NeoEsp32Rmt6Ws2812xInvertedMethod Neo800KbpsInvertedMethod; +typedef NeoEsp32Rmt6400KbpsInvertedMethod Neo400KbpsInvertedMethod; + +#endif // defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32C6) + +#endif // defined(NEOPIXEL_ESP32_RMT_DEFAULT) || defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32C6) + +#endif diff --git a/lib/lib_basic/NeoPixelBus/src/internal/NeoEspBitBangMethod.cpp b/lib/lib_basic/NeoPixelBus/src/internal/NeoEspBitBangMethod.cpp index 32c069f3d..01499fe13 100644 --- a/lib/lib_basic/NeoPixelBus/src/internal/NeoEspBitBangMethod.cpp +++ b/lib/lib_basic/NeoPixelBus/src/internal/NeoEspBitBangMethod.cpp @@ -28,8 +28,11 @@ License along with NeoPixel. If not, see #include -// ESP32C3 I2S is not supported yet -#if !defined(CONFIG_IDF_TARGET_ESP32C3) +// ESP32C3 I2S is not supported yet +#if !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32C2) && !defined(CONFIG_IDF_TARGET_ESP32C6) +#if !defined(ARDUINO_ARCH_ESP8266) +#include "soc/gpio_periph.h" +#endif static inline uint32_t getCycleCount(void) { @@ -154,5 +157,5 @@ void IRAM_ATTR NeoEspBitBangBase_send_pixels_inv(uint8_t* pixels, uint8_t* end, } } -#endif // !defined(CONFIG_IDF_TARGET_ESP32C3) +#endif // !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32C2) && !defined(CONFIG_IDF_TARGET_ESP32C6) #endif // defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_ESP32) diff --git a/lib/lib_basic/NeoPixelBus/src/internal/NeoEspBitBangMethod.h b/lib/lib_basic/NeoPixelBus/src/internal/NeoEspBitBangMethod.h index bfbd13545..44f865488 100644 --- a/lib/lib_basic/NeoPixelBus/src/internal/NeoEspBitBangMethod.h +++ b/lib/lib_basic/NeoPixelBus/src/internal/NeoEspBitBangMethod.h @@ -29,7 +29,7 @@ License along with NeoPixel. If not, see #if defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_ESP32) // ESP32C3 I2S is not supported yet -#if !defined(CONFIG_IDF_TARGET_ESP32C3) +#if !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32C2) && !defined(CONFIG_IDF_TARGET_ESP32C6) #if defined(ARDUINO_ARCH_ESP8266) #include @@ -377,5 +377,5 @@ typedef NeoEsp8266BitBangSk6812InvertedMethod NeoEsp8266BitBangLc8812InvertedMet // ESP bitbang doesn't have defaults and should avoided except for testing -#endif // !defined(CONFIG_IDF_TARGET_ESP32C3) +#endif // !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32C2) && !defined(CONFIG_IDF_TARGET_ESP32C6) #endif // defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_ESP32)