From 4dcc08d0dade52ba1b021bbde2ae48636105b9e8 Mon Sep 17 00:00:00 2001 From: Damian Schneider Date: Thu, 1 Jan 2026 17:08:42 +0100 Subject: [PATCH 1/8] add new custom bus type: TM1815 --- wled00/FX.h | 2 +- wled00/bus_manager.cpp | 3 +- wled00/bus_manager.h | 7 +- wled00/bus_wrapper.h | 379 +++++++++++++++++++++------------- wled00/const.h | 3 +- wled00/data/settings_leds.htm | 2 +- 6 files changed, 247 insertions(+), 149 deletions(-) diff --git a/wled00/FX.h b/wled00/FX.h index bcbab69a59..204d397305 100644 --- a/wled00/FX.h +++ b/wled00/FX.h @@ -933,7 +933,7 @@ class WS2812FX { inline bool isUpdating() const { return !BusManager::canAllShow(); } // return true if the strip is being sent pixel updates inline bool isServicing() const { return _isServicing; } // returns true if strip.service() is executing inline bool hasWhiteChannel() const { return _hasWhiteChannel; } // returns true if strip contains separate white chanel - inline bool isOffRefreshRequired() const { return _isOffRefreshRequired; } // returns true if strip requires regular updates (i.e. TM1814 chipset) + inline bool isOffRefreshRequired() const { return _isOffRefreshRequired; } // returns true if strip requires regular updates (i.e. TM1814/TM1815 chipset) inline bool isSuspended() const { return _suspend; } // returns true if strip.service() execution is suspended inline bool needsUpdate() const { return _triggered; } // returns true if strip received a trigger() request diff --git a/wled00/bus_manager.cpp b/wled00/bus_manager.cpp index 4fa5c40a57..86ce3e104d 100644 --- a/wled00/bus_manager.cpp +++ b/wled00/bus_manager.cpp @@ -159,7 +159,7 @@ uint32_t Bus::autoWhiteCalc(uint32_t c) const { BusDigital::BusDigital(const BusConfig &bc, uint8_t nr) -: Bus(bc.type, bc.start, bc.autoWhite, bc.count, bc.reversed, (bc.refreshReq || bc.type == TYPE_TM1814)) +: Bus(bc.type, bc.start, bc.autoWhite, bc.count, bc.reversed, (bc.refreshReq || bc.type == (TYPE_TM1814 || TYPE_TM1815))) // TM1814/15 need refresh or they fall-back to a "demo mode" , _skip(bc.skipAmount) //sacrificial pixels , _colorOrder(bc.colorOrder) , _milliAmpsPerLed(bc.milliAmpsPerLed) @@ -372,6 +372,7 @@ std::vector BusDigital::getLEDTypes() { {TYPE_WS2812_RGB, "D", PSTR("WS281x")}, {TYPE_SK6812_RGBW, "D", PSTR("SK6812/WS2814 RGBW")}, {TYPE_TM1814, "D", PSTR("TM1814")}, + {TYPE_TM1815, "D", PSTR("TM1815")}, {TYPE_WS2811_400KHZ, "D", PSTR("400kHz")}, {TYPE_TM1829, "D", PSTR("TM1829")}, {TYPE_UCS8903, "D", PSTR("UCS8903")}, diff --git a/wled00/bus_manager.h b/wled00/bus_manager.h index 95772a443f..ec4e016342 100644 --- a/wled00/bus_manager.h +++ b/wled00/bus_manager.h @@ -173,8 +173,9 @@ class Bus { } static constexpr bool hasWhite(uint8_t type) { return (type >= TYPE_WS2812_1CH && type <= TYPE_WS2812_WWA) || - type == TYPE_SK6812_RGBW || type == TYPE_TM1814 || type == TYPE_UCS8904 || - type == TYPE_FW1906 || type == TYPE_WS2805 || type == TYPE_SM16825 || // digital types with white channel + type == TYPE_SK6812_RGBW || type == TYPE_TM1814 || type == TYPE_TM1815 || + type == TYPE_UCS8904 || type == TYPE_FW1906 || type == TYPE_WS2805 || + type == TYPE_SM16825 || // digital types with white channel (type > TYPE_ONOFF && type <= TYPE_ANALOG_5CH && type != TYPE_ANALOG_3CH) || // analog types with white channel type == TYPE_NET_DDP_RGBW || type == TYPE_NET_ARTNET_RGBW; // network types with white channel } @@ -192,7 +193,7 @@ class Bus { static constexpr bool isVirtual(uint8_t type) { return (type >= TYPE_VIRTUAL_MIN && type <= TYPE_VIRTUAL_MAX); } static constexpr bool isHub75(uint8_t type) { return (type >= TYPE_HUB75MATRIX_MIN && type <= TYPE_HUB75MATRIX_MAX); } static constexpr bool is16bit(uint8_t type) { return type == TYPE_UCS8903 || type == TYPE_UCS8904 || type == TYPE_SM16825; } - static constexpr bool mustRefresh(uint8_t type) { return type == TYPE_TM1814; } + static constexpr bool mustRefresh(uint8_t type) { return type == TYPE_TM1814 || type == TYPE_TM1815; } static constexpr int numPWMPins(uint8_t type) { return (type - 40); } static inline int16_t getCCT() { return _cct; } diff --git a/wled00/bus_wrapper.h b/wled00/bus_wrapper.h index b2ff947418..24be495a01 100644 --- a/wled00/bus_wrapper.h +++ b/wled00/bus_wrapper.h @@ -31,15 +31,15 @@ #define I_8266_DM_400_3 11 #define I_8266_BB_400_3 12 //TM1814 (RGBW) -#define I_8266_U0_TM1_4 13 -#define I_8266_U1_TM1_4 14 -#define I_8266_DM_TM1_4 15 -#define I_8266_BB_TM1_4 16 +#define I_8266_U0_TM1814_4 13 +#define I_8266_U1_TM1814_4 14 +#define I_8266_DM_TM1814_4 15 +#define I_8266_BB_TM1814_4 16 //TM1829 (RGB) -#define I_8266_U0_TM2_3 17 -#define I_8266_U1_TM2_3 18 -#define I_8266_DM_TM2_3 19 -#define I_8266_BB_TM2_3 20 +#define I_8266_U0_TM1829_3 17 +#define I_8266_U1_TM1829_3 18 +#define I_8266_DM_TM1829_3 19 +#define I_8266_BB_TM1829_3 20 //UCS8903 (RGB) #define I_8266_U0_UCS_3 21 #define I_8266_U1_UCS_3 22 @@ -87,11 +87,14 @@ #define I_32_RN_400_3 9 #define I_32_I2_400_3 10 //TM1814 (RGBW) -#define I_32_RN_TM1_4 13 -#define I_32_I2_TM1_4 14 +#define I_32_RN_TM1814_4 13 +#define I_32_I2_TM1814_4 14 +//TM1815 (RGBW) +#define I_32_RN_TM1815_4 15 +#define I_32_I2_TM1815_4 16 //TM1829 (RGB) -#define I_32_RN_TM2_3 17 -#define I_32_I2_TM2_3 18 +#define I_32_RN_TM1829_3 17 +#define I_32_I2_TM1829_3 18 //UCS8903 (RGB) #define I_32_RN_UCS_3 21 #define I_32_I2_UCS_3 22 @@ -134,6 +137,79 @@ #define I_HS_LPO_3 109 #define I_SS_LPO_3 110 +// RMT driver selection +#if !defined(WLED_USE_SHARED_RMT) && !defined(__riscv) +#include +#define NeoEsp32RmtMethod(x) NeoEsp32RmtHIN ## x ## Method +#define USE_NEOPIXELBUS_RMT_HI +#else +#include "internal/methods/NeoEsp32RmtMethod.h" // needed for custom RMT types +#define NeoEsp32RmtMethod(x) NeoEsp32RmtN ## x ## Method +#endif + +// special types and classes not officially supported by NPB + +// TM1815 is exactly half the speed of TM1814, normal is inverted signal compared to WS281x (low pulse timing, high idle/reset) +class NeoEsp32RmtSpeedTm1815 : public NeoEsp32RmtInvertedSpeedBase +{ +public: + const static DRAM_ATTR uint32_t RmtBit0 = Item32Val(740, 1780); + const static DRAM_ATTR uint32_t RmtBit1 = Item32Val(1440, 1060); + const static DRAM_ATTR uint16_t RmtDurationReset = FromNs(200000); // 200us + + static void IRAM_ATTR Translate(const void* src, + rmt_item32_t* dest, + size_t src_size, + size_t wanted_num, + size_t* translated_size, + size_t* item_num); +}; + +void NeoEsp32RmtSpeedTm1815::Translate(const void* src, + rmt_item32_t* dest, + size_t src_size, + size_t wanted_num, + size_t* translated_size, + size_t* item_num) +{ + _translate(src, dest, src_size, wanted_num, translated_size, item_num, + RmtBit0, RmtBit1, RmtDurationReset); +} + +class NeoBitsSpeedTm1815 : public NeoBitsSpeedBase +{ +public: + const static uint16_t BitSendTimeNs = 2500; + const static uint16_t ResetTimeUs = 200; +}; + +// special non-native I2S NPB methods +#ifdef ESP32 +// ESP32 RMT Methods +#ifdef USE_NEOPIXELBUS_RMT_HI +typedef NeoEsp32RmtHIMethodBase NeoEsp32RmtHINTm1815Method; +#else +typedef NeoEsp32RmtMethodBase NeoEsp32RmtNTm1815Method; +#endif +#if !defined(CONFIG_IDF_TARGET_ESP32C3) +// ESP32 I2S Methods +typedef NeoEsp32I2sMethodBase NeoEsp32I2s0Tm1815Method; +typedef NeoEsp32I2sMethodBase NeoEsp32I2s1Tm1815Method; +typedef NeoEsp32I2sXMethodBase NeoEsp32I2s0X8Tm1815Method; // user for S2 +typedef NeoEsp32I2sXMethodBase NeoEsp32I2s1X8Tm1815Method; // use for classic ESP32 (not defined for S2, can be defined for S3 but is not used) +#if defined(CONFIG_IDF_TARGET_ESP32S3) +typedef NeoEsp32LcdXMethodBase NeoEsp32LcdX8Tm1815Method; // S3 only +#endif +// I2S Aliases +#if defined(CONFIG_IDF_TARGET_ESP32S3) +typedef NeoEsp32LcdX8Tm1815Method X8Tm1815Method; +#elif defined(CONFIG_IDF_TARGET_ESP32S2) +typedef NeoEsp32I2s0X8Tm1815Method X8Tm1815Method; +#else // ESP32 classic +typedef NeoEsp32I2s1X8Tm1815Method X8Tm1815Method; +#endif +#endif // !CONFIG_IDF_TARGET_ESP32C3 +#endif // ESP32 // In the following NeoGammaNullMethod can be replaced with NeoGammaWLEDMethod to perform Gamma correction implicitly // unfortunately that may apply Gamma correction to pre-calculated palettes which is undesired @@ -156,15 +232,15 @@ #define B_8266_DM_400_3 NeoPixelBus //3 chan, esp8266, gpio3 #define B_8266_BB_400_3 NeoPixelBus //3 chan, esp8266, bb (any pin) //TM1814 (RGBW) -#define B_8266_U0_TM1_4 NeoPixelBus -#define B_8266_U1_TM1_4 NeoPixelBus -#define B_8266_DM_TM1_4 NeoPixelBus -#define B_8266_BB_TM1_4 NeoPixelBus +#define B_8266_U0_TM1814_4 NeoPixelBus +#define B_8266_U1_TM1814_4 NeoPixelBus +#define B_8266_DM_TM1814_4 NeoPixelBus +#define B_8266_BB_TM1814_4 NeoPixelBus //TM1829 (RGB) -#define B_8266_U0_TM2_3 NeoPixelBus -#define B_8266_U1_TM2_3 NeoPixelBus -#define B_8266_DM_TM2_3 NeoPixelBus -#define B_8266_BB_TM2_3 NeoPixelBus +#define B_8266_U0_TM1829_3 NeoPixelBus +#define B_8266_U1_TM1829_3 NeoPixelBus +#define B_8266_DM_TM1829_3 NeoPixelBus +#define B_8266_BB_TM1829_3 NeoPixelBus //UCS8903 #define B_8266_U0_UCS_3 NeoPixelBus //3 chan, esp8266, gpio1 #define B_8266_U1_UCS_3 NeoPixelBus //3 chan, esp8266, gpio2 @@ -216,6 +292,7 @@ typedef X8400KbpsMethod X1400KbpsMethod; typedef X8800KbpsMethod X1800KbpsMethod; typedef X8Tm1814Method X1Tm1814Method; + typedef X8Tm1815Method X1Tm1815Method; typedef X8Tm1829Method X1Tm1829Method; typedef X8Apa106Method X1Apa106Method; typedef X8Ws2805Method X1Ws2805Method; @@ -227,6 +304,7 @@ typedef NeoEsp32I2s0400KbpsMethod X1400KbpsMethod; typedef NeoEsp32I2s0800KbpsMethod X1800KbpsMethod; typedef NeoEsp32I2s0Tm1814Method X1Tm1814Method; + typedef NeoEsp32I2s0Tm1815Method X1Tm1815Method; typedef NeoEsp32I2s0Tm1829Method X1Tm1829Method; typedef NeoEsp32I2s0Apa106Method X1Apa106Method; typedef NeoEsp32I2s0Ws2805Method X1Ws2805Method; @@ -238,20 +316,13 @@ typedef NeoEsp32I2s1400KbpsMethod X1400KbpsMethod; typedef NeoEsp32I2s1800KbpsMethod X1800KbpsMethod; typedef NeoEsp32I2s1Tm1814Method X1Tm1814Method; + typedef NeoEsp32I2s1Tm1815Method X1Tm1815Method; typedef NeoEsp32I2s1Tm1829Method X1Tm1829Method; typedef NeoEsp32I2s1Apa106Method X1Apa106Method; typedef NeoEsp32I2s1Ws2805Method X1Ws2805Method; typedef NeoEsp32I2s1Tm1914Method X1Tm1914Method; #endif -// RMT driver selection -#if !defined(WLED_USE_SHARED_RMT) && !defined(__riscv) -#include -#define NeoEsp32RmtMethod(x) NeoEsp32RmtHIN ## x ## Method -#else -#define NeoEsp32RmtMethod(x) NeoEsp32RmtN ## x ## Method -#endif - //RGB #define B_32_RN_NEO_3 NeoPixelBus // ESP32, S2, S3, C3 //#define B_32_IN_NEO_3 NeoPixelBus // ESP32 (dynamic I2S selection) @@ -266,13 +337,17 @@ #define B_32_I2_400_3 NeoPixelBus #define B_32_IP_400_3 NeoPixelBus // parallel I2S //TM1814 (RGBW) -#define B_32_RN_TM1_4 NeoPixelBus -#define B_32_I2_TM1_4 NeoPixelBus -#define B_32_IP_TM1_4 NeoPixelBus // parallel I2S +#define B_32_RN_TM1814_4 NeoPixelBus +#define B_32_I2_TM1814_4 NeoPixelBus +#define B_32_IP_TM1814_4 NeoPixelBus // parallel I2S +//TM1815 (RGBW): half speed TM1814 +#define B_32_RN_TM1815_4 NeoPixelBus +#define B_32_I2_TM1815_4 NeoPixelBus +#define B_32_IP_TM1815_4 NeoPixelBus // parallel I2S //TM1829 (RGB) -#define B_32_RN_TM2_3 NeoPixelBus -#define B_32_I2_TM2_3 NeoPixelBus -#define B_32_IP_TM2_3 NeoPixelBus // parallel I2S +#define B_32_RN_TM1829_3 NeoPixelBus +#define B_32_I2_TM1829_3 NeoPixelBus +#define B_32_IP_TM1829_3 NeoPixelBus // parallel I2S //UCS8903 #define B_32_RN_UCS_3 NeoPixelBus #define B_32_I2_UCS_3 NeoPixelBus @@ -390,14 +465,14 @@ class PolyBus { case I_8266_U1_400_3: (static_cast(busPtr))->Begin(); break; case I_8266_DM_400_3: (static_cast(busPtr))->Begin(); break; case I_8266_BB_400_3: (static_cast(busPtr))->Begin(); break; - case I_8266_U0_TM1_4: beginTM1814(busPtr); break; - case I_8266_U1_TM1_4: beginTM1814(busPtr); break; - case I_8266_DM_TM1_4: beginTM1814(busPtr); break; - case I_8266_BB_TM1_4: beginTM1814(busPtr); break; - case I_8266_U0_TM2_3: (static_cast(busPtr))->Begin(); break; - case I_8266_U1_TM2_3: (static_cast(busPtr))->Begin(); break; - case I_8266_DM_TM2_3: (static_cast(busPtr))->Begin(); break; - case I_8266_BB_TM2_3: (static_cast(busPtr))->Begin(); break; + case I_8266_U0_TM1814_4: beginTM1814(busPtr); break; + case I_8266_U1_TM1814_4: beginTM1814(busPtr); break; + case I_8266_DM_TM1814_4: beginTM1814(busPtr); break; + case I_8266_BB_TM1814_4: beginTM1814(busPtr); break; + case I_8266_U0_TM1829_3: (static_cast(busPtr))->Begin(); break; + case I_8266_U1_TM1829_3: (static_cast(busPtr))->Begin(); break; + case I_8266_DM_TM1829_3: (static_cast(busPtr))->Begin(); break; + case I_8266_BB_TM1829_3: (static_cast(busPtr))->Begin(); break; case I_HS_DOT_3: beginDotStar(busPtr, -1, -1, -1, -1, clock_kHz); break; case I_HS_LPD_3: beginDotStar(busPtr, -1, -1, -1, -1, clock_kHz); break; case I_HS_LPO_3: beginDotStar(busPtr, -1, -1, -1, -1, clock_kHz); break; @@ -437,8 +512,9 @@ class PolyBus { case I_32_RN_NEO_3: (static_cast(busPtr))->Begin(); break; case I_32_RN_NEO_4: (static_cast(busPtr))->Begin(); break; case I_32_RN_400_3: (static_cast(busPtr))->Begin(); break; - case I_32_RN_TM1_4: beginTM1814(busPtr); break; - case I_32_RN_TM2_3: (static_cast(busPtr))->Begin(); break; + case I_32_RN_TM1814_4: beginTM1814(busPtr); break; + case I_32_RN_TM1815_4: beginTM1814(busPtr); break; // half speed TM1814, same init + case I_32_RN_TM1829_3: (static_cast(busPtr))->Begin(); break; case I_32_RN_UCS_3: (static_cast(busPtr))->Begin(); break; case I_32_RN_UCS_4: (static_cast(busPtr))->Begin(); break; case I_32_RN_FW6_5: (static_cast(busPtr))->Begin(); break; @@ -451,8 +527,9 @@ class PolyBus { case I_32_I2_NEO_3: if (_useParallelI2S) (static_cast(busPtr))->Begin(); else (static_cast(busPtr))->Begin(); break; case I_32_I2_NEO_4: if (_useParallelI2S) (static_cast(busPtr))->Begin(); else (static_cast(busPtr))->Begin(); break; case I_32_I2_400_3: if (_useParallelI2S) (static_cast(busPtr))->Begin(); else (static_cast(busPtr))->Begin(); break; - case I_32_I2_TM1_4: if (_useParallelI2S) beginTM1814(busPtr); else beginTM1814(busPtr); break; - case I_32_I2_TM2_3: if (_useParallelI2S) (static_cast(busPtr))->Begin(); else (static_cast(busPtr))->Begin(); break; + case I_32_I2_TM1814_4: if (_useParallelI2S) beginTM1814(busPtr); else beginTM1814(busPtr); break; + case I_32_I2_TM1815_4: if (_useParallelI2S) beginTM1814(busPtr); else beginTM1814(busPtr); break; // half speed TM1814, same init + case I_32_I2_TM1829_3: if (_useParallelI2S) (static_cast(busPtr))->Begin(); else (static_cast(busPtr))->Begin(); break; case I_32_I2_UCS_3: if (_useParallelI2S) (static_cast(busPtr))->Begin(); else (static_cast(busPtr))->Begin(); break; case I_32_I2_UCS_4: if (_useParallelI2S) (static_cast(busPtr))->Begin(); else (static_cast(busPtr))->Begin(); break; case I_32_I2_FW6_5: if (_useParallelI2S) (static_cast(busPtr))->Begin(); else (static_cast(busPtr))->Begin(); break; @@ -507,14 +584,14 @@ class PolyBus { case I_8266_U1_400_3: busPtr = new B_8266_U1_400_3(len, pins[0]); break; case I_8266_DM_400_3: busPtr = new B_8266_DM_400_3(len, pins[0]); break; case I_8266_BB_400_3: busPtr = new B_8266_BB_400_3(len, pins[0]); break; - case I_8266_U0_TM1_4: busPtr = new B_8266_U0_TM1_4(len, pins[0]); break; - case I_8266_U1_TM1_4: busPtr = new B_8266_U1_TM1_4(len, pins[0]); break; - case I_8266_DM_TM1_4: busPtr = new B_8266_DM_TM1_4(len, pins[0]); break; - case I_8266_BB_TM1_4: busPtr = new B_8266_BB_TM1_4(len, pins[0]); break; - case I_8266_U0_TM2_3: busPtr = new B_8266_U0_TM2_3(len, pins[0]); break; - case I_8266_U1_TM2_3: busPtr = new B_8266_U1_TM2_3(len, pins[0]); break; - case I_8266_DM_TM2_3: busPtr = new B_8266_DM_TM2_3(len, pins[0]); break; - case I_8266_BB_TM2_3: busPtr = new B_8266_BB_TM2_3(len, pins[0]); break; + case I_8266_U0_TM1814_4: busPtr = new B_8266_U0_TM1814_4(len, pins[0]); break; + case I_8266_U1_TM1814_4: busPtr = new B_8266_U1_TM1814_4(len, pins[0]); break; + case I_8266_DM_TM1814_4: busPtr = new B_8266_DM_TM1814_4(len, pins[0]); break; + case I_8266_BB_TM1814_4: busPtr = new B_8266_BB_TM1814_4(len, pins[0]); break; + case I_8266_U0_TM1829_3: busPtr = new B_8266_U0_TM1829_3(len, pins[0]); break; + case I_8266_U1_TM1829_3: busPtr = new B_8266_U1_TM1829_3(len, pins[0]); break; + case I_8266_DM_TM1829_3: busPtr = new B_8266_DM_TM1829_3(len, pins[0]); break; + case I_8266_BB_TM1829_3: busPtr = new B_8266_BB_TM1829_3(len, pins[0]); break; case I_8266_U0_UCS_3: busPtr = new B_8266_U0_UCS_3(len, pins[0]); break; case I_8266_U1_UCS_3: busPtr = new B_8266_U1_UCS_3(len, pins[0]); break; case I_8266_DM_UCS_3: busPtr = new B_8266_DM_UCS_3(len, pins[0]); break; @@ -549,8 +626,9 @@ class PolyBus { case I_32_RN_NEO_3: busPtr = new B_32_RN_NEO_3(len, pins[0], (NeoBusChannel)channel); break; case I_32_RN_NEO_4: busPtr = new B_32_RN_NEO_4(len, pins[0], (NeoBusChannel)channel); break; case I_32_RN_400_3: busPtr = new B_32_RN_400_3(len, pins[0], (NeoBusChannel)channel); break; - case I_32_RN_TM1_4: busPtr = new B_32_RN_TM1_4(len, pins[0], (NeoBusChannel)channel); break; - case I_32_RN_TM2_3: busPtr = new B_32_RN_TM2_3(len, pins[0], (NeoBusChannel)channel); break; + case I_32_RN_TM1814_4: busPtr = new B_32_RN_TM1814_4(len, pins[0], (NeoBusChannel)channel); break; + case I_32_RN_TM1815_4: busPtr = new B_32_RN_TM1815_4(len, pins[0], (NeoBusChannel)channel); break; + case I_32_RN_TM1829_3: busPtr = new B_32_RN_TM1829_3(len, pins[0], (NeoBusChannel)channel); break; case I_32_RN_UCS_3: busPtr = new B_32_RN_UCS_3(len, pins[0], (NeoBusChannel)channel); break; case I_32_RN_UCS_4: busPtr = new B_32_RN_UCS_4(len, pins[0], (NeoBusChannel)channel); break; case I_32_RN_APA106_3: busPtr = new B_32_RN_APA106_3(len, pins[0], (NeoBusChannel)channel); break; @@ -563,8 +641,9 @@ class PolyBus { case I_32_I2_NEO_3: if (_useParallelI2S) busPtr = new B_32_IP_NEO_3(len, pins[0]); else busPtr = new B_32_I2_NEO_3(len, pins[0]); break; case I_32_I2_NEO_4: if (_useParallelI2S) busPtr = new B_32_IP_NEO_4(len, pins[0]); else busPtr = new B_32_I2_NEO_4(len, pins[0]); break; case I_32_I2_400_3: if (_useParallelI2S) busPtr = new B_32_IP_400_3(len, pins[0]); else busPtr = new B_32_I2_400_3(len, pins[0]); break; - case I_32_I2_TM1_4: if (_useParallelI2S) busPtr = new B_32_IP_TM1_4(len, pins[0]); else busPtr = new B_32_I2_TM1_4(len, pins[0]); break; - case I_32_I2_TM2_3: if (_useParallelI2S) busPtr = new B_32_IP_TM2_3(len, pins[0]); else busPtr = new B_32_I2_TM2_3(len, pins[0]); break; + case I_32_I2_TM1814_4: if (_useParallelI2S) busPtr = new B_32_IP_TM1814_4(len, pins[0]); else busPtr = new B_32_I2_TM1814_4(len, pins[0]); break; + case I_32_I2_TM1815_4: if (_useParallelI2S) busPtr = new B_32_IP_TM1815_4(len, pins[0]); else busPtr = new B_32_I2_TM1815_4(len, pins[0]); break; + case I_32_I2_TM1829_3: if (_useParallelI2S) busPtr = new B_32_IP_TM1829_3(len, pins[0]); else busPtr = new B_32_I2_TM1829_3(len, pins[0]); break; case I_32_I2_UCS_3: if (_useParallelI2S) busPtr = new B_32_IP_UCS_3(len, pins[0]); else busPtr = new B_32_I2_UCS_3(len, pins[0]); break; case I_32_I2_UCS_4: if (_useParallelI2S) busPtr = new B_32_IP_UCS_4(len, pins[0]); else busPtr = new B_32_I2_UCS_4(len, pins[0]); break; case I_32_I2_APA106_3: if (_useParallelI2S) busPtr = new B_32_IP_APA106_3(len, pins[0]); else busPtr = new B_32_I2_APA106_3(len, pins[0]); break; @@ -606,14 +685,14 @@ class PolyBus { case I_8266_U1_400_3: (static_cast(busPtr))->Show(consistent); break; case I_8266_DM_400_3: (static_cast(busPtr))->Show(consistent); break; case I_8266_BB_400_3: (static_cast(busPtr))->Show(consistent); break; - case I_8266_U0_TM1_4: (static_cast(busPtr))->Show(consistent); break; - case I_8266_U1_TM1_4: (static_cast(busPtr))->Show(consistent); break; - case I_8266_DM_TM1_4: (static_cast(busPtr))->Show(consistent); break; - case I_8266_BB_TM1_4: (static_cast(busPtr))->Show(consistent); break; - case I_8266_U0_TM2_3: (static_cast(busPtr))->Show(consistent); break; - case I_8266_U1_TM2_3: (static_cast(busPtr))->Show(consistent); break; - case I_8266_DM_TM2_3: (static_cast(busPtr))->Show(consistent); break; - case I_8266_BB_TM2_3: (static_cast(busPtr))->Show(consistent); break; + case I_8266_U0_TM1814_4: (static_cast(busPtr))->Show(consistent); break; + case I_8266_U1_TM1814_4: (static_cast(busPtr))->Show(consistent); break; + case I_8266_DM_TM1814_4: (static_cast(busPtr))->Show(consistent); break; + case I_8266_BB_TM1814_4: (static_cast(busPtr))->Show(consistent); break; + case I_8266_U0_TM1829_3: (static_cast(busPtr))->Show(consistent); break; + case I_8266_U1_TM1829_3: (static_cast(busPtr))->Show(consistent); break; + case I_8266_DM_TM1829_3: (static_cast(busPtr))->Show(consistent); break; + case I_8266_BB_TM1829_3: (static_cast(busPtr))->Show(consistent); break; case I_8266_U0_UCS_3: (static_cast(busPtr))->Show(consistent); break; case I_8266_U1_UCS_3: (static_cast(busPtr))->Show(consistent); break; case I_8266_DM_UCS_3: (static_cast(busPtr))->Show(consistent); break; @@ -648,8 +727,9 @@ class PolyBus { case I_32_RN_NEO_3: (static_cast(busPtr))->Show(consistent); break; case I_32_RN_NEO_4: (static_cast(busPtr))->Show(consistent); break; case I_32_RN_400_3: (static_cast(busPtr))->Show(consistent); break; - case I_32_RN_TM1_4: (static_cast(busPtr))->Show(consistent); break; - case I_32_RN_TM2_3: (static_cast(busPtr))->Show(consistent); break; + case I_32_RN_TM1814_4: (static_cast(busPtr))->Show(consistent); break; + case I_32_RN_TM1815_4: (static_cast(busPtr))->Show(consistent); break; + case I_32_RN_TM1829_3: (static_cast(busPtr))->Show(consistent); break; case I_32_RN_UCS_3: (static_cast(busPtr))->Show(consistent); break; case I_32_RN_UCS_4: (static_cast(busPtr))->Show(consistent); break; case I_32_RN_APA106_3: (static_cast(busPtr))->Show(consistent); break; @@ -662,8 +742,9 @@ class PolyBus { case I_32_I2_NEO_3: if (_useParallelI2S) (static_cast(busPtr))->Show(consistent); else (static_cast(busPtr))->Show(consistent); break; case I_32_I2_NEO_4: if (_useParallelI2S) (static_cast(busPtr))->Show(consistent); else (static_cast(busPtr))->Show(consistent); break; case I_32_I2_400_3: if (_useParallelI2S) (static_cast(busPtr))->Show(consistent); else (static_cast(busPtr))->Show(consistent); break; - case I_32_I2_TM1_4: if (_useParallelI2S) (static_cast(busPtr))->Show(consistent); else (static_cast(busPtr))->Show(consistent); break; - case I_32_I2_TM2_3: if (_useParallelI2S) (static_cast(busPtr))->Show(consistent); else (static_cast(busPtr))->Show(consistent); break; + case I_32_I2_TM1814_4: if (_useParallelI2S) (static_cast(busPtr))->Show(consistent); else (static_cast(busPtr))->Show(consistent); break; + case I_32_I2_TM1815_4: if (_useParallelI2S) (static_cast(busPtr))->Show(consistent); else (static_cast(busPtr))->Show(consistent); break; + case I_32_I2_TM1829_3: if (_useParallelI2S) (static_cast(busPtr))->Show(consistent); else (static_cast(busPtr))->Show(consistent); break; case I_32_I2_UCS_3: if (_useParallelI2S) (static_cast(busPtr))->Show(consistent); else (static_cast(busPtr))->Show(consistent); break; case I_32_I2_UCS_4: if (_useParallelI2S) (static_cast(busPtr))->Show(consistent); else (static_cast(busPtr))->Show(consistent); break; case I_32_I2_APA106_3: if (_useParallelI2S) (static_cast(busPtr))->Show(consistent); else (static_cast(busPtr))->Show(consistent); break; @@ -702,14 +783,14 @@ class PolyBus { case I_8266_U1_400_3: return (static_cast(busPtr))->CanShow(); break; case I_8266_DM_400_3: return (static_cast(busPtr))->CanShow(); break; case I_8266_BB_400_3: return (static_cast(busPtr))->CanShow(); break; - case I_8266_U0_TM1_4: return (static_cast(busPtr))->CanShow(); break; - case I_8266_U1_TM1_4: return (static_cast(busPtr))->CanShow(); break; - case I_8266_DM_TM1_4: return (static_cast(busPtr))->CanShow(); break; - case I_8266_BB_TM1_4: return (static_cast(busPtr))->CanShow(); break; - case I_8266_U0_TM2_3: return (static_cast(busPtr))->CanShow(); break; - case I_8266_U1_TM2_3: return (static_cast(busPtr))->CanShow(); break; - case I_8266_DM_TM2_3: return (static_cast(busPtr))->CanShow(); break; - case I_8266_BB_TM2_3: return (static_cast(busPtr))->CanShow(); break; + case I_8266_U0_TM1814_4: return (static_cast(busPtr))->CanShow(); break; + case I_8266_U1_TM1814_4: return (static_cast(busPtr))->CanShow(); break; + case I_8266_DM_TM1814_4: return (static_cast(busPtr))->CanShow(); break; + case I_8266_BB_TM1814_4: return (static_cast(busPtr))->CanShow(); break; + case I_8266_U0_TM1829_3: return (static_cast(busPtr))->CanShow(); break; + case I_8266_U1_TM1829_3: return (static_cast(busPtr))->CanShow(); break; + case I_8266_DM_TM1829_3: return (static_cast(busPtr))->CanShow(); break; + case I_8266_BB_TM1829_3: return (static_cast(busPtr))->CanShow(); break; case I_8266_U0_UCS_3: return (static_cast(busPtr))->CanShow(); break; case I_8266_U1_UCS_3: return (static_cast(busPtr))->CanShow(); break; case I_8266_DM_UCS_3: return (static_cast(busPtr))->CanShow(); break; @@ -744,8 +825,9 @@ class PolyBus { case I_32_RN_NEO_3: return (static_cast(busPtr))->CanShow(); break; case I_32_RN_NEO_4: return (static_cast(busPtr))->CanShow(); break; case I_32_RN_400_3: return (static_cast(busPtr))->CanShow(); break; - case I_32_RN_TM1_4: return (static_cast(busPtr))->CanShow(); break; - case I_32_RN_TM2_3: return (static_cast(busPtr))->CanShow(); break; + case I_32_RN_TM1814_4: return (static_cast(busPtr))->CanShow(); break; + case I_32_RN_TM1815_4: return (static_cast(busPtr))->CanShow(); break; + case I_32_RN_TM1829_3: return (static_cast(busPtr))->CanShow(); break; case I_32_RN_UCS_3: return (static_cast(busPtr))->CanShow(); break; case I_32_RN_UCS_4: return (static_cast(busPtr))->CanShow(); break; case I_32_RN_APA106_3: return (static_cast(busPtr))->CanShow(); break; @@ -758,8 +840,9 @@ class PolyBus { case I_32_I2_NEO_3: if (_useParallelI2S) return (static_cast(busPtr))->CanShow(); else return (static_cast(busPtr))->CanShow(); break; case I_32_I2_NEO_4: if (_useParallelI2S) return (static_cast(busPtr))->CanShow(); else return (static_cast(busPtr))->CanShow(); break; case I_32_I2_400_3: if (_useParallelI2S) return (static_cast(busPtr))->CanShow(); else return (static_cast(busPtr))->CanShow(); break; - case I_32_I2_TM1_4: if (_useParallelI2S) return (static_cast(busPtr))->CanShow(); else return (static_cast(busPtr))->CanShow(); break; - case I_32_I2_TM2_3: if (_useParallelI2S) return (static_cast(busPtr))->CanShow(); else return (static_cast(busPtr))->CanShow(); break; + case I_32_I2_TM1814_4: if (_useParallelI2S) return (static_cast(busPtr))->CanShow(); else return (static_cast(busPtr))->CanShow(); break; + case I_32_I2_TM1815_4: if (_useParallelI2S) return (static_cast(busPtr))->CanShow(); else return (static_cast(busPtr))->CanShow(); break; + case I_32_I2_TM1829_3: if (_useParallelI2S) return (static_cast(busPtr))->CanShow(); else return (static_cast(busPtr))->CanShow(); break; case I_32_I2_UCS_3: if (_useParallelI2S) return (static_cast(busPtr))->CanShow(); else return (static_cast(busPtr))->CanShow(); break; case I_32_I2_UCS_4: if (_useParallelI2S) return (static_cast(busPtr))->CanShow(); else return (static_cast(busPtr))->CanShow(); break; case I_32_I2_APA106_3: if (_useParallelI2S) return (static_cast(busPtr))->CanShow(); else return (static_cast(busPtr))->CanShow(); break; @@ -824,14 +907,14 @@ class PolyBus { case I_8266_U1_400_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(col)); break; case I_8266_DM_400_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(col)); break; case I_8266_BB_400_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(col)); break; - case I_8266_U0_TM1_4: (static_cast(busPtr))->SetPixelColor(pix, col); break; - case I_8266_U1_TM1_4: (static_cast(busPtr))->SetPixelColor(pix, col); break; - case I_8266_DM_TM1_4: (static_cast(busPtr))->SetPixelColor(pix, col); break; - case I_8266_BB_TM1_4: (static_cast(busPtr))->SetPixelColor(pix, col); break; - case I_8266_U0_TM2_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(col)); break; - case I_8266_U1_TM2_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(col)); break; - case I_8266_DM_TM2_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(col)); break; - case I_8266_BB_TM2_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(col)); break; + case I_8266_U0_TM1814_4: (static_cast(busPtr))->SetPixelColor(pix, col); break; + case I_8266_U1_TM1814_4: (static_cast(busPtr))->SetPixelColor(pix, col); break; + case I_8266_DM_TM1814_4: (static_cast(busPtr))->SetPixelColor(pix, col); break; + case I_8266_BB_TM1814_4: (static_cast(busPtr))->SetPixelColor(pix, col); break; + case I_8266_U0_TM1829_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(col)); break; + case I_8266_U1_TM1829_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(col)); break; + case I_8266_DM_TM1829_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(col)); break; + case I_8266_BB_TM1829_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(col)); break; case I_8266_U0_UCS_3: (static_cast(busPtr))->SetPixelColor(pix, Rgb48Color(RgbColor(col))); break; case I_8266_U1_UCS_3: (static_cast(busPtr))->SetPixelColor(pix, Rgb48Color(RgbColor(col))); break; case I_8266_DM_UCS_3: (static_cast(busPtr))->SetPixelColor(pix, Rgb48Color(RgbColor(col))); break; @@ -866,8 +949,9 @@ class PolyBus { case I_32_RN_NEO_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(col)); break; case I_32_RN_NEO_4: (static_cast(busPtr))->SetPixelColor(pix, col); break; case I_32_RN_400_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(col)); break; - case I_32_RN_TM1_4: (static_cast(busPtr))->SetPixelColor(pix, col); break; - case I_32_RN_TM2_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(col)); break; + case I_32_RN_TM1814_4: (static_cast(busPtr))->SetPixelColor(pix, col); break; + case I_32_RN_TM1815_4: (static_cast(busPtr))->SetPixelColor(pix, col); break; + case I_32_RN_TM1829_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(col)); break; case I_32_RN_UCS_3: (static_cast(busPtr))->SetPixelColor(pix, Rgb48Color(RgbColor(col))); break; case I_32_RN_UCS_4: (static_cast(busPtr))->SetPixelColor(pix, Rgbw64Color(col)); break; case I_32_RN_APA106_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(col)); break; @@ -880,8 +964,9 @@ class PolyBus { case I_32_I2_NEO_3: if (_useParallelI2S) (static_cast(busPtr))->SetPixelColor(pix, RgbColor(col)); else (static_cast(busPtr))->SetPixelColor(pix, RgbColor(col)); break; case I_32_I2_NEO_4: if (_useParallelI2S) (static_cast(busPtr))->SetPixelColor(pix, col); else (static_cast(busPtr))->SetPixelColor(pix, col); break; case I_32_I2_400_3: if (_useParallelI2S) (static_cast(busPtr))->SetPixelColor(pix, RgbColor(col)); else (static_cast(busPtr))->SetPixelColor(pix, RgbColor(col)); break; - case I_32_I2_TM1_4: if (_useParallelI2S) (static_cast(busPtr))->SetPixelColor(pix, col); else (static_cast(busPtr))->SetPixelColor(pix, col); break; - case I_32_I2_TM2_3: if (_useParallelI2S) (static_cast(busPtr))->SetPixelColor(pix, RgbColor(col)); else (static_cast(busPtr))->SetPixelColor(pix, RgbColor(col)); break; + case I_32_I2_TM1814_4: if (_useParallelI2S) (static_cast(busPtr))->SetPixelColor(pix, col); else (static_cast(busPtr))->SetPixelColor(pix, col); break; + case I_32_I2_TM1815_4: if (_useParallelI2S) (static_cast(busPtr))->SetPixelColor(pix, col); else (static_cast(busPtr))->SetPixelColor(pix, col); break; + case I_32_I2_TM1829_3: if (_useParallelI2S) (static_cast(busPtr))->SetPixelColor(pix, RgbColor(col)); else (static_cast(busPtr))->SetPixelColor(pix, RgbColor(col)); break; case I_32_I2_UCS_3: if (_useParallelI2S) (static_cast(busPtr))->SetPixelColor(pix, Rgb48Color(RgbColor(col))); else (static_cast(busPtr))->SetPixelColor(pix, Rgb48Color(RgbColor(col))); break; case I_32_I2_UCS_4: if (_useParallelI2S) (static_cast(busPtr))->SetPixelColor(pix, Rgbw64Color(col)); else (static_cast(busPtr))->SetPixelColor(pix, Rgbw64Color(col)); break; case I_32_I2_APA106_3: if (_useParallelI2S) (static_cast(busPtr))->SetPixelColor(pix, RgbColor(col)); else (static_cast(busPtr))->SetPixelColor(pix, RgbColor(col)); break; @@ -921,14 +1006,14 @@ class PolyBus { case I_8266_U1_400_3: col = (static_cast(busPtr))->GetPixelColor(pix); break; case I_8266_DM_400_3: col = (static_cast(busPtr))->GetPixelColor(pix); break; case I_8266_BB_400_3: col = (static_cast(busPtr))->GetPixelColor(pix); break; - case I_8266_U0_TM1_4: col = (static_cast(busPtr))->GetPixelColor(pix); break; - case I_8266_U1_TM1_4: col = (static_cast(busPtr))->GetPixelColor(pix); break; - case I_8266_DM_TM1_4: col = (static_cast(busPtr))->GetPixelColor(pix); break; - case I_8266_BB_TM1_4: col = (static_cast(busPtr))->GetPixelColor(pix); break; - case I_8266_U0_TM2_3: col = (static_cast(busPtr))->GetPixelColor(pix); break; - case I_8266_U1_TM2_3: col = (static_cast(busPtr))->GetPixelColor(pix); break; - case I_8266_DM_TM2_3: col = (static_cast(busPtr))->GetPixelColor(pix); break; - case I_8266_BB_TM2_3: col = (static_cast(busPtr))->GetPixelColor(pix); break; + case I_8266_U0_TM1814_4: col = (static_cast(busPtr))->GetPixelColor(pix); break; + case I_8266_U1_TM1814_4: col = (static_cast(busPtr))->GetPixelColor(pix); break; + case I_8266_DM_TM1814_4: col = (static_cast(busPtr))->GetPixelColor(pix); break; + case I_8266_BB_TM1814_4: col = (static_cast(busPtr))->GetPixelColor(pix); break; + case I_8266_U0_TM1829_3: col = (static_cast(busPtr))->GetPixelColor(pix); break; + case I_8266_U1_TM1829_3: col = (static_cast(busPtr))->GetPixelColor(pix); break; + case I_8266_DM_TM1829_3: col = (static_cast(busPtr))->GetPixelColor(pix); break; + case I_8266_BB_TM1829_3: col = (static_cast(busPtr))->GetPixelColor(pix); break; case I_8266_U0_UCS_3: { Rgb48Color c = (static_cast(busPtr))->GetPixelColor(pix); col = RGBW32(c.R>>8,c.G>>8,c.B>>8,0); } break; case I_8266_U1_UCS_3: { Rgb48Color c = (static_cast(busPtr))->GetPixelColor(pix); col = RGBW32(c.R>>8,c.G>>8,c.B>>8,0); } break; case I_8266_DM_UCS_3: { Rgb48Color c = (static_cast(busPtr))->GetPixelColor(pix); col = RGBW32(c.R>>8,c.G>>8,c.B>>8,0); } break; @@ -963,8 +1048,9 @@ class PolyBus { case I_32_RN_NEO_3: col = (static_cast(busPtr))->GetPixelColor(pix); break; case I_32_RN_NEO_4: col = (static_cast(busPtr))->GetPixelColor(pix); break; case I_32_RN_400_3: col = (static_cast(busPtr))->GetPixelColor(pix); break; - case I_32_RN_TM1_4: col = (static_cast(busPtr))->GetPixelColor(pix); break; - case I_32_RN_TM2_3: col = (static_cast(busPtr))->GetPixelColor(pix); break; + case I_32_RN_TM1814_4: col = (static_cast(busPtr))->GetPixelColor(pix); break; + case I_32_RN_TM1815_4: col = (static_cast(busPtr))->GetPixelColor(pix); break; + case I_32_RN_TM1829_3: col = (static_cast(busPtr))->GetPixelColor(pix); break; case I_32_RN_UCS_3: { Rgb48Color c = (static_cast(busPtr))->GetPixelColor(pix); col = RGBW32(c.R>>8,c.G>>8,c.B>>8,0); } break; case I_32_RN_UCS_4: { Rgbw64Color c = (static_cast(busPtr))->GetPixelColor(pix); col = RGBW32(c.R>>8,c.G>>8,c.B>>8,c.W>>8); } break; case I_32_RN_APA106_3: col = (static_cast(busPtr))->GetPixelColor(pix); break; @@ -977,8 +1063,9 @@ class PolyBus { case I_32_I2_NEO_3: col = (_useParallelI2S) ? (static_cast(busPtr))->GetPixelColor(pix) : (static_cast(busPtr))->GetPixelColor(pix); break; case I_32_I2_NEO_4: col = (_useParallelI2S) ? (static_cast(busPtr))->GetPixelColor(pix) : (static_cast(busPtr))->GetPixelColor(pix); break; case I_32_I2_400_3: col = (_useParallelI2S) ? (static_cast(busPtr))->GetPixelColor(pix) : (static_cast(busPtr))->GetPixelColor(pix); break; - case I_32_I2_TM1_4: col = (_useParallelI2S) ? (static_cast(busPtr))->GetPixelColor(pix) : (static_cast(busPtr))->GetPixelColor(pix); break; - case I_32_I2_TM2_3: col = (_useParallelI2S) ? (static_cast(busPtr))->GetPixelColor(pix) : (static_cast(busPtr))->GetPixelColor(pix); break; + case I_32_I2_TM1814_4: col = (_useParallelI2S) ? (static_cast(busPtr))->GetPixelColor(pix) : (static_cast(busPtr))->GetPixelColor(pix); break; + case I_32_I2_TM1815_4: col = (_useParallelI2S) ? (static_cast(busPtr))->GetPixelColor(pix) : (static_cast(busPtr))->GetPixelColor(pix); break; + case I_32_I2_TM1829_3: col = (_useParallelI2S) ? (static_cast(busPtr))->GetPixelColor(pix) : (static_cast(busPtr))->GetPixelColor(pix); break; case I_32_I2_UCS_3: { Rgb48Color c = (_useParallelI2S) ? (static_cast(busPtr))->GetPixelColor(pix) : (static_cast(busPtr))->GetPixelColor(pix); col = RGBW32(c.R/257,c.G/257,c.B/257,0); } break; case I_32_I2_UCS_4: { Rgbw64Color c = (_useParallelI2S) ? (static_cast(busPtr))->GetPixelColor(pix) : (static_cast(busPtr))->GetPixelColor(pix); col = RGBW32(c.R/257,c.G/257,c.B/257,c.W/257); } break; case I_32_I2_APA106_3: col = (_useParallelI2S) ? (static_cast(busPtr))->GetPixelColor(pix) : (static_cast(busPtr))->GetPixelColor(pix); break; @@ -1036,14 +1123,14 @@ class PolyBus { case I_8266_U1_400_3: delete (static_cast(busPtr)); break; case I_8266_DM_400_3: delete (static_cast(busPtr)); break; case I_8266_BB_400_3: delete (static_cast(busPtr)); break; - case I_8266_U0_TM1_4: delete (static_cast(busPtr)); break; - case I_8266_U1_TM1_4: delete (static_cast(busPtr)); break; - case I_8266_DM_TM1_4: delete (static_cast(busPtr)); break; - case I_8266_BB_TM1_4: delete (static_cast(busPtr)); break; - case I_8266_U0_TM2_3: delete (static_cast(busPtr)); break; - case I_8266_U1_TM2_3: delete (static_cast(busPtr)); break; - case I_8266_DM_TM2_3: delete (static_cast(busPtr)); break; - case I_8266_BB_TM2_3: delete (static_cast(busPtr)); break; + case I_8266_U0_TM1814_4: delete (static_cast(busPtr)); break; + case I_8266_U1_TM1814_4: delete (static_cast(busPtr)); break; + case I_8266_DM_TM1814_4: delete (static_cast(busPtr)); break; + case I_8266_BB_TM1814_4: delete (static_cast(busPtr)); break; + case I_8266_U0_TM1829_3: delete (static_cast(busPtr)); break; + case I_8266_U1_TM1829_3: delete (static_cast(busPtr)); break; + case I_8266_DM_TM1829_3: delete (static_cast(busPtr)); break; + case I_8266_BB_TM1829_3: delete (static_cast(busPtr)); break; case I_8266_U0_UCS_3: delete (static_cast(busPtr)); break; case I_8266_U1_UCS_3: delete (static_cast(busPtr)); break; case I_8266_DM_UCS_3: delete (static_cast(busPtr)); break; @@ -1078,8 +1165,9 @@ class PolyBus { case I_32_RN_NEO_3: delete (static_cast(busPtr)); break; case I_32_RN_NEO_4: delete (static_cast(busPtr)); break; case I_32_RN_400_3: delete (static_cast(busPtr)); break; - case I_32_RN_TM1_4: delete (static_cast(busPtr)); break; - case I_32_RN_TM2_3: delete (static_cast(busPtr)); break; + case I_32_RN_TM1814_4: delete (static_cast(busPtr)); break; + case I_32_RN_TM1815_4: delete (static_cast(busPtr)); break; + case I_32_RN_TM1829_3: delete (static_cast(busPtr)); break; case I_32_RN_UCS_3: delete (static_cast(busPtr)); break; case I_32_RN_UCS_4: delete (static_cast(busPtr)); break; case I_32_RN_APA106_3: delete (static_cast(busPtr)); break; @@ -1092,8 +1180,9 @@ class PolyBus { case I_32_I2_NEO_3: if (_useParallelI2S) delete (static_cast(busPtr)); else delete (static_cast(busPtr)); break; case I_32_I2_NEO_4: if (_useParallelI2S) delete (static_cast(busPtr)); else delete (static_cast(busPtr)); break; case I_32_I2_400_3: if (_useParallelI2S) delete (static_cast(busPtr)); else delete (static_cast(busPtr)); break; - case I_32_I2_TM1_4: if (_useParallelI2S) delete (static_cast(busPtr)); else delete (static_cast(busPtr)); break; - case I_32_I2_TM2_3: if (_useParallelI2S) delete (static_cast(busPtr)); else delete (static_cast(busPtr)); break; + case I_32_I2_TM1814_4: if (_useParallelI2S) delete (static_cast(busPtr)); else delete (static_cast(busPtr)); break; + case I_32_I2_TM1815_4: if (_useParallelI2S) delete (static_cast(busPtr)); else delete (static_cast(busPtr)); break; + case I_32_I2_TM1829_3: if (_useParallelI2S) delete (static_cast(busPtr)); else delete (static_cast(busPtr)); break; case I_32_I2_UCS_3: if (_useParallelI2S) delete (static_cast(busPtr)); else delete (static_cast(busPtr)); break; case I_32_I2_UCS_4: if (_useParallelI2S) delete (static_cast(busPtr)); else delete (static_cast(busPtr)); break; case I_32_I2_APA106_3: if (_useParallelI2S) delete (static_cast(busPtr)); else delete (static_cast(busPtr)); break; @@ -1133,14 +1222,14 @@ class PolyBus { case I_8266_U1_400_3: size = (static_cast(busPtr))->PixelsSize(); break; case I_8266_DM_400_3: size = (static_cast(busPtr))->PixelsSize()*5; break; case I_8266_BB_400_3: size = (static_cast(busPtr))->PixelsSize(); break; - case I_8266_U0_TM1_4: size = (static_cast(busPtr))->PixelsSize(); break; - case I_8266_U1_TM1_4: size = (static_cast(busPtr))->PixelsSize(); break; - case I_8266_DM_TM1_4: size = (static_cast(busPtr))->PixelsSize()*5; break; - case I_8266_BB_TM1_4: size = (static_cast(busPtr))->PixelsSize(); break; - case I_8266_U0_TM2_3: size = (static_cast(busPtr))->PixelsSize(); break; - case I_8266_U1_TM2_3: size = (static_cast(busPtr))->PixelsSize(); break; - case I_8266_DM_TM2_3: size = (static_cast(busPtr))->PixelsSize()*5; break; - case I_8266_BB_TM2_3: size = (static_cast(busPtr))->PixelsSize(); break; + case I_8266_U0_TM1814_4: size = (static_cast(busPtr))->PixelsSize(); break; + case I_8266_U1_TM1814_4: size = (static_cast(busPtr))->PixelsSize(); break; + case I_8266_DM_TM1814_4: size = (static_cast(busPtr))->PixelsSize()*5; break; + case I_8266_BB_TM1814_4: size = (static_cast(busPtr))->PixelsSize(); break; + case I_8266_U0_TM1829_3: size = (static_cast(busPtr))->PixelsSize(); break; + case I_8266_U1_TM1829_3: size = (static_cast(busPtr))->PixelsSize(); break; + case I_8266_DM_TM1829_3: size = (static_cast(busPtr))->PixelsSize()*5; break; + case I_8266_BB_TM1829_3: size = (static_cast(busPtr))->PixelsSize(); break; case I_8266_U0_UCS_3: size = (static_cast(busPtr))->PixelsSize(); break; case I_8266_U1_UCS_3: size = (static_cast(busPtr))->PixelsSize(); break; case I_8266_DM_UCS_3: size = (static_cast(busPtr))->PixelsSize()*5; break; @@ -1175,8 +1264,9 @@ class PolyBus { case I_32_RN_NEO_3: size = (static_cast(busPtr))->PixelsSize()*2; break; case I_32_RN_NEO_4: size = (static_cast(busPtr))->PixelsSize()*2; break; case I_32_RN_400_3: size = (static_cast(busPtr))->PixelsSize()*2; break; - case I_32_RN_TM1_4: size = (static_cast(busPtr))->PixelsSize()*2; break; - case I_32_RN_TM2_3: size = (static_cast(busPtr))->PixelsSize()*2; break; + case I_32_RN_TM1814_4: size = (static_cast(busPtr))->PixelsSize()*2; break; + case I_32_RN_TM1815_4: size = (static_cast(busPtr))->PixelsSize()*2; break; + case I_32_RN_TM1829_3: size = (static_cast(busPtr))->PixelsSize()*2; break; case I_32_RN_UCS_3: size = (static_cast(busPtr))->PixelsSize()*2; break; case I_32_RN_UCS_4: size = (static_cast(busPtr))->PixelsSize()*2; break; case I_32_RN_APA106_3: size = (static_cast(busPtr))->PixelsSize()*2; break; @@ -1189,8 +1279,9 @@ class PolyBus { case I_32_I2_NEO_3: size = (_useParallelI2S) ? (static_cast(busPtr))->PixelsSize()*4 : (static_cast(busPtr))->PixelsSize()*4; break; case I_32_I2_NEO_4: size = (_useParallelI2S) ? (static_cast(busPtr))->PixelsSize()*4 : (static_cast(busPtr))->PixelsSize()*4; break; case I_32_I2_400_3: size = (_useParallelI2S) ? (static_cast(busPtr))->PixelsSize()*4 : (static_cast(busPtr))->PixelsSize()*4; break; - case I_32_I2_TM1_4: size = (_useParallelI2S) ? (static_cast(busPtr))->PixelsSize()*4 : (static_cast(busPtr))->PixelsSize()*4; break; - case I_32_I2_TM2_3: size = (_useParallelI2S) ? (static_cast(busPtr))->PixelsSize()*4 : (static_cast(busPtr))->PixelsSize()*4; break; + case I_32_I2_TM1814_4: size = (_useParallelI2S) ? (static_cast(busPtr))->PixelsSize()*4 : (static_cast(busPtr))->PixelsSize()*4; break; + case I_32_I2_TM1815_4: size = (_useParallelI2S) ? (static_cast(busPtr))->PixelsSize()*4 : (static_cast(busPtr))->PixelsSize()*4; break; + case I_32_I2_TM1829_3: size = (_useParallelI2S) ? (static_cast(busPtr))->PixelsSize()*4 : (static_cast(busPtr))->PixelsSize()*4; break; case I_32_I2_UCS_3: size = (_useParallelI2S) ? (static_cast(busPtr))->PixelsSize()*4 : (static_cast(busPtr))->PixelsSize()*4; break; case I_32_I2_UCS_4: size = (_useParallelI2S) ? (static_cast(busPtr))->PixelsSize()*4 : (static_cast(busPtr))->PixelsSize()*4; break; case I_32_I2_APA106_3: size = (_useParallelI2S) ? (static_cast(busPtr))->PixelsSize()*4 : (static_cast(busPtr))->PixelsSize()*4; break; @@ -1223,9 +1314,9 @@ class PolyBus { case I_8266_U0_NEO_4 : // fallthrough case I_8266_U1_NEO_4 : // fallthrough case I_8266_BB_NEO_4 : // fallthrough - case I_8266_U0_TM1_4 : // fallthrough - case I_8266_U1_TM1_4 : // fallthrough - case I_8266_BB_TM1_4 : size = (size + count); break; // 4 channels + case I_8266_U0_TM1814_4 : // fallthrough + case I_8266_U1_TM1814_4 : // fallthrough + case I_8266_BB_TM1814_4 : size = (size + count); break; // 4 channels case I_8266_U0_UCS_3 : // fallthrough case I_8266_U1_UCS_3 : // fallthrough case I_8266_BB_UCS_3 : size *= 2; break; // 16 bit @@ -1244,11 +1335,11 @@ class PolyBus { // DMA methods have front + DMA buffer = ((1+(3+1)) * channels; exact value is a bit of mistery - needs a dig into NPB) case I_8266_DM_NEO_3 : // fallthrough case I_8266_DM_400_3 : // fallthrough - case I_8266_DM_TM2_3 : // fallthrough + case I_8266_DM_TM1829_3 : // fallthrough case I_8266_DM_APA106_3 : // fallthrough case I_8266_DM_TM1914_3 : size *= 5; break; case I_8266_DM_NEO_4 : // fallthrough - case I_8266_DM_TM1_4 : size = (size + count)*5; break; + case I_8266_DM_TM1814_4 : size = (size + count)*5; break; case I_8266_DM_UCS_3 : size *= 2*5; break; case I_8266_DM_UCS_4 : size = (size + count)*2*5; break; case I_8266_DM_FW6_5 : // fallthrough @@ -1257,7 +1348,8 @@ class PolyBus { #else // RMT buses (1x front and 1x back buffer, does not include small RMT buffer) case I_32_RN_NEO_4 : // fallthrough - case I_32_RN_TM1_4 : size = (size + count)*2; break; // 4 channels + case I_32_RN_TM1814_4 : // fallthrough + case I_32_RN_TM1815_4 : size = (size + count)*2; break; // 4 channels case I_32_RN_UCS_3 : size *= 2*2; break; // 16bit case I_32_RN_UCS_4 : size = (size + count)*2*2; break; // 16bit, 4 channels case I_32_RN_FW6_5 : // fallthrough @@ -1267,10 +1359,11 @@ class PolyBus { #ifndef CONFIG_IDF_TARGET_ESP32C3 case I_32_I2_NEO_3 : // fallthrough case I_32_I2_400_3 : // fallthrough - case I_32_I2_TM2_3 : // fallthrough + case I_32_I2_TM1829_3 : // fallthrough case I_32_I2_APA106_3 : break; // do nothing, I2S uses single buffer + DMA buffer case I_32_I2_NEO_4 : // fallthrough - case I_32_I2_TM1_4 : size = (size + count); break; // 4 channels + case I_32_I2_TM1814_4 : // fallthrough + case I_32_I2_TM1815_4 : size = (size + count); break; // 4 channels case I_32_I2_UCS_3 : size *= 2; break; // 16 bit case I_32_I2_UCS_4 : size = (size + count)*2; break; // 16 bit, 4 channels case I_32_I2_FW6_5 : // fallthrough @@ -1321,9 +1414,9 @@ class PolyBus { case TYPE_WS2811_400KHZ: return I_8266_U0_400_3 + offset; case TYPE_TM1814: - return I_8266_U0_TM1_4 + offset; + return I_8266_U0_TM1814_4 + offset; case TYPE_TM1829: - return I_8266_U0_TM2_3 + offset; + return I_8266_U0_TM1829_3 + offset; case TYPE_UCS8903: return I_8266_U0_UCS_3 + offset; case TYPE_UCS8904: @@ -1384,9 +1477,11 @@ class PolyBus { case TYPE_WS2811_400KHZ: return I_32_RN_400_3 + offset; case TYPE_TM1814: - return I_32_RN_TM1_4 + offset; + return I_32_RN_TM1814_4 + offset; + case TYPE_TM1815: + return I_32_RN_TM1815_4 + offset; case TYPE_TM1829: - return I_32_RN_TM2_3 + offset; + return I_32_RN_TM1829_3 + offset; case TYPE_UCS8903: return I_32_RN_UCS_3 + offset; case TYPE_UCS8904: diff --git a/wled00/const.h b/wled00/const.h index 9067d9b16c..2e38cbb3de 100644 --- a/wled00/const.h +++ b/wled00/const.h @@ -301,10 +301,11 @@ static_assert(WLED_MAX_BUSSES <= 32, "WLED_MAX_BUSSES exceeds hard limit"); #define TYPE_FW1906 28 //RGB + CW + WW + unused channel (6 channels per IC) #define TYPE_UCS8904 29 //first RGBW digital type (hardcoded in busmanager.cpp, memUsage()) #define TYPE_SK6812_RGBW 30 -#define TYPE_TM1814 31 +#define TYPE_TM1814 31 //RGBW #define TYPE_WS2805 32 //RGB + WW + CW #define TYPE_TM1914 33 //RGB #define TYPE_SM16825 34 //RGB + WW + CW +#define TYPE_TM1815 35 //RGBW (half speed TM1814) #define TYPE_DIGITAL_MAX 39 // last usable digital type //"Analog" types (40-47) #define TYPE_ONOFF 40 //binary output (relays etc.; NOT PWM) diff --git a/wled00/data/settings_leds.htm b/wled00/data/settings_leds.htm index 2cd5e28393..04c95140fc 100644 --- a/wled00/data/settings_leds.htm +++ b/wled00/data/settings_leds.htm @@ -289,7 +289,7 @@ setPinConfig(n,t); gId("abl"+n).style.display = (!abl || !isDig(t)) ? "none" : "inline"; // show/hide individual ABL settings if (change) { // did we change LED type? - gId("rf"+n).checked = (gId("rf"+n).checked || t == 31); // LEDs require data in off state (mandatory for TM1814) + gId("rf"+n).checked = (gId("rf"+n).checked || t == 31 || t == 35); // LEDs require data in off state (mandatory for TM1814/TM1815) if (isAna(t)) d.Sf["LC"+n].value = 1; // for sanity change analog count just to 1 LED d.Sf["LA"+n].min = (!isDig(t) || !abl) ? 0 : 1; // set minimum value for LED mA d.Sf["MA"+n].min = (!isDig(t)) ? 0 : 250; // set minimum value for PSU mA From ec09a017aaf3b912da75006131c356fb5588ac0d Mon Sep 17 00:00:00 2001 From: Damian Schneider Date: Fri, 2 Jan 2026 10:46:55 +0100 Subject: [PATCH 2/8] add support for ESP8266 tested this, timings are not perfect on all protocols but are just within specification --- wled00/bus_wrapper.h | 95 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 90 insertions(+), 5 deletions(-) diff --git a/wled00/bus_wrapper.h b/wled00/bus_wrapper.h index 24be495a01..ccc120f6d5 100644 --- a/wled00/bus_wrapper.h +++ b/wled00/bus_wrapper.h @@ -75,6 +75,11 @@ #define I_8266_U1_SM16825_5 46 #define I_8266_DM_SM16825_5 47 #define I_8266_BB_SM16825_5 48 +//TM1815 (RGBW) +#define I_8266_U0_TM1815_4 49 +#define I_8266_U1_TM1815_4 50 +#define I_8266_DM_TM1815_4 51 +#define I_8266_BB_TM1815_4 52 /*** ESP32 Neopixel methods ***/ //RGB @@ -137,6 +142,7 @@ #define I_HS_LPO_3 109 #define I_SS_LPO_3 110 +#ifdef ESP32 // RMT driver selection #if !defined(WLED_USE_SHARED_RMT) && !defined(__riscv) #include @@ -175,7 +181,8 @@ void NeoEsp32RmtSpeedTm1815::Translate(const void* src, _translate(src, dest, src_size, wanted_num, translated_size, item_num, RmtBit0, RmtBit1, RmtDurationReset); } - +#else // ESP8266 +// special types and classes not officially supported by NPB class NeoBitsSpeedTm1815 : public NeoBitsSpeedBase { public: @@ -183,6 +190,33 @@ class NeoBitsSpeedTm1815 : public NeoBitsSpeedBase const static uint16_t ResetTimeUs = 200; }; +// Tm1815 normal is inverted signal +class NeoEspBitBangSpeedTm1815 +{ +public: + const static uint32_t T0H = (F_CPU / 5833332 - CYCLES_LOOPTEST); // 0.7us + const static uint32_t T1H = (F_CPU / 3333332 - CYCLES_LOOPTEST); // 1.5us + const static uint32_t Period = (F_CPU / 1600000 - CYCLES_LOOPTEST); // 2.5us per bit + + static const uint32_t ResetTimeUs = 200; + const static uint32_t TLatch = (F_CPU / 20000 - CYCLES_LOOPTEST); // 200us, be generous +}; + +class NeoEsp8266UartSpeedTm1815 // values taken from "400kHz" speed bus but extended reset time (just like TM1814 does with 800kHz timings) +{ +public: + static const uint32_t ByteSendTimeUs = 20; // us it takes to send a single pixel element at 400khz speed + static const uint32_t UartBaud = 1600000; // 400mhz, 4 serial bytes per NeoByte + static const uint32_t ResetTimeUs = 200; // us between data send bursts to reset for next update +}; + +class NeoWrgbTm1815Feature : + public Neo4ByteFeature, + public NeoElementsTm1814Settings +{ +}; +#endif + // special non-native I2S NPB methods #ifdef ESP32 // ESP32 RMT Methods @@ -209,6 +243,13 @@ typedef NeoEsp32I2s0X8Tm1815Method X8Tm1815Method; typedef NeoEsp32I2s1X8Tm1815Method X8Tm1815Method; #endif #endif // !CONFIG_IDF_TARGET_ESP32C3 +#else // ESP8266 + +typedef NeoEsp8266UartMethodBase, NeoEsp8266UartInverted> NeoEsp8266Uart0Tm1815Method; +typedef NeoEsp8266UartMethodBase, NeoEsp8266UartInverted> NeoEsp8266Uart1Tm1815Method; +typedef NeoEsp8266DmaMethodBase,NeoBitsSpeedTm1815> NeoEsp8266DmaTm1815Method; +typedef NeoEspBitBangMethodBase NeoEsp8266BitBangTm1815Method; + #endif // ESP32 // In the following NeoGammaNullMethod can be replaced with NeoGammaWLEDMethod to perform Gamma correction implicitly @@ -236,6 +277,12 @@ typedef NeoEsp32I2s1X8Tm1815Method X8Tm1815Method; #define B_8266_U1_TM1814_4 NeoPixelBus #define B_8266_DM_TM1814_4 NeoPixelBus #define B_8266_BB_TM1814_4 NeoPixelBus +//TM1815 (RGBW) +#define B_8266_U0_TM1815_4 NeoPixelBus +#define B_8266_U1_TM1815_4 NeoPixelBus +#define B_8266_DM_TM1815_4 NeoPixelBus +#define B_8266_BB_TM1815_4 NeoPixelBus + //TM1829 (RGB) #define B_8266_U0_TM1829_3 NeoPixelBus #define B_8266_U1_TM1829_3 NeoPixelBus @@ -469,6 +516,10 @@ class PolyBus { case I_8266_U1_TM1814_4: beginTM1814(busPtr); break; case I_8266_DM_TM1814_4: beginTM1814(busPtr); break; case I_8266_BB_TM1814_4: beginTM1814(busPtr); break; + case I_8266_U0_TM1815_4: beginTM1814(busPtr); break; + case I_8266_U1_TM1815_4: beginTM1814(busPtr); break; + case I_8266_DM_TM1815_4: beginTM1814(busPtr); break; + case I_8266_BB_TM1815_4: beginTM1814(busPtr); break; case I_8266_U0_TM1829_3: (static_cast(busPtr))->Begin(); break; case I_8266_U1_TM1829_3: (static_cast(busPtr))->Begin(); break; case I_8266_DM_TM1829_3: (static_cast(busPtr))->Begin(); break; @@ -588,6 +639,10 @@ class PolyBus { case I_8266_U1_TM1814_4: busPtr = new B_8266_U1_TM1814_4(len, pins[0]); break; case I_8266_DM_TM1814_4: busPtr = new B_8266_DM_TM1814_4(len, pins[0]); break; case I_8266_BB_TM1814_4: busPtr = new B_8266_BB_TM1814_4(len, pins[0]); break; + case I_8266_U0_TM1815_4: busPtr = new B_8266_U0_TM1815_4(len, pins[0]); break; + case I_8266_U1_TM1815_4: busPtr = new B_8266_U1_TM1815_4(len, pins[0]); break; + case I_8266_DM_TM1815_4: busPtr = new B_8266_DM_TM1815_4(len, pins[0]); break; + case I_8266_BB_TM1815_4: busPtr = new B_8266_BB_TM1815_4(len, pins[0]); break; case I_8266_U0_TM1829_3: busPtr = new B_8266_U0_TM1829_3(len, pins[0]); break; case I_8266_U1_TM1829_3: busPtr = new B_8266_U1_TM1829_3(len, pins[0]); break; case I_8266_DM_TM1829_3: busPtr = new B_8266_DM_TM1829_3(len, pins[0]); break; @@ -689,6 +744,10 @@ class PolyBus { case I_8266_U1_TM1814_4: (static_cast(busPtr))->Show(consistent); break; case I_8266_DM_TM1814_4: (static_cast(busPtr))->Show(consistent); break; case I_8266_BB_TM1814_4: (static_cast(busPtr))->Show(consistent); break; + case I_8266_U0_TM1815_4: (static_cast(busPtr))->Show(consistent); break; + case I_8266_U1_TM1815_4: (static_cast(busPtr))->Show(consistent); break; + case I_8266_DM_TM1815_4: (static_cast(busPtr))->Show(consistent); break; + case I_8266_BB_TM1815_4: (static_cast(busPtr))->Show(consistent); break; case I_8266_U0_TM1829_3: (static_cast(busPtr))->Show(consistent); break; case I_8266_U1_TM1829_3: (static_cast(busPtr))->Show(consistent); break; case I_8266_DM_TM1829_3: (static_cast(busPtr))->Show(consistent); break; @@ -787,6 +846,10 @@ class PolyBus { case I_8266_U1_TM1814_4: return (static_cast(busPtr))->CanShow(); break; case I_8266_DM_TM1814_4: return (static_cast(busPtr))->CanShow(); break; case I_8266_BB_TM1814_4: return (static_cast(busPtr))->CanShow(); break; + case I_8266_U0_TM1815_4: return (static_cast(busPtr))->CanShow(); break; + case I_8266_U1_TM1815_4: return (static_cast(busPtr))->CanShow(); break; + case I_8266_DM_TM1815_4: return (static_cast(busPtr))->CanShow(); break; + case I_8266_BB_TM1815_4: return (static_cast(busPtr))->CanShow(); break; case I_8266_U0_TM1829_3: return (static_cast(busPtr))->CanShow(); break; case I_8266_U1_TM1829_3: return (static_cast(busPtr))->CanShow(); break; case I_8266_DM_TM1829_3: return (static_cast(busPtr))->CanShow(); break; @@ -911,6 +974,10 @@ class PolyBus { case I_8266_U1_TM1814_4: (static_cast(busPtr))->SetPixelColor(pix, col); break; case I_8266_DM_TM1814_4: (static_cast(busPtr))->SetPixelColor(pix, col); break; case I_8266_BB_TM1814_4: (static_cast(busPtr))->SetPixelColor(pix, col); break; + case I_8266_U0_TM1815_4: (static_cast(busPtr))->SetPixelColor(pix, col); break; + case I_8266_U1_TM1815_4: (static_cast(busPtr))->SetPixelColor(pix, col); break; + case I_8266_DM_TM1815_4: (static_cast(busPtr))->SetPixelColor(pix, col); break; + case I_8266_BB_TM1815_4: (static_cast(busPtr))->SetPixelColor(pix, col); break; case I_8266_U0_TM1829_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(col)); break; case I_8266_U1_TM1829_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(col)); break; case I_8266_DM_TM1829_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(col)); break; @@ -1010,6 +1077,10 @@ class PolyBus { case I_8266_U1_TM1814_4: col = (static_cast(busPtr))->GetPixelColor(pix); break; case I_8266_DM_TM1814_4: col = (static_cast(busPtr))->GetPixelColor(pix); break; case I_8266_BB_TM1814_4: col = (static_cast(busPtr))->GetPixelColor(pix); break; + case I_8266_U0_TM1815_4: col = (static_cast(busPtr))->GetPixelColor(pix); break; + case I_8266_U1_TM1815_4: col = (static_cast(busPtr))->GetPixelColor(pix); break; + case I_8266_DM_TM1815_4: col = (static_cast(busPtr))->GetPixelColor(pix); break; + case I_8266_BB_TM1815_4: col = (static_cast(busPtr))->GetPixelColor(pix); break; case I_8266_U0_TM1829_3: col = (static_cast(busPtr))->GetPixelColor(pix); break; case I_8266_U1_TM1829_3: col = (static_cast(busPtr))->GetPixelColor(pix); break; case I_8266_DM_TM1829_3: col = (static_cast(busPtr))->GetPixelColor(pix); break; @@ -1127,6 +1198,10 @@ class PolyBus { case I_8266_U1_TM1814_4: delete (static_cast(busPtr)); break; case I_8266_DM_TM1814_4: delete (static_cast(busPtr)); break; case I_8266_BB_TM1814_4: delete (static_cast(busPtr)); break; + case I_8266_U0_TM1815_4: delete (static_cast(busPtr)); break; + case I_8266_U1_TM1815_4: delete (static_cast(busPtr)); break; + case I_8266_DM_TM1815_4: delete (static_cast(busPtr)); break; + case I_8266_BB_TM1815_4: delete (static_cast(busPtr)); break; case I_8266_U0_TM1829_3: delete (static_cast(busPtr)); break; case I_8266_U1_TM1829_3: delete (static_cast(busPtr)); break; case I_8266_DM_TM1829_3: delete (static_cast(busPtr)); break; @@ -1226,6 +1301,10 @@ class PolyBus { case I_8266_U1_TM1814_4: size = (static_cast(busPtr))->PixelsSize(); break; case I_8266_DM_TM1814_4: size = (static_cast(busPtr))->PixelsSize()*5; break; case I_8266_BB_TM1814_4: size = (static_cast(busPtr))->PixelsSize(); break; + case I_8266_U0_TM1815_4: size = (static_cast(busPtr))->PixelsSize(); break; + case I_8266_U1_TM1815_4: size = (static_cast(busPtr))->PixelsSize(); break; + case I_8266_DM_TM1815_4: size = (static_cast(busPtr))->PixelsSize()*5; break; + case I_8266_BB_TM1815_4: size = (static_cast(busPtr))->PixelsSize(); break; case I_8266_U0_TM1829_3: size = (static_cast(busPtr))->PixelsSize(); break; case I_8266_U1_TM1829_3: size = (static_cast(busPtr))->PixelsSize(); break; case I_8266_DM_TM1829_3: size = (static_cast(busPtr))->PixelsSize()*5; break; @@ -1314,9 +1393,12 @@ class PolyBus { case I_8266_U0_NEO_4 : // fallthrough case I_8266_U1_NEO_4 : // fallthrough case I_8266_BB_NEO_4 : // fallthrough - case I_8266_U0_TM1814_4 : // fallthrough - case I_8266_U1_TM1814_4 : // fallthrough - case I_8266_BB_TM1814_4 : size = (size + count); break; // 4 channels + case I_8266_U0_TM1814_4 : // fallthrough + case I_8266_U1_TM1814_4 : // fallthrough + case I_8266_BB_TM1814_4 : // fallthrough + case I_8266_U0_TM1815_4 : // fallthrough + case I_8266_U1_TM1815_4 : // fallthrough + case I_8266_BB_TM1815_4 : size = (size + count); break; // 4 channels case I_8266_U0_UCS_3 : // fallthrough case I_8266_U1_UCS_3 : // fallthrough case I_8266_BB_UCS_3 : size *= 2; break; // 16 bit @@ -1339,7 +1421,8 @@ class PolyBus { case I_8266_DM_APA106_3 : // fallthrough case I_8266_DM_TM1914_3 : size *= 5; break; case I_8266_DM_NEO_4 : // fallthrough - case I_8266_DM_TM1814_4 : size = (size + count)*5; break; + case I_8266_DM_TM1814_4 : // fallthrough + case I_8266_DM_TM1815_4 : size = (size + count)*5; break; case I_8266_DM_UCS_3 : size *= 2*5; break; case I_8266_DM_UCS_4 : size = (size + count)*2*5; break; case I_8266_DM_FW6_5 : // fallthrough @@ -1415,6 +1498,8 @@ class PolyBus { return I_8266_U0_400_3 + offset; case TYPE_TM1814: return I_8266_U0_TM1814_4 + offset; + case TYPE_TM1815: + return I_8266_U0_TM1815_4 + offset; case TYPE_TM1829: return I_8266_U0_TM1829_3 + offset; case TYPE_UCS8903: From 283a16a4d71875c198b17afa8792d6f6e5dd20a3 Mon Sep 17 00:00:00 2001 From: Damian Schneider Date: Fri, 2 Jan 2026 11:41:10 +0100 Subject: [PATCH 3/8] add comment to magic current limit number --- wled00/bus_wrapper.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wled00/bus_wrapper.h b/wled00/bus_wrapper.h index ccc120f6d5..7fca1d5385 100644 --- a/wled00/bus_wrapper.h +++ b/wled00/bus_wrapper.h @@ -485,7 +485,7 @@ class PolyBus { static void beginTM1814(void* busPtr) { T tm1814_strip = static_cast(busPtr); tm1814_strip->Begin(); - // Max current for each LED (22.5 mA). + // Max current for each LED (22.5 mA): max is 38mA, 22.5 was chosen as a safe value, see #1905 tm1814_strip->SetPixelSettings(NeoTm1814Settings(/*R*/225, /*G*/225, /*B*/225, /*W*/225)); } From 8d1eb72c419e6a3a475003538bb459f199e21c20 Mon Sep 17 00:00:00 2001 From: Damian Schneider Date: Sat, 3 Jan 2026 13:10:10 +0100 Subject: [PATCH 4/8] bugfix: move I2S/DMA timing out of the #ifdef --- wled00/bus_wrapper.h | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/wled00/bus_wrapper.h b/wled00/bus_wrapper.h index 7fca1d5385..45bb07c5ba 100644 --- a/wled00/bus_wrapper.h +++ b/wled00/bus_wrapper.h @@ -156,6 +156,7 @@ // special types and classes not officially supported by NPB // TM1815 is exactly half the speed of TM1814, normal is inverted signal compared to WS281x (low pulse timing, high idle/reset) +//RMT timing class NeoEsp32RmtSpeedTm1815 : public NeoEsp32RmtInvertedSpeedBase { public: @@ -181,15 +182,8 @@ void NeoEsp32RmtSpeedTm1815::Translate(const void* src, _translate(src, dest, src_size, wanted_num, translated_size, item_num, RmtBit0, RmtBit1, RmtDurationReset); } -#else // ESP8266 -// special types and classes not officially supported by NPB -class NeoBitsSpeedTm1815 : public NeoBitsSpeedBase -{ -public: - const static uint16_t BitSendTimeNs = 2500; - const static uint16_t ResetTimeUs = 200; -}; +#else // ESP8266 // Tm1815 normal is inverted signal class NeoEspBitBangSpeedTm1815 { @@ -217,6 +211,14 @@ class NeoWrgbTm1815Feature : }; #endif +// I2S / DMA custom timing +class NeoBitsSpeedTm1815 : public NeoBitsSpeedBase +{ +public: + const static uint16_t BitSendTimeNs = 2500; + const static uint16_t ResetTimeUs = 200; +}; + // special non-native I2S NPB methods #ifdef ESP32 // ESP32 RMT Methods From 17431344cbba1bf33a7fffe3e71b50c972f0d33a Mon Sep 17 00:00:00 2001 From: Damian Schneider Date: Sat, 3 Jan 2026 13:32:51 +0100 Subject: [PATCH 5/8] move custom timings to new header file --- wled00/bus_customNPBtiming.h | 129 +++++++++++++++++++++++++++++++++++ wled00/bus_wrapper.h | 102 +-------------------------- 2 files changed, 130 insertions(+), 101 deletions(-) create mode 100644 wled00/bus_customNPBtiming.h diff --git a/wled00/bus_customNPBtiming.h b/wled00/bus_customNPBtiming.h new file mode 100644 index 0000000000..7dd52be7ff --- /dev/null +++ b/wled00/bus_customNPBtiming.h @@ -0,0 +1,129 @@ +/* + * Custom NeoPixelBus timing definitions for WLED + */ + +#pragma once +#ifndef BusCustomNPBtiming_h +#define BusCustomNPBtiming_h + +#include +#include "NeoPixelBus.h" + +#define WLED_USE_SHARED_RMT + +#ifdef ESP32 +// RMT driver selection +#if !defined(WLED_USE_SHARED_RMT) && !defined(__riscv) +#include +//#define NeoEsp32RmtMethod(x) NeoEsp32RmtHIN ## x ## Method +#define USE_NEOPIXELBUS_RMT_HI +#else +#include "internal/methods/NeoEsp32RmtMethod.h" // needed for custom RMT types +//#define NeoEsp32RmtMethod(x) NeoEsp32RmtN ## x ## Method +#endif + +//////////////////////////////// +// TM1815 timing definitions // +//////////////////////////////// + +// TM1815 is exactly half the speed of TM1814, other features are identical so can use TM1814 as a base class +// normal timing pulses are inverted compared to WS281x (low pulse timing, high idle/reset) + +// RMT timing +class NeoEsp32RmtSpeedTm1815 : public NeoEsp32RmtInvertedSpeedBase +{ +public: + const static DRAM_ATTR uint32_t RmtBit0 = Item32Val(740, 1780); + const static DRAM_ATTR uint32_t RmtBit1 = Item32Val(1440, 1060); + const static DRAM_ATTR uint16_t RmtDurationReset = FromNs(200000); // 200us + + static void IRAM_ATTR Translate(const void* src, + rmt_item32_t* dest, + size_t src_size, + size_t wanted_num, + size_t* translated_size, + size_t* item_num); +}; + +void NeoEsp32RmtSpeedTm1815::Translate(const void* src, + rmt_item32_t* dest, + size_t src_size, + size_t wanted_num, + size_t* translated_size, + size_t* item_num) +{ + _translate(src, dest, src_size, wanted_num, translated_size, item_num, + RmtBit0, RmtBit1, RmtDurationReset); +} + +#else // ESP8266 +class NeoEspBitBangSpeedTm1815 +{ +public: + const static uint32_t T0H = (F_CPU / 5833332 - CYCLES_LOOPTEST); // 0.7us + const static uint32_t T1H = (F_CPU / 3333332 - CYCLES_LOOPTEST); // 1.5us + const static uint32_t Period = (F_CPU / 1600000 - CYCLES_LOOPTEST); // 2.5us per bit + + static const uint32_t ResetTimeUs = 200; + const static uint32_t TLatch = (F_CPU / 20000 - CYCLES_LOOPTEST); // 200us, be generous +}; + +class NeoEsp8266UartSpeedTm1815 // values taken from "400kHz" speed bus but extended reset time (just like TM1814 does with 800kHz timings) +{ +public: + static const uint32_t ByteSendTimeUs = 20; // us it takes to send a single pixel element at 400khz speed + static const uint32_t UartBaud = 1600000; // 400mhz, 4 serial bytes per NeoByte + static const uint32_t ResetTimeUs = 200; // us between data send bursts to reset for next update +}; + +class NeoWrgbTm1815Feature : + public Neo4ByteFeature, + public NeoElementsTm1814Settings +{ +}; +#endif + +// I2S / DMA custom timing +class NeoBitsSpeedTm1815 : public NeoBitsSpeedBase +{ +public: + const static uint16_t BitSendTimeNs = 2500; + const static uint16_t ResetTimeUs = 200; +}; + +// TM1815 methods +#ifdef ESP32 + // ESP32 RMT Methods + #ifdef USE_NEOPIXELBUS_RMT_HI + typedef NeoEsp32RmtHIMethodBase NeoEsp32RmtHINTm1815Method; + #else + typedef NeoEsp32RmtMethodBase NeoEsp32RmtNTm1815Method; + #endif + + // ESP32 I2S Methods + #if !defined(CONFIG_IDF_TARGET_ESP32C3) + typedef NeoEsp32I2sMethodBase NeoEsp32I2s0Tm1815Method; + typedef NeoEsp32I2sMethodBase NeoEsp32I2s1Tm1815Method; + typedef NeoEsp32I2sXMethodBase NeoEsp32I2s0X8Tm1815Method; // used by S2 + typedef NeoEsp32I2sXMethodBase NeoEsp32I2s1X8Tm1815Method; // used by classic ESP32 + #if defined(CONFIG_IDF_TARGET_ESP32S3) + typedef NeoEsp32LcdXMethodBase NeoEsp32LcdX8Tm1815Method; // S3 only + #endif + // I2S Aliases + #if defined(CONFIG_IDF_TARGET_ESP32S3) + typedef NeoEsp32LcdX8Tm1815Method X8Tm1815Method; + #elif defined(CONFIG_IDF_TARGET_ESP32S2) + typedef NeoEsp32I2s0X8Tm1815Method X8Tm1815Method; + #else // ESP32 classic + typedef NeoEsp32I2s1X8Tm1815Method X8Tm1815Method; + #endif + #endif // !CONFIG_IDF_TARGET_ESP32C3 + + #else // ESP8266 + typedef NeoEsp8266UartMethodBase, NeoEsp8266UartInverted> NeoEsp8266Uart0Tm1815Method; + typedef NeoEsp8266UartMethodBase, NeoEsp8266UartInverted> NeoEsp8266Uart1Tm1815Method; + typedef NeoEsp8266DmaMethodBase,NeoBitsSpeedTm1815> NeoEsp8266DmaTm1815Method; + typedef NeoEspBitBangMethodBase NeoEsp8266BitBangTm1815Method; +#endif + +#endif // BusCustomNPBtiming_h \ No newline at end of file diff --git a/wled00/bus_wrapper.h b/wled00/bus_wrapper.h index 45bb07c5ba..f269e84b21 100644 --- a/wled00/bus_wrapper.h +++ b/wled00/bus_wrapper.h @@ -4,6 +4,7 @@ //#define NPB_CONF_4STEP_CADENCE #include "NeoPixelBus.h" +#include "bus_customNPBtiming.h" //Hardware SPI Pins #define P_8266_HS_MOSI 13 @@ -147,113 +148,12 @@ #if !defined(WLED_USE_SHARED_RMT) && !defined(__riscv) #include #define NeoEsp32RmtMethod(x) NeoEsp32RmtHIN ## x ## Method -#define USE_NEOPIXELBUS_RMT_HI #else #include "internal/methods/NeoEsp32RmtMethod.h" // needed for custom RMT types #define NeoEsp32RmtMethod(x) NeoEsp32RmtN ## x ## Method #endif - -// special types and classes not officially supported by NPB - -// TM1815 is exactly half the speed of TM1814, normal is inverted signal compared to WS281x (low pulse timing, high idle/reset) -//RMT timing -class NeoEsp32RmtSpeedTm1815 : public NeoEsp32RmtInvertedSpeedBase -{ -public: - const static DRAM_ATTR uint32_t RmtBit0 = Item32Val(740, 1780); - const static DRAM_ATTR uint32_t RmtBit1 = Item32Val(1440, 1060); - const static DRAM_ATTR uint16_t RmtDurationReset = FromNs(200000); // 200us - - static void IRAM_ATTR Translate(const void* src, - rmt_item32_t* dest, - size_t src_size, - size_t wanted_num, - size_t* translated_size, - size_t* item_num); -}; - -void NeoEsp32RmtSpeedTm1815::Translate(const void* src, - rmt_item32_t* dest, - size_t src_size, - size_t wanted_num, - size_t* translated_size, - size_t* item_num) -{ - _translate(src, dest, src_size, wanted_num, translated_size, item_num, - RmtBit0, RmtBit1, RmtDurationReset); -} - -#else // ESP8266 -// Tm1815 normal is inverted signal -class NeoEspBitBangSpeedTm1815 -{ -public: - const static uint32_t T0H = (F_CPU / 5833332 - CYCLES_LOOPTEST); // 0.7us - const static uint32_t T1H = (F_CPU / 3333332 - CYCLES_LOOPTEST); // 1.5us - const static uint32_t Period = (F_CPU / 1600000 - CYCLES_LOOPTEST); // 2.5us per bit - - static const uint32_t ResetTimeUs = 200; - const static uint32_t TLatch = (F_CPU / 20000 - CYCLES_LOOPTEST); // 200us, be generous -}; - -class NeoEsp8266UartSpeedTm1815 // values taken from "400kHz" speed bus but extended reset time (just like TM1814 does with 800kHz timings) -{ -public: - static const uint32_t ByteSendTimeUs = 20; // us it takes to send a single pixel element at 400khz speed - static const uint32_t UartBaud = 1600000; // 400mhz, 4 serial bytes per NeoByte - static const uint32_t ResetTimeUs = 200; // us between data send bursts to reset for next update -}; - -class NeoWrgbTm1815Feature : - public Neo4ByteFeature, - public NeoElementsTm1814Settings -{ -}; #endif -// I2S / DMA custom timing -class NeoBitsSpeedTm1815 : public NeoBitsSpeedBase -{ -public: - const static uint16_t BitSendTimeNs = 2500; - const static uint16_t ResetTimeUs = 200; -}; - -// special non-native I2S NPB methods -#ifdef ESP32 -// ESP32 RMT Methods -#ifdef USE_NEOPIXELBUS_RMT_HI -typedef NeoEsp32RmtHIMethodBase NeoEsp32RmtHINTm1815Method; -#else -typedef NeoEsp32RmtMethodBase NeoEsp32RmtNTm1815Method; -#endif -#if !defined(CONFIG_IDF_TARGET_ESP32C3) -// ESP32 I2S Methods -typedef NeoEsp32I2sMethodBase NeoEsp32I2s0Tm1815Method; -typedef NeoEsp32I2sMethodBase NeoEsp32I2s1Tm1815Method; -typedef NeoEsp32I2sXMethodBase NeoEsp32I2s0X8Tm1815Method; // user for S2 -typedef NeoEsp32I2sXMethodBase NeoEsp32I2s1X8Tm1815Method; // use for classic ESP32 (not defined for S2, can be defined for S3 but is not used) -#if defined(CONFIG_IDF_TARGET_ESP32S3) -typedef NeoEsp32LcdXMethodBase NeoEsp32LcdX8Tm1815Method; // S3 only -#endif -// I2S Aliases -#if defined(CONFIG_IDF_TARGET_ESP32S3) -typedef NeoEsp32LcdX8Tm1815Method X8Tm1815Method; -#elif defined(CONFIG_IDF_TARGET_ESP32S2) -typedef NeoEsp32I2s0X8Tm1815Method X8Tm1815Method; -#else // ESP32 classic -typedef NeoEsp32I2s1X8Tm1815Method X8Tm1815Method; -#endif -#endif // !CONFIG_IDF_TARGET_ESP32C3 -#else // ESP8266 - -typedef NeoEsp8266UartMethodBase, NeoEsp8266UartInverted> NeoEsp8266Uart0Tm1815Method; -typedef NeoEsp8266UartMethodBase, NeoEsp8266UartInverted> NeoEsp8266Uart1Tm1815Method; -typedef NeoEsp8266DmaMethodBase,NeoBitsSpeedTm1815> NeoEsp8266DmaTm1815Method; -typedef NeoEspBitBangMethodBase NeoEsp8266BitBangTm1815Method; - -#endif // ESP32 - // In the following NeoGammaNullMethod can be replaced with NeoGammaWLEDMethod to perform Gamma correction implicitly // unfortunately that may apply Gamma correction to pre-calculated palettes which is undesired From 0f77d660430b9c60404d8a42cbc5ca4d75bcc0bb Mon Sep 17 00:00:00 2001 From: Damian Schneider Date: Sat, 3 Jan 2026 16:40:01 +0100 Subject: [PATCH 6/8] revert unnecessary changes, some cleanup --- wled00/bus_customNPBtiming.h | 30 ++++++++++++------------------ wled00/bus_wrapper.h | 19 ++++++++----------- 2 files changed, 20 insertions(+), 29 deletions(-) diff --git a/wled00/bus_customNPBtiming.h b/wled00/bus_customNPBtiming.h index 7dd52be7ff..45279e3f0b 100644 --- a/wled00/bus_customNPBtiming.h +++ b/wled00/bus_customNPBtiming.h @@ -9,26 +9,23 @@ #include #include "NeoPixelBus.h" -#define WLED_USE_SHARED_RMT - -#ifdef ESP32 -// RMT driver selection +#ifdef ARDUINO_ARCH_ESP32 +// RMT driver selection, includes needed for custom RMT types #if !defined(WLED_USE_SHARED_RMT) && !defined(__riscv) #include -//#define NeoEsp32RmtMethod(x) NeoEsp32RmtHIN ## x ## Method #define USE_NEOPIXELBUS_RMT_HI #else -#include "internal/methods/NeoEsp32RmtMethod.h" // needed for custom RMT types -//#define NeoEsp32RmtMethod(x) NeoEsp32RmtN ## x ## Method +#include "internal/methods/NeoEsp32RmtMethod.h" +#endif #endif //////////////////////////////// -// TM1815 timing definitions // +// TM1815 timing and methods // //////////////////////////////// // TM1815 is exactly half the speed of TM1814, other features are identical so can use TM1814 as a base class // normal timing pulses are inverted compared to WS281x (low pulse timing, high idle/reset) - +#ifdef ARDUINO_ARCH_ESP32 // RMT timing class NeoEsp32RmtSpeedTm1815 : public NeoEsp32RmtInvertedSpeedBase { @@ -55,7 +52,6 @@ void NeoEsp32RmtSpeedTm1815::Translate(const void* src, _translate(src, dest, src_size, wanted_num, translated_size, item_num, RmtBit0, RmtBit1, RmtDurationReset); } - #else // ESP8266 class NeoEspBitBangSpeedTm1815 { @@ -92,14 +88,13 @@ class NeoBitsSpeedTm1815 : public NeoBitsSpeedBase }; // TM1815 methods -#ifdef ESP32 +#ifdef ARDUINO_ARCH_ESP32 // ESP32 RMT Methods #ifdef USE_NEOPIXELBUS_RMT_HI typedef NeoEsp32RmtHIMethodBase NeoEsp32RmtHINTm1815Method; #else typedef NeoEsp32RmtMethodBase NeoEsp32RmtNTm1815Method; #endif - // ESP32 I2S Methods #if !defined(CONFIG_IDF_TARGET_ESP32C3) typedef NeoEsp32I2sMethodBase NeoEsp32I2s0Tm1815Method; @@ -118,12 +113,11 @@ class NeoBitsSpeedTm1815 : public NeoBitsSpeedBase typedef NeoEsp32I2s1X8Tm1815Method X8Tm1815Method; #endif #endif // !CONFIG_IDF_TARGET_ESP32C3 - - #else // ESP8266 - typedef NeoEsp8266UartMethodBase, NeoEsp8266UartInverted> NeoEsp8266Uart0Tm1815Method; - typedef NeoEsp8266UartMethodBase, NeoEsp8266UartInverted> NeoEsp8266Uart1Tm1815Method; - typedef NeoEsp8266DmaMethodBase,NeoBitsSpeedTm1815> NeoEsp8266DmaTm1815Method; - typedef NeoEspBitBangMethodBase NeoEsp8266BitBangTm1815Method; +#else // ESP8266 + typedef NeoEsp8266UartMethodBase, NeoEsp8266UartInverted> NeoEsp8266Uart0Tm1815Method; + typedef NeoEsp8266UartMethodBase, NeoEsp8266UartInverted> NeoEsp8266Uart1Tm1815Method; + typedef NeoEsp8266DmaMethodBase,NeoBitsSpeedTm1815> NeoEsp8266DmaTm1815Method; + typedef NeoEspBitBangMethodBase NeoEsp8266BitBangTm1815Method; #endif #endif // BusCustomNPBtiming_h \ No newline at end of file diff --git a/wled00/bus_wrapper.h b/wled00/bus_wrapper.h index f269e84b21..bf7522b6be 100644 --- a/wled00/bus_wrapper.h +++ b/wled00/bus_wrapper.h @@ -143,17 +143,6 @@ #define I_HS_LPO_3 109 #define I_SS_LPO_3 110 -#ifdef ESP32 -// RMT driver selection -#if !defined(WLED_USE_SHARED_RMT) && !defined(__riscv) -#include -#define NeoEsp32RmtMethod(x) NeoEsp32RmtHIN ## x ## Method -#else -#include "internal/methods/NeoEsp32RmtMethod.h" // needed for custom RMT types -#define NeoEsp32RmtMethod(x) NeoEsp32RmtN ## x ## Method -#endif -#endif - // In the following NeoGammaNullMethod can be replaced with NeoGammaWLEDMethod to perform Gamma correction implicitly // unfortunately that may apply Gamma correction to pre-calculated palettes which is undesired @@ -272,6 +261,14 @@ typedef NeoEsp32I2s1Tm1914Method X1Tm1914Method; #endif +// RMT driver selection +#if !defined(WLED_USE_SHARED_RMT) && !defined(__riscv) +#include +#define NeoEsp32RmtMethod(x) NeoEsp32RmtHIN ## x ## Method +#else +#define NeoEsp32RmtMethod(x) NeoEsp32RmtN ## x ## Method +#endif + //RGB #define B_32_RN_NEO_3 NeoPixelBus // ESP32, S2, S3, C3 //#define B_32_IN_NEO_3 NeoPixelBus // ESP32 (dynamic I2S selection) From d733b91ab4cb2e7d10213b5db1b43defec0c2b71 Mon Sep 17 00:00:00 2001 From: Damian Schneider Date: Sat, 3 Jan 2026 18:08:33 +0100 Subject: [PATCH 7/8] Fix compile error for S3 --- wled00/bus_customNPBtiming.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/wled00/bus_customNPBtiming.h b/wled00/bus_customNPBtiming.h index 45279e3f0b..c5ebed03d0 100644 --- a/wled00/bus_customNPBtiming.h +++ b/wled00/bus_customNPBtiming.h @@ -97,12 +97,13 @@ class NeoBitsSpeedTm1815 : public NeoBitsSpeedBase #endif // ESP32 I2S Methods #if !defined(CONFIG_IDF_TARGET_ESP32C3) + #if defined(CONFIG_IDF_TARGET_ESP32S3) + typedef NeoEsp32LcdXMethodBase NeoEsp32LcdX8Tm1815Method; // S3 only + #else // ESP32 classic & S2 typedef NeoEsp32I2sMethodBase NeoEsp32I2s0Tm1815Method; typedef NeoEsp32I2sMethodBase NeoEsp32I2s1Tm1815Method; typedef NeoEsp32I2sXMethodBase NeoEsp32I2s0X8Tm1815Method; // used by S2 typedef NeoEsp32I2sXMethodBase NeoEsp32I2s1X8Tm1815Method; // used by classic ESP32 - #if defined(CONFIG_IDF_TARGET_ESP32S3) - typedef NeoEsp32LcdXMethodBase NeoEsp32LcdX8Tm1815Method; // S3 only #endif // I2S Aliases #if defined(CONFIG_IDF_TARGET_ESP32S3) From 8f0eeb90f074e30776dc2831e8161c306ebd1e92 Mon Sep 17 00:00:00 2001 From: Damian Schneider Date: Sat, 3 Jan 2026 18:22:55 +0100 Subject: [PATCH 8/8] bugfixes, now also compiles for S2 --- wled00/bus_customNPBtiming.h | 68 +++++++++++++++++++----------------- wled00/bus_manager.cpp | 2 +- 2 files changed, 36 insertions(+), 34 deletions(-) diff --git a/wled00/bus_customNPBtiming.h b/wled00/bus_customNPBtiming.h index c5ebed03d0..de0e8ca033 100644 --- a/wled00/bus_customNPBtiming.h +++ b/wled00/bus_customNPBtiming.h @@ -30,51 +30,51 @@ class NeoEsp32RmtSpeedTm1815 : public NeoEsp32RmtInvertedSpeedBase { public: - const static DRAM_ATTR uint32_t RmtBit0 = Item32Val(740, 1780); - const static DRAM_ATTR uint32_t RmtBit1 = Item32Val(1440, 1060); - const static DRAM_ATTR uint16_t RmtDurationReset = FromNs(200000); // 200us + const static DRAM_ATTR uint32_t RmtBit0 = Item32Val(740, 1780); + const static DRAM_ATTR uint32_t RmtBit1 = Item32Val(1440, 1060); + const static DRAM_ATTR uint16_t RmtDurationReset = FromNs(200000); // 200us - static void IRAM_ATTR Translate(const void* src, - rmt_item32_t* dest, - size_t src_size, - size_t wanted_num, - size_t* translated_size, - size_t* item_num); -}; - -void NeoEsp32RmtSpeedTm1815::Translate(const void* src, + static void IRAM_ATTR Translate(const void* src, rmt_item32_t* dest, size_t src_size, size_t wanted_num, size_t* translated_size, - size_t* item_num) + size_t* item_num); +}; + +void NeoEsp32RmtSpeedTm1815::Translate(const void* src, + rmt_item32_t* dest, + size_t src_size, + size_t wanted_num, + size_t* translated_size, + size_t* item_num) { - _translate(src, dest, src_size, wanted_num, translated_size, item_num, - RmtBit0, RmtBit1, RmtDurationReset); + _translate(src, dest, src_size, wanted_num, translated_size, item_num, + RmtBit0, RmtBit1, RmtDurationReset); } #else // ESP8266 class NeoEspBitBangSpeedTm1815 { public: - const static uint32_t T0H = (F_CPU / 5833332 - CYCLES_LOOPTEST); // 0.7us - const static uint32_t T1H = (F_CPU / 3333332 - CYCLES_LOOPTEST); // 1.5us - const static uint32_t Period = (F_CPU / 1600000 - CYCLES_LOOPTEST); // 2.5us per bit + const static uint32_t T0H = (F_CPU / 5833332 - CYCLES_LOOPTEST); // 0.7us + const static uint32_t T1H = (F_CPU / 3333332 - CYCLES_LOOPTEST); // 1.5us + const static uint32_t Period = (F_CPU / 1600000 - CYCLES_LOOPTEST); // 2.5us per bit - static const uint32_t ResetTimeUs = 200; - const static uint32_t TLatch = (F_CPU / 20000 - CYCLES_LOOPTEST); // 200us, be generous + static const uint32_t ResetTimeUs = 200; + const static uint32_t TLatch = (F_CPU / 20000 - CYCLES_LOOPTEST); // 200us, be generous }; class NeoEsp8266UartSpeedTm1815 // values taken from "400kHz" speed bus but extended reset time (just like TM1814 does with 800kHz timings) { public: - static const uint32_t ByteSendTimeUs = 20; // us it takes to send a single pixel element at 400khz speed - static const uint32_t UartBaud = 1600000; // 400mhz, 4 serial bytes per NeoByte - static const uint32_t ResetTimeUs = 200; // us between data send bursts to reset for next update + static const uint32_t ByteSendTimeUs = 20; // us it takes to send a single pixel element at 400khz speed + static const uint32_t UartBaud = 1600000; // 400khz output, 4 serial bytes per NeoByte + static const uint32_t ResetTimeUs = 200; // use between data send bursts to reset for next update }; class NeoWrgbTm1815Feature : - public Neo4ByteFeature, - public NeoElementsTm1814Settings + public Neo4ByteFeature, + public NeoElementsTm1814Settings { }; #endif @@ -98,20 +98,22 @@ class NeoBitsSpeedTm1815 : public NeoBitsSpeedBase // ESP32 I2S Methods #if !defined(CONFIG_IDF_TARGET_ESP32C3) #if defined(CONFIG_IDF_TARGET_ESP32S3) - typedef NeoEsp32LcdXMethodBase NeoEsp32LcdX8Tm1815Method; // S3 only + typedef NeoEsp32LcdXMethodBase NeoEsp32LcdX8Tm1815Method; // S3 only #else // ESP32 classic & S2 - typedef NeoEsp32I2sMethodBase NeoEsp32I2s0Tm1815Method; - typedef NeoEsp32I2sMethodBase NeoEsp32I2s1Tm1815Method; - typedef NeoEsp32I2sXMethodBase NeoEsp32I2s0X8Tm1815Method; // used by S2 - typedef NeoEsp32I2sXMethodBase NeoEsp32I2s1X8Tm1815Method; // used by classic ESP32 + typedef NeoEsp32I2sMethodBase NeoEsp32I2s0Tm1815Method; + typedef NeoEsp32I2sXMethodBase NeoEsp32I2s0X8Tm1815Method; // used by S2, not used by classic ESP32 + #if defined(CONFIG_IDF_TARGET_ESP32) + typedef NeoEsp32I2sMethodBase NeoEsp32I2s1Tm1815Method; + typedef NeoEsp32I2sXMethodBase NeoEsp32I2s1X8Tm1815Method; // available on classic ESP32 only + #endif #endif // I2S Aliases #if defined(CONFIG_IDF_TARGET_ESP32S3) - typedef NeoEsp32LcdX8Tm1815Method X8Tm1815Method; + typedef NeoEsp32LcdX8Tm1815Method X8Tm1815Method; #elif defined(CONFIG_IDF_TARGET_ESP32S2) - typedef NeoEsp32I2s0X8Tm1815Method X8Tm1815Method; + typedef NeoEsp32I2s0X8Tm1815Method X8Tm1815Method; #else // ESP32 classic - typedef NeoEsp32I2s1X8Tm1815Method X8Tm1815Method; + typedef NeoEsp32I2s1X8Tm1815Method X8Tm1815Method; #endif #endif // !CONFIG_IDF_TARGET_ESP32C3 #else // ESP8266 diff --git a/wled00/bus_manager.cpp b/wled00/bus_manager.cpp index 86ce3e104d..b69317453c 100644 --- a/wled00/bus_manager.cpp +++ b/wled00/bus_manager.cpp @@ -159,7 +159,7 @@ uint32_t Bus::autoWhiteCalc(uint32_t c) const { BusDigital::BusDigital(const BusConfig &bc, uint8_t nr) -: Bus(bc.type, bc.start, bc.autoWhite, bc.count, bc.reversed, (bc.refreshReq || bc.type == (TYPE_TM1814 || TYPE_TM1815))) // TM1814/15 need refresh or they fall-back to a "demo mode" +: Bus(bc.type, bc.start, bc.autoWhite, bc.count, bc.reversed, (bc.refreshReq || bc.type == TYPE_TM1814 || bc.type == TYPE_TM1815)) // TM1814/15 need refresh or they fall-back to a "demo mode" , _skip(bc.skipAmount) //sacrificial pixels , _colorOrder(bc.colorOrder) , _milliAmpsPerLed(bc.milliAmpsPerLed)