diff --git a/CHANGELOG.md b/CHANGELOG.md index 99aee1988..40e4bbfab 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -37,6 +37,7 @@ 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) - GPIOViewer from v1.5.0 to v1.5.2 - ESP32 Core3 platform update from 2024.05.10 to 2024.05.11 (#21381) +- Berry `Leds` uses native WS2812 driver by default ### Fixed - HASPmota `align` attribute and expand PNG cache (#21228) diff --git a/lib/libesp32/berry_tasmota/src/embedded/leds.be b/lib/libesp32/berry_tasmota/src/embedded/leds.be index 1d9e505ac..9442f8787 100644 --- a/lib/libesp32/berry_tasmota/src/embedded/leds.be +++ b/lib/libesp32/berry_tasmota/src/embedded/leds.be @@ -33,23 +33,27 @@ class Leds : Leds_ntv # 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 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.leds = int(leds) - self.bri = 127 # 50% brightness by default + if (gpio_phy == nil) || (gpio_phy == gpio.pin(gpio.WS2812, 0)) + # 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 - if gpio_phy == nil - raise "valuer_error", "no GPIO specified for neopixelbus" + # initialize the structure + self.ctor(self.leds, gpio_phy, typ, rmt) 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 # call begin self.begin() - end # assign RMT @@ -106,13 +110,17 @@ class Leds : Leds_ntv end def ctor(leds, gpio_phy, typ, rmt) - if typ == nil - typ = self.WS2812_GRB + if gpio_phy == nil + 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 - if rmt == nil - rmt = self.assign_rmt(gpio_phy) - end - self.call_native(0, leds, gpio_phy, typ, rmt) end def begin() self.call_native(1) diff --git a/lib/libesp32/berry_tasmota/src/solidify/solidified_leds.h b/lib/libesp32/berry_tasmota/src/solidify/solidified_leds.h index 3e0ef7846..4ea0f61f7 100644 --- a/lib/libesp32/berry_tasmota/src/solidify/solidified_leds.h +++ b/lib/libesp32/berry_tasmota/src/solidify/solidified_leds.h @@ -649,7 +649,7 @@ be_local_closure(Leds_clear, /* name */ ********************************************************************/ be_local_closure(Leds_init, /* name */ be_nested_proto( - 11, /* nstack */ + 12, /* nstack */ 5, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -657,47 +657,69 @@ be_local_closure(Leds_init, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[10]) { /* constants */ - /* K0 */ be_nested_str(gamma), - /* K1 */ be_nested_str(leds), - /* K2 */ be_nested_str(bri), - /* K3 */ be_nested_str(valuer_error), - /* K4 */ be_nested_str(no_X20GPIO_X20specified_X20for_X20neopixelbus), + ( &(const bvalue[15]) { /* constants */ + /* K0 */ be_nested_str(gpio), + /* K1 */ be_nested_str(gamma), + /* K2 */ be_nested_str(pin), + /* K3 */ be_nested_str(WS2812), + /* K4 */ be_const_int(0), /* K5 */ be_nested_str(ctor), - /* K6 */ be_nested_str(_p), - /* K7 */ be_nested_str(internal_error), - /* K8 */ be_nested_str(couldn_X27t_X20not_X20initialize_X20noepixelbus), - /* K9 */ be_nested_str(begin), + /* K6 */ be_nested_str(leds), + /* K7 */ be_nested_str(pixel_count), + /* K8 */ be_nested_str(light), + /* 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_solidified, - ( &(const binstruction[26]) { /* code */ - 0x50140200, // 0000 LDBOOL R5 1 0 - 0x90020005, // 0001 SETMBR R0 K0 R5 - 0x60140009, // 0002 GETGBL R5 G9 - 0x5C180200, // 0003 MOVE R6 R1 - 0x7C140200, // 0004 CALL R5 1 - 0x90020205, // 0005 SETMBR R0 K1 R5 - 0x5416007E, // 0006 LDINT R5 127 - 0x90020405, // 0007 SETMBR R0 K2 R5 - 0x4C140000, // 0008 LDNIL R5 - 0x1C140405, // 0009 EQ R5 R2 R5 - 0x78160000, // 000A JMPF R5 #000C - 0xB0060704, // 000B RAISE 1 K3 K4 - 0x8C140105, // 000C GETMET R5 R0 K5 - 0x881C0101, // 000D GETMBR R7 R0 K1 - 0x5C200400, // 000E MOVE R8 R2 - 0x5C240600, // 000F MOVE R9 R3 - 0x5C280800, // 0010 MOVE R10 R4 - 0x7C140A00, // 0011 CALL R5 5 - 0x88140106, // 0012 GETMBR R5 R0 K6 - 0x4C180000, // 0013 LDNIL R6 - 0x1C140A06, // 0014 EQ R5 R5 R6 - 0x78160000, // 0015 JMPF R5 #0017 - 0xB0060F08, // 0016 RAISE 1 K7 K8 - 0x8C140109, // 0017 GETMET R5 R0 K9 - 0x7C140200, // 0018 CALL R5 1 - 0x80000000, // 0019 RET 0 + ( &(const binstruction[43]) { /* code */ + 0xA4160000, // 0000 IMPORT R5 K0 + 0x50180200, // 0001 LDBOOL R6 1 0 + 0x90020206, // 0002 SETMBR R0 K1 R6 + 0x4C180000, // 0003 LDNIL R6 + 0x1C180406, // 0004 EQ R6 R2 R6 + 0x741A0005, // 0005 JMPT R6 #000C + 0x8C180B02, // 0006 GETMET R6 R5 K2 + 0x88200B03, // 0007 GETMBR R8 R5 K3 + 0x58240004, // 0008 LDCONST R9 K4 + 0x7C180600, // 0009 CALL R6 3 + 0x1C180406, // 000A EQ R6 R2 R6 + 0x781A000A, // 000B JMPF R6 #0017 + 0x8C180105, // 000C GETMET R6 R0 K5 + 0x7C180200, // 000D CALL R6 1 + 0x8C180107, // 000E GETMET R6 R0 K7 + 0x7C180200, // 000F CALL R6 1 + 0x90020C06, // 0010 SETMBR R0 K6 R6 + 0xA41A1000, // 0011 IMPORT R6 K8 + 0x8C1C0D0A, // 0012 GETMET R7 R6 K10 + 0x7C1C0200, // 0013 CALL R7 1 + 0x941C0F09, // 0014 GETIDX R7 R7 K9 + 0x90021207, // 0015 SETMBR R0 K9 R7 + 0x7002000B, // 0016 JMP #0023 + 0x60180009, // 0017 GETGBL R6 G9 + 0x5C1C0200, // 0018 MOVE R7 R1 + 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 */ 1, /* has constants */ ( &(const bvalue[ 4]) { /* constants */ - /* K0 */ be_nested_str(WS2812_GRB), - /* K1 */ be_nested_str(assign_rmt), - /* K2 */ be_nested_str(call_native), - /* K3 */ be_const_int(0), + /* K0 */ be_nested_str(call_native), + /* K1 */ be_const_int(0), + /* K2 */ be_nested_str(WS2812_GRB), + /* K3 */ be_nested_str(assign_rmt), }), &be_const_str_ctor, &be_const_str_solidified, - ( &(const binstruction[19]) { /* code */ + ( &(const binstruction[26]) { /* code */ 0x4C140000, // 0000 LDNIL R5 - 0x1C140605, // 0001 EQ R5 R3 R5 - 0x78160000, // 0002 JMPF R5 #0004 - 0x880C0100, // 0003 GETMBR R3 R0 K0 - 0x4C140000, // 0004 LDNIL R5 - 0x1C140805, // 0005 EQ R5 R4 R5 - 0x78160003, // 0006 JMPF R5 #000B - 0x8C140101, // 0007 GETMET R5 R0 K1 - 0x5C1C0400, // 0008 MOVE R7 R2 - 0x7C140400, // 0009 CALL R5 2 - 0x5C100A00, // 000A MOVE R4 R5 - 0x8C140102, // 000B GETMET R5 R0 K2 - 0x581C0003, // 000C LDCONST R7 K3 - 0x5C200200, // 000D MOVE R8 R1 - 0x5C240400, // 000E MOVE R9 R2 - 0x5C280600, // 000F MOVE R10 R3 - 0x5C2C0800, // 0010 MOVE R11 R4 - 0x7C140C00, // 0011 CALL R5 6 - 0x80000000, // 0012 RET 0 + 0x1C140405, // 0001 EQ R5 R2 R5 + 0x78160003, // 0002 JMPF R5 #0007 + 0x8C140100, // 0003 GETMET R5 R0 K0 + 0x581C0001, // 0004 LDCONST R7 K1 + 0x7C140400, // 0005 CALL R5 2 + 0x70020011, // 0006 JMP #0019 + 0x4C140000, // 0007 LDNIL R5 + 0x1C140605, // 0008 EQ R5 R3 R5 + 0x78160000, // 0009 JMPF R5 #000B + 0x880C0102, // 000A GETMBR R3 R0 K2 + 0x4C140000, // 000B LDNIL R5 + 0x1C140805, // 000C EQ R5 R4 R5 + 0x78160003, // 000D JMPF R5 #0012 + 0x8C140103, // 000E GETMET R5 R0 K3 + 0x5C1C0400, // 000F MOVE R7 R2 + 0x7C140400, // 0010 CALL R5 2 + 0x5C100A00, // 0011 MOVE R4 R5 + 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 }) ) ); diff --git a/tasmota/tasmota_xdrv_driver/xdrv_04_light_artnet.ino b/tasmota/tasmota_xdrv_driver/xdrv_04_light_artnet.ino index 49ebf6ddf..d0d3b61ff 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_04_light_artnet.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_04_light_artnet.ino @@ -384,7 +384,7 @@ bool ArtNetStart(void) { 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_rotation = 0; - Ws2812ReinitStrip(); + Ws2812InitStrip(); } else { Ws2812Clear(); } diff --git a/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_leds.ino b/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_leds.ino index 08f287567..0984cb14b 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_leds.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_leds.ino @@ -41,6 +41,23 @@ typedef NeoPixelBus neopixel_ws2812_gr typedef NeoPixelBus neopixel_sk6812_grbw_t; #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 @@ -82,7 +99,7 @@ extern "C" { be_getmember(vm, 1, "_t"); int32_t type = be_toint(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"); } return type; @@ -95,30 +112,46 @@ extern "C" { int32_t cmd = be_toint(vm, 2); 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"); } - int32_t leds = be_toint(vm, 3); - int32_t gpio = be_toint(vm, 4); - int32_t neopixel_type = be_toint(vm, 5); - int32_t rmt = be_toint(vm, 6); - 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; } + int32_t leds = -1; + int32_t gpio = -1; + int32_t neopixel_type = 0; + int32_t rmt = 0; + void * strip = nullptr; + if (argc > 2) { + leds = be_toint(vm, 3); + 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` be_pushint(vm, neopixel_type); be_setmember(vm, 1, "_t"); 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_setmember(vm, 1, "_p"); be_pop(vm, 1); @@ -130,11 +163,14 @@ extern "C" { // initialize all possible variants 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; + // detect native driver + bool native = (leds_type == 0); be_pushnil(vm); // push a default `nil` return value switch (cmd) { case 1: // # 01 : begin void -> void + if (native) Ws2812Begin(); if (s_ws2812_grb) s_ws2812_grb->Begin(); if (s_sk6812_grbw) s_sk6812_grbw->Begin(); break; @@ -159,6 +195,7 @@ extern "C" { } } 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_sk6812_grbw) { s_sk6812_grbw->Show(); pixels_size = s_sk6812_grbw->PixelsSize(); } @@ -168,20 +205,24 @@ extern "C" { } break; 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_sk6812_grbw) be_pushbool(vm, s_sk6812_grbw->CanShow()); break; 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_sk6812_grbw) be_pushbool(vm, s_sk6812_grbw->IsDirty()); break; case 5: // # 05 : Dirty void -> void + if (native) Ws2812Dirty(); if (s_ws2812_grb) s_ws2812_grb->Dirty(); if (s_sk6812_grbw) s_sk6812_grbw->Dirty(); break; case 6: // # 06 : Pixels void -> bytes() (mapped to the buffer) { uint8_t * pixels; + if (native) pixels = Ws2812Pixels(); if (s_ws2812_grb) pixels = s_ws2812_grb->Pixels(); if (s_sk6812_grbw) pixels = s_sk6812_grbw->Pixels(); @@ -189,10 +230,12 @@ extern "C" { } break; 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_sk6812_grbw) be_pushint(vm, s_sk6812_grbw->PixelSize()); break; 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_sk6812_grbw) be_pushint(vm, s_sk6812_grbw->PixelCount()); break; @@ -204,11 +247,16 @@ extern "C" { uint8_t g = (rgbw >> 8) & 0xFF; uint8_t b = (rgbw ) & 0xFF; if (argc >= 5 && be_isint(vm, 4) && be_isint(vm, 5)) { - uint32_t from = be_toint(vm, 4); - uint32_t len = be_toint(vm, 5); + int32_t from = be_toint(vm, 4); + 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_sk6812_grbw) s_sk6812_grbw->ClearTo(RgbwColor(r, g, b, w), from, from + len - 1); } else { + if (native) Ws2812ClearTo(r, g, b, w, -1, -1); 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)); } @@ -222,6 +270,7 @@ extern "C" { uint8_t r = (rgbw >> 16) & 0xFF; uint8_t g = (rgbw >> 8) & 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_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:?? { int32_t idx = be_toint(vm, 3); - RgbColor rgb; + if (native) { + be_pushint(vm, Ws2812GetPixelColor(idx)); + } if (s_ws2812_grb) { RgbColor rgb = s_ws2812_grb->GetPixelColor(idx); be_pushint(vm, (rgb.R << 16) | (rgb.G << 8) | rgb.B); } if (s_sk6812_grbw) { 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; diff --git a/tasmota/tasmota_xlgt_light/xlgt_01_ws2812.ino b/tasmota/tasmota_xlgt_light/xlgt_01_ws2812.ino index e87d393f7..dd4f425da 100644 --- a/tasmota/tasmota_xlgt_light/xlgt_01_ws2812.ino +++ b/tasmota/tasmota_xlgt_light/xlgt_01_ws2812.ino @@ -681,16 +681,10 @@ void Ws2812ShowScheme(void) } } -bool Ws2812ReinitStrip(void) +bool Ws2812InitStrip(void) { if (strip != nullptr) { - Ws2812Clear(); - if (!strip->CanShow()) { - // we're doing DMA, so wait for a decent amount of time - delay(10); - } - delete strip; - strip = nullptr; + return true; } #if (USE_WS2812_HARDWARE == NEO_HW_P9813) @@ -711,7 +705,7 @@ bool Ws2812ReinitStrip(void) void Ws2812ModuleSelected(void) { - if (Ws2812ReinitStrip()) { + if (Ws2812InitStrip()) { Ws2812.scheme_offset = Light.max_scheme +1; Light.max_scheme += WS2812_SCHEMES; @@ -728,6 +722,112 @@ void Ws2812ModuleSelected(void) } } +/********************************************************************************************/ +// 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; +} + /********************************************************************************************/ void CmndLed(void) @@ -758,7 +858,8 @@ void CmndPixels(void) if ((XdrvMailbox.payload > 0) && (XdrvMailbox.payload <= WS2812_MAX_LEDS)) { Settings->light_pixels = XdrvMailbox.payload; Settings->light_rotation = 0; - Ws2812ReinitStrip(); + // Ws2812ReinitStrip(); -- does not work + TasmotaGlobal.restart_flag = 2; // reboot instead Light.update = true; } ResponseCmndNumber(Settings->light_pixels); @@ -768,7 +869,7 @@ void CmndStepPixels(void) { if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 255)) { 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; } ResponseCmndNumber(Settings->light_step_pixels);