Berry `Leds` uses native WS2812 driver by default (#21406)

This commit is contained in:
s-hadinger 2024-05-13 22:21:58 +02:00 committed by GitHub
parent 2865630309
commit 4cda2d7dc2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 299 additions and 109 deletions

View File

@ -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)

View File

@ -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
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"
end
# initialize the structure
self.ctor(self.leds, gpio_phy, typ, rmt)
end
if self._p == nil raise "internal_error", "couldn't not initialize noepixelbus" end
# call begin
self.begin()
end
# assign RMT
@ -106,6 +110,9 @@ class Leds : Leds_ntv
end
def ctor(leds, gpio_phy, typ, rmt)
if gpio_phy == nil
self.call_native(0) # native driver
else
if typ == nil
typ = self.WS2812_GRB
end
@ -114,6 +121,7 @@ class Leds : Leds_ntv
end
self.call_native(0, leds, gpio_phy, typ, rmt)
end
end
def begin()
self.call_native(1)
end

View File

@ -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
})
)
);

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)) {
Settings->light_pixels = artnet_conf.rows * artnet_conf.cols + artnet_conf.offs;
Settings->light_rotation = 0;
Ws2812ReinitStrip();
Ws2812InitStrip();
} else {
Ws2812Clear();
}

View File

@ -41,6 +41,23 @@ typedef NeoPixelBus<NeoGrbFeature, NeoEsp32RmtN800KbpsMethod> neopixel_ws2812_gr
typedef NeoPixelBus<NeoGrbwFeature, NeoEsp32RmtNSk6812Method> 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);
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; }
// 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;
}
}
// store type in attribute `_t`
be_pushint(vm, neopixel_type);
be_setmember(vm, 1, "_t");
be_pop(vm, 1);
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;

View File

@ -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);