Merge branch 'development' into prerelease-14.0.0

This commit is contained in:
Theo Arends 2024-05-14 11:07:06 +02:00
commit ba2ad90384
14 changed files with 368 additions and 193 deletions

View File

@ -40,6 +40,8 @@ All notable changes to this project will be documented in this file.
- TLS Letsencrypt replace R3 CA with long-term ISRG_Root_X1 CA, which works with R3 and R10-R14 (#21352) - TLS Letsencrypt replace R3 CA with long-term ISRG_Root_X1 CA, which works with R3 and R10-R14 (#21352)
- GPIOViewer from v1.5.0 to v1.5.2 - GPIOViewer from v1.5.0 to v1.5.2
- ESP32 Core3 platform update from 2024.05.10 to 2024.05.11 (#21381) - ESP32 Core3 platform update from 2024.05.10 to 2024.05.11 (#21381)
- Berry `Leds` uses native WS2812 driver by default (#21406)
- Command ``Pixels`` initiates a restart before activation due to changed NeoPixelBus library (#21406)
### Fixed ### Fixed
- HASPmota `align` attribute and expand PNG cache (#21228) - HASPmota `align` attribute and expand PNG cache (#21228)
@ -56,6 +58,7 @@ All notable changes to this project will be documented in this file.
- Avoid unwanted OTA upgrade when safeboot starts for the first time (#21360) - Avoid unwanted OTA upgrade when safeboot starts for the first time (#21360)
- Matter broken NOCStruct types preventing pairing with HA (#21365) - Matter broken NOCStruct types preventing pairing with HA (#21365)
- jpeg compile core3 (#21387) - jpeg compile core3 (#21387)
- Berry `gpio.dac_voltage()` (#21403)
### Removed ### Removed
- LVGL disabled vector graphics (#21242) - LVGL disabled vector graphics (#21242)

View File

@ -40,10 +40,10 @@ This release will be supported from ESP32/Arduino library Core version **3.0.0**
Support of ESP8266 Core versions before 2.7.6 and ESP32 Core versions before 3.0.0 have been removed. Support of ESP8266 Core versions before 2.7.6 and ESP32 Core versions before 3.0.0 have been removed.
### Known issues ### Known issues with v14.0.0
Due to the change from ESP32 Arduino Core2/IDF4 to Arduino Core3/IDF5 not all functionality has been restored. The following features are known not to work on ESP32: Due to the change from ESP32 Arduino Core2/IDF4 to Arduino Core3/IDF5 not all functionality has been restored. The following features are known not to work on ESP32:
- Wifi Range Extender - Wifi Range Extender [#21200](https://github.com/arendst/Tasmota/issues/21200)
## Support of TLS ## Support of TLS
@ -177,6 +177,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasm
- GPIOViewer from v1.5.0 to v1.5.2 - GPIOViewer from v1.5.0 to v1.5.2
- Seriallog set to `SERIAL_LOG_LEVEL` at boot [#21363](https://github.com/arendst/Tasmota/issues/21363) - Seriallog set to `SERIAL_LOG_LEVEL` at boot [#21363](https://github.com/arendst/Tasmota/issues/21363)
- TLS Letsencrypt replace R3 CA with long-term ISRG_Root_X1 CA, which works with R3 and R10-R14 [#21352](https://github.com/arendst/Tasmota/issues/21352) - TLS Letsencrypt replace R3 CA with long-term ISRG_Root_X1 CA, which works with R3 and R10-R14 [#21352](https://github.com/arendst/Tasmota/issues/21352)
- Command ``Pixels`` initiates a restart before activation due to changed NeoPixelBus library [#21406](https://github.com/arendst/Tasmota/issues/21406)
- Command ``EthType`` option selection [#21317](https://github.com/arendst/Tasmota/issues/21317) - Command ``EthType`` option selection [#21317](https://github.com/arendst/Tasmota/issues/21317)
- Refactor Platformio script `post_esp32.py` [#20966](https://github.com/arendst/Tasmota/issues/20966) - Refactor Platformio script `post_esp32.py` [#20966](https://github.com/arendst/Tasmota/issues/20966)
- SGP4x Domoticz air quality value from raw to computed [#18880](https://github.com/arendst/Tasmota/issues/18880) - SGP4x Domoticz air quality value from raw to computed [#18880](https://github.com/arendst/Tasmota/issues/18880)
@ -194,6 +195,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasm
- ESP32 WiFi phy modes 11n and 11ax represented as HT20, HT40 and HE20 [#19350](https://github.com/arendst/Tasmota/issues/19350) - ESP32 WiFi phy modes 11n and 11ax represented as HT20, HT40 and HE20 [#19350](https://github.com/arendst/Tasmota/issues/19350)
- berry.exe (pre-compiled for Windows) updated to latest Berry patches [#21024](https://github.com/arendst/Tasmota/issues/21024) - berry.exe (pre-compiled for Windows) updated to latest Berry patches [#21024](https://github.com/arendst/Tasmota/issues/21024)
- Berry class `int64` made immutable [#20727](https://github.com/arendst/Tasmota/issues/20727) - Berry class `int64` made immutable [#20727](https://github.com/arendst/Tasmota/issues/20727)
- Berry `Leds` uses native WS2812 driver by default [#21406](https://github.com/arendst/Tasmota/issues/21406)
- Matter reduce memory usage when reading with wildcards [#20809](https://github.com/arendst/Tasmota/issues/20809) - Matter reduce memory usage when reading with wildcards [#20809](https://github.com/arendst/Tasmota/issues/20809)
- LVGL make lv_touch_3_buttons more responsive [#20728](https://github.com/arendst/Tasmota/issues/20728) - LVGL make lv_touch_3_buttons more responsive [#20728](https://github.com/arendst/Tasmota/issues/20728)
- LVGL optimize fonts and add icons [#20880](https://github.com/arendst/Tasmota/issues/20880) - LVGL optimize fonts and add icons [#20880](https://github.com/arendst/Tasmota/issues/20880)
@ -228,6 +230,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasm
- Berry walrus bug when assigning to self [#21015](https://github.com/arendst/Tasmota/issues/21015) - Berry walrus bug when assigning to self [#21015](https://github.com/arendst/Tasmota/issues/21015)
- Berry `web_add_handler` called before `Webserver` is initialized [#21272](https://github.com/arendst/Tasmota/issues/21272) - Berry `web_add_handler` called before `Webserver` is initialized [#21272](https://github.com/arendst/Tasmota/issues/21272)
- Berry `math.inf`, `math.isinf()` and fixed json ouput for `inf` and `nan` [#21304](https://github.com/arendst/Tasmota/issues/21304) - Berry `math.inf`, `math.isinf()` and fixed json ouput for `inf` and `nan` [#21304](https://github.com/arendst/Tasmota/issues/21304)
- Berry `gpio.dac_voltage()` [#21403](https://github.com/arendst/Tasmota/issues/21403)
- Matter broken NOCStruct types preventing pairing with HA [#21365](https://github.com/arendst/Tasmota/issues/21365) - Matter broken NOCStruct types preventing pairing with HA [#21365](https://github.com/arendst/Tasmota/issues/21365)
- LVGL restore `lv_palette` functions [#21232](https://github.com/arendst/Tasmota/issues/21232) - LVGL restore `lv_palette` functions [#21232](https://github.com/arendst/Tasmota/issues/21232)
- LVGL fix memory allocation of flush buffers [#21256](https://github.com/arendst/Tasmota/issues/21256) - LVGL fix memory allocation of flush buffers [#21256](https://github.com/arendst/Tasmota/issues/21256)

View File

@ -33,23 +33,27 @@ class Leds : Leds_ntv
# typ:int (optional) = Type of LED, defaults to WS2812 RGB # typ:int (optional) = Type of LED, defaults to WS2812 RGB
# rmt:int (optional) = RMT hardware channel to use, leave default unless you have a good reason # rmt:int (optional) = RMT hardware channel to use, leave default unless you have a good reason
def init(leds, gpio_phy, typ, rmt) # rmt is optional def init(leds, gpio_phy, typ, rmt) # rmt is optional
import gpio
self.gamma = true # gamma is enabled by default, it should be disabled explicitly if needed self.gamma = true # gamma is enabled by default, it should be disabled explicitly if needed
self.leds = int(leds) if (gpio_phy == nil) || (gpio_phy == gpio.pin(gpio.WS2812, 0))
self.bri = 127 # 50% brightness by default # use native driver
self.ctor() # no parameters
self.leds = self.pixel_count()
import light
self.bri = light.get()['bri']
else
# use pure Berry driver
self.leds = int(leds)
self.bri = 127 # 50% brightness by default
# if no GPIO, abort # initialize the structure
if gpio_phy == nil self.ctor(self.leds, gpio_phy, typ, rmt)
raise "valuer_error", "no GPIO specified for neopixelbus"
end end
# initialize the structure
self.ctor(self.leds, gpio_phy, typ, rmt)
if self._p == nil raise "internal_error", "couldn't not initialize noepixelbus" end if self._p == nil raise "internal_error", "couldn't not initialize noepixelbus" end
# call begin # call begin
self.begin() self.begin()
end end
# assign RMT # assign RMT
@ -106,13 +110,17 @@ class Leds : Leds_ntv
end end
def ctor(leds, gpio_phy, typ, rmt) def ctor(leds, gpio_phy, typ, rmt)
if typ == nil if gpio_phy == nil
typ = self.WS2812_GRB self.call_native(0) # native driver
else
if typ == nil
typ = self.WS2812_GRB
end
if rmt == nil
rmt = self.assign_rmt(gpio_phy)
end
self.call_native(0, leds, gpio_phy, typ, rmt)
end end
if rmt == nil
rmt = self.assign_rmt(gpio_phy)
end
self.call_native(0, leds, gpio_phy, typ, rmt)
end end
def begin() def begin()
self.call_native(1) self.call_native(1)

View File

@ -649,7 +649,7 @@ be_local_closure(Leds_clear, /* name */
********************************************************************/ ********************************************************************/
be_local_closure(Leds_init, /* name */ be_local_closure(Leds_init, /* name */
be_nested_proto( be_nested_proto(
11, /* nstack */ 12, /* nstack */
5, /* argc */ 5, /* argc */
2, /* varg */ 2, /* varg */
0, /* has upvals */ 0, /* has upvals */
@ -657,47 +657,69 @@ be_local_closure(Leds_init, /* name */
0, /* has sup protos */ 0, /* has sup protos */
NULL, /* no sub protos */ NULL, /* no sub protos */
1, /* has constants */ 1, /* has constants */
( &(const bvalue[10]) { /* constants */ ( &(const bvalue[15]) { /* constants */
/* K0 */ be_nested_str(gamma), /* K0 */ be_nested_str(gpio),
/* K1 */ be_nested_str(leds), /* K1 */ be_nested_str(gamma),
/* K2 */ be_nested_str(bri), /* K2 */ be_nested_str(pin),
/* K3 */ be_nested_str(valuer_error), /* K3 */ be_nested_str(WS2812),
/* K4 */ be_nested_str(no_X20GPIO_X20specified_X20for_X20neopixelbus), /* K4 */ be_const_int(0),
/* K5 */ be_nested_str(ctor), /* K5 */ be_nested_str(ctor),
/* K6 */ be_nested_str(_p), /* K6 */ be_nested_str(leds),
/* K7 */ be_nested_str(internal_error), /* K7 */ be_nested_str(pixel_count),
/* K8 */ be_nested_str(couldn_X27t_X20not_X20initialize_X20noepixelbus), /* K8 */ be_nested_str(light),
/* K9 */ be_nested_str(begin), /* K9 */ be_nested_str(bri),
/* K10 */ be_nested_str(get),
/* K11 */ be_nested_str(_p),
/* K12 */ be_nested_str(internal_error),
/* K13 */ be_nested_str(couldn_X27t_X20not_X20initialize_X20noepixelbus),
/* K14 */ be_nested_str(begin),
}), }),
&be_const_str_init, &be_const_str_init,
&be_const_str_solidified, &be_const_str_solidified,
( &(const binstruction[26]) { /* code */ ( &(const binstruction[43]) { /* code */
0x50140200, // 0000 LDBOOL R5 1 0 0xA4160000, // 0000 IMPORT R5 K0
0x90020005, // 0001 SETMBR R0 K0 R5 0x50180200, // 0001 LDBOOL R6 1 0
0x60140009, // 0002 GETGBL R5 G9 0x90020206, // 0002 SETMBR R0 K1 R6
0x5C180200, // 0003 MOVE R6 R1 0x4C180000, // 0003 LDNIL R6
0x7C140200, // 0004 CALL R5 1 0x1C180406, // 0004 EQ R6 R2 R6
0x90020205, // 0005 SETMBR R0 K1 R5 0x741A0005, // 0005 JMPT R6 #000C
0x5416007E, // 0006 LDINT R5 127 0x8C180B02, // 0006 GETMET R6 R5 K2
0x90020405, // 0007 SETMBR R0 K2 R5 0x88200B03, // 0007 GETMBR R8 R5 K3
0x4C140000, // 0008 LDNIL R5 0x58240004, // 0008 LDCONST R9 K4
0x1C140405, // 0009 EQ R5 R2 R5 0x7C180600, // 0009 CALL R6 3
0x78160000, // 000A JMPF R5 #000C 0x1C180406, // 000A EQ R6 R2 R6
0xB0060704, // 000B RAISE 1 K3 K4 0x781A000A, // 000B JMPF R6 #0017
0x8C140105, // 000C GETMET R5 R0 K5 0x8C180105, // 000C GETMET R6 R0 K5
0x881C0101, // 000D GETMBR R7 R0 K1 0x7C180200, // 000D CALL R6 1
0x5C200400, // 000E MOVE R8 R2 0x8C180107, // 000E GETMET R6 R0 K7
0x5C240600, // 000F MOVE R9 R3 0x7C180200, // 000F CALL R6 1
0x5C280800, // 0010 MOVE R10 R4 0x90020C06, // 0010 SETMBR R0 K6 R6
0x7C140A00, // 0011 CALL R5 5 0xA41A1000, // 0011 IMPORT R6 K8
0x88140106, // 0012 GETMBR R5 R0 K6 0x8C1C0D0A, // 0012 GETMET R7 R6 K10
0x4C180000, // 0013 LDNIL R6 0x7C1C0200, // 0013 CALL R7 1
0x1C140A06, // 0014 EQ R5 R5 R6 0x941C0F09, // 0014 GETIDX R7 R7 K9
0x78160000, // 0015 JMPF R5 #0017 0x90021207, // 0015 SETMBR R0 K9 R7
0xB0060F08, // 0016 RAISE 1 K7 K8 0x7002000B, // 0016 JMP #0023
0x8C140109, // 0017 GETMET R5 R0 K9 0x60180009, // 0017 GETGBL R6 G9
0x7C140200, // 0018 CALL R5 1 0x5C1C0200, // 0018 MOVE R7 R1
0x80000000, // 0019 RET 0 0x7C180200, // 0019 CALL R6 1
0x90020C06, // 001A SETMBR R0 K6 R6
0x541A007E, // 001B LDINT R6 127
0x90021206, // 001C SETMBR R0 K9 R6
0x8C180105, // 001D GETMET R6 R0 K5
0x88200106, // 001E GETMBR R8 R0 K6
0x5C240400, // 001F MOVE R9 R2
0x5C280600, // 0020 MOVE R10 R3
0x5C2C0800, // 0021 MOVE R11 R4
0x7C180A00, // 0022 CALL R6 5
0x8818010B, // 0023 GETMBR R6 R0 K11
0x4C1C0000, // 0024 LDNIL R7
0x1C180C07, // 0025 EQ R6 R6 R7
0x781A0000, // 0026 JMPF R6 #0028
0xB006190D, // 0027 RAISE 1 K12 K13
0x8C18010E, // 0028 GETMET R6 R0 K14
0x7C180200, // 0029 CALL R6 1
0x80000000, // 002A RET 0
}) })
) )
); );
@ -2061,33 +2083,40 @@ be_local_closure(Leds_ctor, /* name */
NULL, /* no sub protos */ NULL, /* no sub protos */
1, /* has constants */ 1, /* has constants */
( &(const bvalue[ 4]) { /* constants */ ( &(const bvalue[ 4]) { /* constants */
/* K0 */ be_nested_str(WS2812_GRB), /* K0 */ be_nested_str(call_native),
/* K1 */ be_nested_str(assign_rmt), /* K1 */ be_const_int(0),
/* K2 */ be_nested_str(call_native), /* K2 */ be_nested_str(WS2812_GRB),
/* K3 */ be_const_int(0), /* K3 */ be_nested_str(assign_rmt),
}), }),
&be_const_str_ctor, &be_const_str_ctor,
&be_const_str_solidified, &be_const_str_solidified,
( &(const binstruction[19]) { /* code */ ( &(const binstruction[26]) { /* code */
0x4C140000, // 0000 LDNIL R5 0x4C140000, // 0000 LDNIL R5
0x1C140605, // 0001 EQ R5 R3 R5 0x1C140405, // 0001 EQ R5 R2 R5
0x78160000, // 0002 JMPF R5 #0004 0x78160003, // 0002 JMPF R5 #0007
0x880C0100, // 0003 GETMBR R3 R0 K0 0x8C140100, // 0003 GETMET R5 R0 K0
0x4C140000, // 0004 LDNIL R5 0x581C0001, // 0004 LDCONST R7 K1
0x1C140805, // 0005 EQ R5 R4 R5 0x7C140400, // 0005 CALL R5 2
0x78160003, // 0006 JMPF R5 #000B 0x70020011, // 0006 JMP #0019
0x8C140101, // 0007 GETMET R5 R0 K1 0x4C140000, // 0007 LDNIL R5
0x5C1C0400, // 0008 MOVE R7 R2 0x1C140605, // 0008 EQ R5 R3 R5
0x7C140400, // 0009 CALL R5 2 0x78160000, // 0009 JMPF R5 #000B
0x5C100A00, // 000A MOVE R4 R5 0x880C0102, // 000A GETMBR R3 R0 K2
0x8C140102, // 000B GETMET R5 R0 K2 0x4C140000, // 000B LDNIL R5
0x581C0003, // 000C LDCONST R7 K3 0x1C140805, // 000C EQ R5 R4 R5
0x5C200200, // 000D MOVE R8 R1 0x78160003, // 000D JMPF R5 #0012
0x5C240400, // 000E MOVE R9 R2 0x8C140103, // 000E GETMET R5 R0 K3
0x5C280600, // 000F MOVE R10 R3 0x5C1C0400, // 000F MOVE R7 R2
0x5C2C0800, // 0010 MOVE R11 R4 0x7C140400, // 0010 CALL R5 2
0x7C140C00, // 0011 CALL R5 6 0x5C100A00, // 0011 MOVE R4 R5
0x80000000, // 0012 RET 0 0x8C140100, // 0012 GETMET R5 R0 K0
0x581C0001, // 0013 LDCONST R7 K1
0x5C200200, // 0014 MOVE R8 R1
0x5C240400, // 0015 MOVE R9 R2
0x5C280600, // 0016 MOVE R10 R3
0x5C2C0800, // 0017 MOVE R11 R4
0x7C140C00, // 0018 CALL R5 6
0x80000000, // 0019 RET 0
}) })
) )
); );

View File

@ -36,6 +36,7 @@ build_flags = ${esp_defaults.build_flags}
-Wl,--wrap=panicHandler -Wl,--wrap=xt_unhandled_exception -Wl,--wrap=panicHandler -Wl,--wrap=xt_unhandled_exception
-Wl,--wrap=_Z11analogWritehi ; `analogWrite(unsigned char, int)` use the Tasmota version of analogWrite for deeper integration and phase control -Wl,--wrap=_Z11analogWritehi ; `analogWrite(unsigned char, int)` use the Tasmota version of analogWrite for deeper integration and phase control
-Wl,--wrap=ledcReadFreq ; `uint32_t ledcReadFreq(uint8_t chan)` -Wl,--wrap=ledcReadFreq ; `uint32_t ledcReadFreq(uint8_t chan)`
-Wl,--wrap=delay ; void delay(uint32_t ms)
lib_ignore = lib_ignore =
HTTPUpdateServer HTTPUpdateServer
USB USB

View File

@ -1122,6 +1122,8 @@ https://rya.nc/tasmota-fingerprint.html"
#ifdef ESP32 #ifdef ESP32
// #define USE_ESP32_WDT // Enable Watchdog for ESP32, trigger a restart if loop has not responded for 5s, and if `yield();` was not called
#define SET_ESP32_STACK_SIZE (8 * 1024) // Set the stack size for Tasmota. The default value is 8192 for Arduino, some builds might need to increase it #define SET_ESP32_STACK_SIZE (8 * 1024) // Set the stack size for Tasmota. The default value is 8192 for Arduino, some builds might need to increase it
#ifdef SOC_TOUCH_VERSION_1 // ESP32 #ifdef SOC_TOUCH_VERSION_1 // ESP32

View File

@ -411,6 +411,10 @@ void setup(void) {
#endif // CONFIG_IDF_TARGET_ESP32 #endif // CONFIG_IDF_TARGET_ESP32
#endif // ESP32 #endif // ESP32
#ifdef USE_ESP32_WDT
enableLoopWDT(); // enabled WDT Watchdog on Arduino `loop()` - must return before 5s or called `feedLoopWDT();` - included in `yield()`
#endif // USE_ESP32_WDT
RtcPreInit(); RtcPreInit();
SettingsInit(); SettingsInit();

View File

@ -21,6 +21,30 @@ extern "C" {
extern struct rst_info resetInfo; extern struct rst_info resetInfo;
} }
/*********************************************************************************************\
* ESP32 Watchdog
\*********************************************************************************************/
#ifdef ESP32
// Watchdog - yield() resets the watchdog
#ifdef USE_ESP32_WDT
extern "C"
void yield(void) {
vPortYield(); // was originally in `__yield`
feedLoopWDT();
}
// patching delay(uint32_t ms)
extern "C" void __real_delay(uint32_t ms);
extern "C" void __wrap_delay(uint32_t ms) {
__real_delay(ms);
feedLoopWDT();
}
#endif // USE_ESP32_WDT
#endif // ESP32
/*********************************************************************************************\ /*********************************************************************************************\
* Watchdog extension (https://github.com/esp8266/Arduino/issues/1532) * Watchdog extension (https://github.com/esp8266/Arduino/issues/1532)
\*********************************************************************************************/ \*********************************************************************************************/

View File

@ -384,7 +384,7 @@ bool ArtNetStart(void) {
if ((Settings->light_pixels != artnet_conf.rows * artnet_conf.cols + artnet_conf.offs) || (Settings->light_rotation != 0)) { if ((Settings->light_pixels != artnet_conf.rows * artnet_conf.cols + artnet_conf.offs) || (Settings->light_rotation != 0)) {
Settings->light_pixels = artnet_conf.rows * artnet_conf.cols + artnet_conf.offs; Settings->light_pixels = artnet_conf.rows * artnet_conf.cols + artnet_conf.offs;
Settings->light_rotation = 0; Settings->light_rotation = 0;
Ws2812ReinitStrip(); Ws2812InitStrip();
} else { } else {
Ws2812Clear(); Ws2812Clear();
} }

View File

@ -110,6 +110,7 @@ void BrTimeoutStart(void) {
if (0 == berry.timeout) { if (0 == berry.timeout) {
berry.timeout = 1; // rare case when value accidentally computes to zero berry.timeout = 1; // rare case when value accidentally computes to zero
} }
yield();
} }
void BrTimeoutYield(void) { void BrTimeoutYield(void) {

View File

@ -40,6 +40,9 @@
extern "C" { extern "C" {
#include "berry/include/be_gpio_defines.h" #include "berry/include/be_gpio_defines.h"
#if defined(CONFIG_IDF_TARGET_ESP32) || defined(CONFIG_IDF_TARGET_ESP32S2)
#include "soc/dac_channel.h"
#endif // defined(CONFIG_IDF_TARGET_ESP32) || defined(CONFIG_IDF_TARGET_ESP32S2)
// virtual member // virtual member
int gp_member(bvm *vm); int gp_member(bvm *vm);
@ -62,44 +65,11 @@ extern "C" {
// synthetic mode // synthetic mode
if (-1 == mode) { if (-1 == mode) {
// DAC // DAC
#if defined(CONFIG_IDF_TARGET_ESP32) #if defined(CONFIG_IDF_TARGET_ESP32) || defined(CONFIG_IDF_TARGET_ESP32S2)
if (25 == pin || 26 == pin) { if (pin != DAC_CHAN0_GPIO_NUM && pin != DAC_CHAN1_GPIO_NUM) {
#if ESP_IDF_VERSION_MAJOR >= 5 be_raisef(vm, "value_error", "DAC only supported on GPIO%i-%i", DAC_CHAN0_GPIO_NUM, DAC_CHAN1_GPIO_NUM);
dac_oneshot_handle_t channel_handle;
const dac_channel_t channel = (25 == pin) ? DAC_CHAN_0 : DAC_CHAN_1;
dac_oneshot_config_t channel_cfg = {
.chan_id = channel,
};
esp_err_t err = dac_oneshot_new_channel(&channel_cfg, &channel_handle);
#else
dac_channel_t channel = (25 == pin) ? DAC_CHANNEL_1 : DAC_CHANNEL_2;
esp_err_t err = dac_output_enable(channel);
#endif
if (err) {
be_raisef(vm, "value_error", "Error: dac_output_enable(%i) -> %i", channel, err);
}
} else {
be_raise(vm, "value_error", "DAC only supported on GPIO25-26");
}
#elif defined(CONFIG_IDF_TARGET_ESP32S2)
if (17 == pin || 18 == pin) {
#if ESP_IDF_VERSION_MAJOR >= 5
dac_oneshot_handle_t channel_handle;
const dac_channel_t channel = (17 == pin) ? DAC_CHAN_0 : DAC_CHAN_1;
dac_oneshot_config_t channel_cfg = {
.chan_id = channel,
};
esp_err_t err = dac_oneshot_new_channel(&channel_cfg, &channel_handle);
#else
dac_channel_t channel = (17 == pin) ? DAC_CHANNEL_1 : DAC_CHANNEL_2;
esp_err_t err = dac_output_enable(channel);
#endif
if (err) {
be_raisef(vm, "value_error", "Error: dac_output_enable(%i) -> %i", channel, err);
}
} else {
be_raise(vm, "value_error", "DAC only supported on GPIO17-18");
} }
// DEPRECATED - this is not needed anymore, the GPIO is configured when first write occurs
#else #else
be_raise(vm, "value_error", "DAC unsupported in this chip"); be_raise(vm, "value_error", "DAC unsupported in this chip");
#endif #endif
@ -143,59 +113,26 @@ extern "C" {
int gp_dac_voltage(bvm *vm); int gp_dac_voltage(bvm *vm);
int gp_dac_voltage(bvm *vm) { int gp_dac_voltage(bvm *vm) {
#if defined(CONFIG_IDF_TARGET_ESP32) || defined(CONFIG_IDF_TARGET_ESP32S2)
int32_t argc = be_top(vm); // Get the number of arguments int32_t argc = be_top(vm); // Get the number of arguments
if (argc == 2 && be_isint(vm, 1) && be_isint(vm, 2)) { if (argc == 2 && be_isint(vm, 1) && be_isnumber(vm, 2)) {
int32_t pin = be_toint(vm, 1); int32_t pin = be_toint(vm, 1);
int32_t mV = be_toint(vm, 2); int32_t mV = be_toint(vm, 2);
if (pin != DAC_CHAN0_GPIO_NUM && pin != DAC_CHAN1_GPIO_NUM) {
be_raisef(vm, "value_error", "DAC only supported on GPIO%i-%i", DAC_CHAN0_GPIO_NUM, DAC_CHAN1_GPIO_NUM);
}
if (mV < 0) { mV = 0; } if (mV < 0) { mV = 0; }
uint32_t dac_value = changeUIntScale(mV, 0, 3300, 0, 255); // convert from 0..3300 ms to 0..255 uint32_t dac_value = changeUIntScale(mV, 0, 3300, 0, 255); // convert from 0..3300 ms to 0..255
#if defined(CONFIG_IDF_TARGET_ESP32) if (!dacWrite(pin, dac_value)) {
if (25 == pin || 26 == pin) { be_raise(vm, "value_error", "Error: dacWrite failed");
#if ESP_IDF_VERSION_MAJOR >= 5
dac_oneshot_handle_t channel_handle;
const dac_channel_t channel = (25 == pin) ? DAC_CHAN_0 : DAC_CHAN_1;
dac_oneshot_config_t channel_cfg = {
.chan_id = channel,
};
esp_err_t err = dac_oneshot_new_channel(&channel_cfg, &channel_handle);
#else
dac_channel_t channel = (25 == pin) ? DAC_CHANNEL_1 : DAC_CHANNEL_2;
esp_err_t err = dac_output_voltage(channel, dac_value);
// err = dac_output_enable(channel);
#endif
if (err) {
be_raisef(vm, "internal_error", "Error: esp_err_tdac_output_voltage(%i, %i) -> %i", channel, dac_value, err);
}
} else {
be_raise(vm, "value_error", "DAC only supported on GPIO25-26");
} }
#elif defined(CONFIG_IDF_TARGET_ESP32S2) be_pushint(vm, changeUIntScale(dac_value, 0, 255, 0, 3300)); // convert back to mV to indicate the actual value
if (17 == pin || 18 == pin) {
#if ESP_IDF_VERSION_MAJOR >= 5
dac_oneshot_handle_t channel_handle;
const dac_channel_t channel = (17 == pin) ? DAC_CHAN_0 : DAC_CHAN_1;
dac_oneshot_config_t channel_cfg = {
.chan_id = channel,
};
esp_err_t err = dac_oneshot_new_channel(&channel_cfg, &channel_handle);
#else
dac_channel_t channel = (17 == pin) ? DAC_CHANNEL_1 : DAC_CHANNEL_2;
esp_err_t err = dac_output_voltage(channel, dac_value);
// err = dac_output_enable(channel);
#endif
if (err) {
be_raisef(vm, "internal_error", "Error: esp_err_tdac_output_voltage(%i, %i) -> %i", channel, dac_value, err);
}
} else {
be_raise(vm, "value_error", "DAC only supported on GPIO17-18");
}
#else
be_raise(vm, "value_error", "DAC unsupported in this chip");
#endif
be_pushint(vm, changeUIntScale(dac_value, 0, 255, 0, 3300));
be_return(vm); be_return(vm);
} }
be_raise(vm, kTypeError, nullptr); be_raise(vm, kTypeError, nullptr);
#else // defined(CONFIG_IDF_TARGET_ESP32) || defined(CONFIG_IDF_TARGET_ESP32S2)
be_raise(vm, "value_error", "DAC unsupported in this chip");
#endif // defined(CONFIG_IDF_TARGET_ESP32) || defined(CONFIG_IDF_TARGET_ESP32S2)
} }
// Tasmota specific // Tasmota specific

View File

@ -41,6 +41,23 @@ typedef NeoPixelBus<NeoGrbFeature, NeoEsp32RmtN800KbpsMethod> neopixel_ws2812_gr
typedef NeoPixelBus<NeoGrbwFeature, NeoEsp32RmtNSk6812Method> neopixel_sk6812_grbw_t; typedef NeoPixelBus<NeoGrbwFeature, NeoEsp32RmtNSk6812Method> neopixel_sk6812_grbw_t;
#endif #endif
/*********************************************************************************************\
* Functions from Tasmota WS2812 driver
*
\*********************************************************************************************/
extern void *Ws2812GetStrip(void);
extern void Ws2812Begin(void);
extern void Ws2812Show(void);
extern uint32_t Ws2812PixelsSize(void);
extern bool Ws2812CanShow(void);
extern bool Ws2812IsDirty(void);
extern void Ws2812Dirty(void);
extern uint8_t * Ws2812Pixels(void);
extern size_t Ws2812PixelSize(void);
extern size_t Ws2812PixelCount(void);
extern void Ws2812ClearTo(uint8_t r, uint8_t g, uint8_t b, uint8_t w, int32_t from, int32_t to);
extern void Ws2812SetPixelColor(uint32_t idx, uint8_t r, uint8_t g, uint8_t b, uint8_t w);
extern uint32_t Ws2812GetPixelColor(uint32_t idx);
/*********************************************************************************************\ /*********************************************************************************************\
* Native functions mapped to Berry functions * Native functions mapped to Berry functions
@ -82,7 +99,7 @@ extern "C" {
be_getmember(vm, 1, "_t"); be_getmember(vm, 1, "_t");
int32_t type = be_toint(vm, -1); int32_t type = be_toint(vm, -1);
be_pop(vm, 1); be_pop(vm, 1);
if (type <= 0 || type >= neopixel_type_end) { if (type < 0 || type >= neopixel_type_end) {
be_raise(vm, "internal_error", "invalid leds type"); be_raise(vm, "internal_error", "invalid leds type");
} }
return type; return type;
@ -95,30 +112,46 @@ extern "C" {
int32_t cmd = be_toint(vm, 2); int32_t cmd = be_toint(vm, 2);
if (0 == cmd) { // 00 : ctor (leds:int, gpio:int) -> void if (0 == cmd) { // 00 : ctor (leds:int, gpio:int) -> void
if (!(argc >= 6 && be_isint(vm, 3) && be_isint(vm, 4) && be_isint(vm, 5) && be_isint(vm, 6))) { if ((argc != 2) && !(argc >= 6 && be_isint(vm, 3) && be_isint(vm, 4) && be_isint(vm, 5) && be_isint(vm, 6))) {
be_raise(vm, "value_error", "bad arguments for neopixelbus:ctor"); be_raise(vm, "value_error", "bad arguments for neopixelbus:ctor");
} }
int32_t leds = be_toint(vm, 3); int32_t leds = -1;
int32_t gpio = be_toint(vm, 4); int32_t gpio = -1;
int32_t neopixel_type = be_toint(vm, 5); int32_t neopixel_type = 0;
int32_t rmt = be_toint(vm, 6); int32_t rmt = 0;
if (neopixel_type < 1) { neopixel_type = 1; } void * strip = nullptr;
if (neopixel_type >= neopixel_type_end) { neopixel_type = neopixel_type_end - 1; } if (argc > 2) {
if (rmt < 0) { rmt = 0; } leds = be_toint(vm, 3);
if (rmt >= MAX_RMT) { rmt = MAX_RMT - 1; } gpio = be_toint(vm, 4);
neopixel_type = be_toint(vm, 5);
rmt = be_toint(vm, 6);
}
if (-1 == gpio) {
// if GPIO is '-1'
neopixel_type = 0;
Ws2812InitStrip(); // ensure the NeoPixelbus object is initialized, because Berry code runs before the driver is initialized
strip = Ws2812GetStrip();
} else {
// allocate a new RMT
if (neopixel_type < 1) { neopixel_type = 1; }
if (neopixel_type >= neopixel_type_end) { neopixel_type = neopixel_type_end - 1; }
if (rmt < 0) { rmt = 0; }
if (rmt >= MAX_RMT) { rmt = MAX_RMT - 1; }
switch (neopixel_type) {
case ws2812_grb: strip = new neopixel_ws2812_grb_t(leds, gpio, (NeoBusChannel) rmt);
break;
case sk6812_grbw: strip = new neopixel_sk6812_grbw_t(leds, gpio, (NeoBusChannel) rmt);
break;
}
}
// store type in attribute `_t` // store type in attribute `_t`
be_pushint(vm, neopixel_type); be_pushint(vm, neopixel_type);
be_setmember(vm, 1, "_t"); be_setmember(vm, 1, "_t");
be_pop(vm, 1); be_pop(vm, 1);
void * strip = nullptr;
switch (neopixel_type) {
case ws2812_grb: strip = new neopixel_ws2812_grb_t(leds, gpio, (NeoBusChannel) rmt);
break;
case sk6812_grbw: strip = new neopixel_sk6812_grbw_t(leds, gpio, (NeoBusChannel) rmt);
break;
}
be_pushcomptr(vm, (void*) strip); be_pushcomptr(vm, (void*) strip);
be_setmember(vm, 1, "_p"); be_setmember(vm, 1, "_p");
be_pop(vm, 1); be_pop(vm, 1);
@ -130,11 +163,14 @@ extern "C" {
// initialize all possible variants // initialize all possible variants
neopixel_ws2812_grb_t * s_ws2812_grb = (leds_type == ws2812_grb) ? (neopixel_ws2812_grb_t*) s : nullptr; neopixel_ws2812_grb_t * s_ws2812_grb = (leds_type == ws2812_grb) ? (neopixel_ws2812_grb_t*) s : nullptr;
neopixel_sk6812_grbw_t * s_sk6812_grbw = (leds_type == sk6812_grbw) ? (neopixel_sk6812_grbw_t*) s : nullptr; neopixel_sk6812_grbw_t * s_sk6812_grbw = (leds_type == sk6812_grbw) ? (neopixel_sk6812_grbw_t*) s : nullptr;
// detect native driver
bool native = (leds_type == 0);
be_pushnil(vm); // push a default `nil` return value be_pushnil(vm); // push a default `nil` return value
switch (cmd) { switch (cmd) {
case 1: // # 01 : begin void -> void case 1: // # 01 : begin void -> void
if (native) Ws2812Begin();
if (s_ws2812_grb) s_ws2812_grb->Begin(); if (s_ws2812_grb) s_ws2812_grb->Begin();
if (s_sk6812_grbw) s_sk6812_grbw->Begin(); if (s_sk6812_grbw) s_sk6812_grbw->Begin();
break; break;
@ -159,6 +195,7 @@ extern "C" {
} }
} }
uint32_t pixels_size; // number of bytes to push uint32_t pixels_size; // number of bytes to push
if (native) { Ws2812Show(); pixels_size = Ws2812PixelsSize(); }
if (s_ws2812_grb) { s_ws2812_grb->Show(); pixels_size = s_ws2812_grb->PixelsSize(); } if (s_ws2812_grb) { s_ws2812_grb->Show(); pixels_size = s_ws2812_grb->PixelsSize(); }
if (s_sk6812_grbw) { s_sk6812_grbw->Show(); pixels_size = s_sk6812_grbw->PixelsSize(); } if (s_sk6812_grbw) { s_sk6812_grbw->Show(); pixels_size = s_sk6812_grbw->PixelsSize(); }
@ -168,20 +205,24 @@ extern "C" {
} }
break; break;
case 3: // # 03 : CanShow void -> bool case 3: // # 03 : CanShow void -> bool
if (native) be_pushbool(vm, Ws2812CanShow());
if (s_ws2812_grb) be_pushbool(vm, s_ws2812_grb->CanShow()); if (s_ws2812_grb) be_pushbool(vm, s_ws2812_grb->CanShow());
if (s_sk6812_grbw) be_pushbool(vm, s_sk6812_grbw->CanShow()); if (s_sk6812_grbw) be_pushbool(vm, s_sk6812_grbw->CanShow());
break; break;
case 4: // # 04 : IsDirty void -> bool case 4: // # 04 : IsDirty void -> bool
if (native) be_pushbool(vm, Ws2812IsDirty());
if (s_ws2812_grb) be_pushbool(vm, s_ws2812_grb->IsDirty()); if (s_ws2812_grb) be_pushbool(vm, s_ws2812_grb->IsDirty());
if (s_sk6812_grbw) be_pushbool(vm, s_sk6812_grbw->IsDirty()); if (s_sk6812_grbw) be_pushbool(vm, s_sk6812_grbw->IsDirty());
break; break;
case 5: // # 05 : Dirty void -> void case 5: // # 05 : Dirty void -> void
if (native) Ws2812Dirty();
if (s_ws2812_grb) s_ws2812_grb->Dirty(); if (s_ws2812_grb) s_ws2812_grb->Dirty();
if (s_sk6812_grbw) s_sk6812_grbw->Dirty(); if (s_sk6812_grbw) s_sk6812_grbw->Dirty();
break; break;
case 6: // # 06 : Pixels void -> bytes() (mapped to the buffer) case 6: // # 06 : Pixels void -> bytes() (mapped to the buffer)
{ {
uint8_t * pixels; uint8_t * pixels;
if (native) pixels = Ws2812Pixels();
if (s_ws2812_grb) pixels = s_ws2812_grb->Pixels(); if (s_ws2812_grb) pixels = s_ws2812_grb->Pixels();
if (s_sk6812_grbw) pixels = s_sk6812_grbw->Pixels(); if (s_sk6812_grbw) pixels = s_sk6812_grbw->Pixels();
@ -189,10 +230,12 @@ extern "C" {
} }
break; break;
case 7: // # 07 : PixelSize void -> int case 7: // # 07 : PixelSize void -> int
if (native) be_pushint(vm, Ws2812PixelSize());
if (s_ws2812_grb) be_pushint(vm, s_ws2812_grb->PixelSize()); if (s_ws2812_grb) be_pushint(vm, s_ws2812_grb->PixelSize());
if (s_sk6812_grbw) be_pushint(vm, s_sk6812_grbw->PixelSize()); if (s_sk6812_grbw) be_pushint(vm, s_sk6812_grbw->PixelSize());
break; break;
case 8: // # 08 : PixelCount void -> int case 8: // # 08 : PixelCount void -> int
if (native) be_pushint(vm, Ws2812PixelCount());
if (s_ws2812_grb) be_pushint(vm, s_ws2812_grb->PixelCount()); if (s_ws2812_grb) be_pushint(vm, s_ws2812_grb->PixelCount());
if (s_sk6812_grbw) be_pushint(vm, s_sk6812_grbw->PixelCount()); if (s_sk6812_grbw) be_pushint(vm, s_sk6812_grbw->PixelCount());
break; break;
@ -204,11 +247,16 @@ extern "C" {
uint8_t g = (rgbw >> 8) & 0xFF; uint8_t g = (rgbw >> 8) & 0xFF;
uint8_t b = (rgbw ) & 0xFF; uint8_t b = (rgbw ) & 0xFF;
if (argc >= 5 && be_isint(vm, 4) && be_isint(vm, 5)) { if (argc >= 5 && be_isint(vm, 4) && be_isint(vm, 5)) {
uint32_t from = be_toint(vm, 4); int32_t from = be_toint(vm, 4);
uint32_t len = be_toint(vm, 5); int32_t len = be_toint(vm, 5);
if (from < 0) { from = 0; }
if (len < 0) { len = 0; }
if (native) Ws2812ClearTo(r, g, b, w, from, from + len - 1);
if (s_ws2812_grb) s_ws2812_grb->ClearTo(RgbColor(r, g, b), from, from + len - 1); if (s_ws2812_grb) s_ws2812_grb->ClearTo(RgbColor(r, g, b), from, from + len - 1);
if (s_sk6812_grbw) s_sk6812_grbw->ClearTo(RgbwColor(r, g, b, w), from, from + len - 1); if (s_sk6812_grbw) s_sk6812_grbw->ClearTo(RgbwColor(r, g, b, w), from, from + len - 1);
} else { } else {
if (native) Ws2812ClearTo(r, g, b, w, -1, -1);
if (s_ws2812_grb) s_ws2812_grb->ClearTo(RgbColor(r, g, b)); if (s_ws2812_grb) s_ws2812_grb->ClearTo(RgbColor(r, g, b));
if (s_sk6812_grbw) s_sk6812_grbw->ClearTo(RgbwColor(r, g, b, w)); if (s_sk6812_grbw) s_sk6812_grbw->ClearTo(RgbwColor(r, g, b, w));
} }
@ -222,6 +270,7 @@ extern "C" {
uint8_t r = (rgbw >> 16) & 0xFF; uint8_t r = (rgbw >> 16) & 0xFF;
uint8_t g = (rgbw >> 8) & 0xFF; uint8_t g = (rgbw >> 8) & 0xFF;
uint8_t b = (rgbw ) & 0xFF; uint8_t b = (rgbw ) & 0xFF;
if (native) Ws2812SetPixelColor(idx, r, g, b, w);
if (s_ws2812_grb) s_ws2812_grb->SetPixelColor(idx, RgbColor(r, g, b)); if (s_ws2812_grb) s_ws2812_grb->SetPixelColor(idx, RgbColor(r, g, b));
if (s_sk6812_grbw) s_sk6812_grbw->SetPixelColor(idx, RgbwColor(r, g, b, w)); if (s_sk6812_grbw) s_sk6812_grbw->SetPixelColor(idx, RgbwColor(r, g, b, w));
} }
@ -229,15 +278,17 @@ extern "C" {
case 11: // # 11 : GetPixelColor (idx:int) -> color:?? case 11: // # 11 : GetPixelColor (idx:int) -> color:??
{ {
int32_t idx = be_toint(vm, 3); int32_t idx = be_toint(vm, 3);
RgbColor rgb;
if (native) {
be_pushint(vm, Ws2812GetPixelColor(idx));
}
if (s_ws2812_grb) { if (s_ws2812_grb) {
RgbColor rgb = s_ws2812_grb->GetPixelColor(idx); RgbColor rgb = s_ws2812_grb->GetPixelColor(idx);
be_pushint(vm, (rgb.R << 16) | (rgb.G << 8) | rgb.B); be_pushint(vm, (rgb.R << 16) | (rgb.G << 8) | rgb.B);
} }
if (s_sk6812_grbw) { if (s_sk6812_grbw) {
RgbwColor rgbw = s_sk6812_grbw->GetPixelColor(idx); RgbwColor rgbw = s_sk6812_grbw->GetPixelColor(idx);
be_pushint(vm, (rgbw.W << 24) | (rgb.R << 16) | (rgb.G << 8) | rgb.B); be_pushint(vm, (rgbw.W << 24) | (rgbw.R << 16) | (rgbw.G << 8) | rgbw.B);
} }
} }
break; break;

View File

@ -404,7 +404,8 @@ extern "C" {
// ESP object // ESP object
int32_t l_yield(bvm *vm); int32_t l_yield(bvm *vm);
int32_t l_yield(bvm *vm) { int32_t l_yield(bvm *vm) {
return be_call_c_func(vm, (void*) &BrTimeoutYield, NULL, "-"); BrTimeoutYield();
be_return_nil(vm);
} }
// Berry: tasmota.scale_uint(int * 5) -> int // Berry: tasmota.scale_uint(int * 5) -> int

View File

@ -681,16 +681,10 @@ void Ws2812ShowScheme(void)
} }
} }
bool Ws2812ReinitStrip(void) bool Ws2812InitStrip(void)
{ {
if (strip != nullptr) { if (strip != nullptr) {
Ws2812Clear(); return true;
if (!strip->CanShow()) {
// we're doing DMA, so wait for a decent amount of time
delay(10);
}
delete strip;
strip = nullptr;
} }
#if (USE_WS2812_HARDWARE == NEO_HW_P9813) #if (USE_WS2812_HARDWARE == NEO_HW_P9813)
@ -711,7 +705,7 @@ bool Ws2812ReinitStrip(void)
void Ws2812ModuleSelected(void) void Ws2812ModuleSelected(void)
{ {
if (Ws2812ReinitStrip()) { if (Ws2812InitStrip()) {
Ws2812.scheme_offset = Light.max_scheme +1; Ws2812.scheme_offset = Light.max_scheme +1;
Light.max_scheme += WS2812_SCHEMES; Light.max_scheme += WS2812_SCHEMES;
@ -728,6 +722,117 @@ void Ws2812ModuleSelected(void)
} }
} }
#ifdef ESP32
#ifdef USE_BERRY
/********************************************************************************************/
// Callbacks for Berry driver
//
// Since we dont' want to export all the template stuff, we need to encapsulate the calls
// in plain functions
//
void *Ws2812GetStrip(void) {
return strip;
}
void Ws2812Begin(void) {
if (strip) { strip->Begin(); }
}
void Ws2812Show(void) {
if (strip) { strip->Show(); }
}
uint32_t Ws2812PixelsSize(void) {
if (strip) { return strip->PixelCount(); }
return 0;
}
bool Ws2812CanShow(void) {
if (strip) { return strip->CanShow(); }
return false;
}
bool Ws2812IsDirty(void) {
if (strip) { return strip->IsDirty(); }
return false;
}
void Ws2812Dirty(void) {
if (strip) { strip->Dirty(); }
}
uint8_t * Ws2812Pixels(void) {
if (strip) { return strip->Pixels(); }
return nullptr;
}
size_t Ws2812PixelSize(void) {
if (strip) { return strip->PixelSize(); }
return 0;
}
size_t Ws2812PixelCount(void) {
if (strip) { return strip->PixelCount(); }
return 0;
}
void Ws2812ClearTo(uint8_t r, uint8_t g, uint8_t b, uint8_t w, int32_t from, int32_t to) {
#if (USE_WS2812_CTYPE > NEO_3LED)
RgbwColor lcolor;
lcolor.W = w;
#else
RgbColor lcolor;
#endif
lcolor.R = r;
lcolor.G = g;
lcolor.B = b;
if (strip) {
if (from < 0) {
strip->ClearTo(lcolor);
} else {
strip->ClearTo(lcolor, from, to);
}
}
}
void Ws2812SetPixelColor(uint32_t idx, uint8_t r, uint8_t g, uint8_t b, uint8_t w)
{
#if (USE_WS2812_CTYPE > NEO_3LED)
RgbwColor lcolor;
lcolor.W = w;
#else
RgbColor lcolor;
#endif
lcolor.R = r;
lcolor.G = g;
lcolor.B = b;
if (strip) {
strip->SetPixelColor(idx, lcolor);
}
}
uint32_t Ws2812GetPixelColor(uint32_t idx) {
#if (USE_WS2812_CTYPE > NEO_3LED)
RgbwColor lcolor;
#else
RgbColor lcolor;
#endif
if (strip) {
lcolor = strip->GetPixelColor(idx);
#if (USE_WS2812_CTYPE > NEO_3LED)
return (lcolor.W << 24) | (lcolor.R << 16) | (lcolor.G << 8) | lcolor.B;
#else
return (lcolor.R << 16) | (lcolor.G << 8) | lcolor.B;
#endif
}
return 0;
}
#endif // ESP32
#endif // USE_BERRY
/********************************************************************************************/ /********************************************************************************************/
void CmndLed(void) void CmndLed(void)
@ -756,10 +861,16 @@ void CmndLed(void)
void CmndPixels(void) void CmndPixels(void)
{ {
if ((XdrvMailbox.payload > 0) && (XdrvMailbox.payload <= WS2812_MAX_LEDS)) { if ((XdrvMailbox.payload > 0) && (XdrvMailbox.payload <= WS2812_MAX_LEDS)) {
/*
Settings->light_pixels = XdrvMailbox.payload; Settings->light_pixels = XdrvMailbox.payload;
Settings->light_rotation = 0; Settings->light_rotation = 0;
Ws2812ReinitStrip(); Ws2812ReinitStrip(); -- does not work with latest NeoPixelBus driver
Light.update = true; Light.update = true;
*/
Ws2812Clear(); // Clear all known pixels
Settings->light_pixels = XdrvMailbox.payload;
Settings->light_rotation = 0;
TasmotaGlobal.restart_flag = 2; // reboot instead
} }
ResponseCmndNumber(Settings->light_pixels); ResponseCmndNumber(Settings->light_pixels);
} }
@ -768,7 +879,7 @@ void CmndStepPixels(void)
{ {
if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 255)) { if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 255)) {
Settings->light_step_pixels = (XdrvMailbox.payload > WS2812_MAX_LEDS) ? WS2812_MAX_LEDS : XdrvMailbox.payload; Settings->light_step_pixels = (XdrvMailbox.payload > WS2812_MAX_LEDS) ? WS2812_MAX_LEDS : XdrvMailbox.payload;
Ws2812ReinitStrip(); // Ws2812ReinitStrip(); -- not sure it's actually needed
Light.update = true; Light.update = true;
} }
ResponseCmndNumber(Settings->light_step_pixels); ResponseCmndNumber(Settings->light_step_pixels);