Skip to content

Commit 4676db2

Browse files
authored
WS2812 and Berry animation support for reverse-order LED strip (#24138)
1 parent 9340e21 commit 4676db2

File tree

5 files changed

+32
-17
lines changed

5 files changed

+32
-17
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ All notable changes to this project will be documented in this file.
55

66
## [15.1.0.2]
77
### Added
8+
- WS2812 and Berry animation support for reverse-order LED strip
89

910
### Breaking Changed
1011

lib/lib_basic/TasmotaLED/TASMOTALED_DOCUMENTATION.md

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -57,10 +57,10 @@ TasmotaLED is designed with the following principles:
5757
5858
┌─────────────────────────────────────────────────────────────┐
5959
│ TasmotaLED Class │
60-
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
61-
│ │ _buf_work │ │ _buf_show │ │ Pixel Format │ │
62-
│ │ (editable) │─▶│ (internal) │ │ Conversion │ │
63-
│ └──────────────┘ └──────────────┘ └──────────────┘ │
60+
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐
61+
│ │ _buf_work │ │ _buf_show │ │ Pixel Format │
62+
│ │ (editable) │─▶│ (internal) │ │ Conversion │
63+
│ └──────────────┘ └──────────────┘ └──────────────┘
6464
└────────────────────┬────────────────────────────────────────┘
6565
6666
@@ -116,6 +116,7 @@ TasmotaLED uses a dual-buffer system:
116116
│ - _type: uint16_t │
117117
│ - _pixel_order: uint8_t │
118118
│ - _w_before: bool │
119+
│ - _pixel_reverse: bool │
119120
│ - _timing: uint8_t │
120121
│ - _started: bool │
121122
│ - _dirty: bool │
@@ -144,6 +145,7 @@ TasmotaLED uses a dual-buffer system:
144145
│ + GetType(): uint8_t │
145146
│ + IsDirty(): bool │
146147
│ + Dirty(): void │
148+
│ + SetPixelReverse(bool): void │
147149
│ + SetRawFormat(raw): void │
148150
└─────────────────────────────────────────────────────────────┘
149151
@@ -171,18 +173,18 @@ TasmotaLED uses a dual-buffer system:
171173
172174
┌─────────────────┼─────────────────┐
173175
│ │ │
174-
┌─────────┴──────────┐ ┌────┴────────┐ ┌─────┴──────────┐
175-
│ TasmotaLEDPusherRMT│ │TasmotaLED │ │ TasmotaLED │
176-
│ │ │PusherSPI │ │PusherI2S │
177-
├────────────────────┤ ├─────────────┤ ├────────────────┤
176+
┌─────────┴──────────┐ ┌────┴────────┐ ┌─────┴──────────┐
177+
│ TasmotaLEDPusherRMT│ │TasmotaLED │ │ TasmotaLED │
178+
│ │ │PusherSPI │ │PusherI2S │
179+
├────────────────────┤ ├─────────────┤ ├────────────────┤
178180
│ - _pin: int8_t │ │- _pin: int8_t│ │(Future) │
179-
│ - _channel: handle │ │- _spi_strip │ │ │
180-
│ - _led_encoder │ │- _with_dma │ │ │
181-
│ - _tx_config │ │ │ │ │
182-
├────────────────────┤ ├─────────────┤ ├────────────────┤
181+
│ - _channel: handle │ │- _spi_strip │ │ │
182+
│ - _led_encoder │ │- _with_dma │ │ │
183+
│ - _tx_config │ │ │ │ │
184+
├────────────────────┤ ├─────────────┤ ├────────────────┤
183185
│ + Push(): bool │ │+ Push(): bool│ │ │
184-
│ + CanShow(): bool │ │+ CanShow() │ │ │
185-
└────────────────────┘ └─────────────┘ └────────────────┘
186+
│ + CanShow(): bool │ │+ CanShow() │ │ │
187+
└────────────────────┘ └─────────────┘ └────────────────┘
186188
```
187189

188190

lib/lib_basic/TasmotaLED/src/TasmotaLED.cpp

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ enum LoggingLevels {LOG_LEVEL_NONE, LOG_LEVEL_ERROR, LOG_LEVEL_INFO, LOG_LEVEL_D
6363

6464
TasmotaLED::TasmotaLED(uint16_t type, uint16_t num_leds) :
6565
_type(type),
66+
_pixel_reverse(false),
6667
_timing((type >> 8) & 0xFF),
6768
_started(false),
6869
_dirty(true),
@@ -175,14 +176,19 @@ void TasmotaLED::Show(void) {
175176
} else {
176177
uint8_t *buf_from = _buf_work;
177178
uint8_t *buf_to = _buf_show;
179+
int32_t pixel_incr = _pixel_size; // will be set to negative if reverse
180+
if (_pixel_reverse) {
181+
buf_from += (_pixel_count - 1) * _pixel_size;
182+
pixel_incr = -pixel_incr;
183+
}
178184
if (_pixel_size == 3) {
179185
// copying with swapping 512 pixels (1536 bytes) takes 124 microseconds to copy, so it's negligeable
180186
for (uint32_t i = 0; i < _pixel_count; i++) {
181187
buf_to[(*_pixel_matrix)[0]] = buf_from[0]; // R
182188
buf_to[(*_pixel_matrix)[1]] = buf_from[1]; // G
183189
buf_to[(*_pixel_matrix)[2]] = buf_from[2]; // B
184190
buf_to += 3;
185-
buf_from += 3;
191+
buf_from += pixel_incr;
186192
}
187193
} else if (_pixel_size == 4) {
188194
for (uint32_t i = 0; i < _pixel_count; i++) {
@@ -191,8 +197,8 @@ void TasmotaLED::Show(void) {
191197
buf_to[(*_pixel_matrix)[1]] = buf_from[1]; // G
192198
buf_to[(*_pixel_matrix)[2]] = buf_from[2]; // B
193199
if (!_w_before) { *buf_to++ = buf_from[3]; }
194-
buf_to += 3; // one increment already happened
195-
buf_from += 4;
200+
buf_to += 4; // one increment already happened
201+
buf_from += pixel_incr;
196202
}
197203
}
198204
}

lib/lib_basic/TasmotaLED/src/TasmotaLED.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,8 @@ class TasmotaLED {
9696
void SetPixelSubType(uint8_t type); // change only Pixel order and pixel size
9797
void _adjustSubType(void);
9898

99+
inline void SetPixelReverse(bool reverse) { _pixel_reverse = reverse; }
100+
99101
bool Begin(void);
100102
void SetPusher(TasmotaLEDPusher *pusher); // needs to be called before `Begin()`, sets the hardware implementation
101103
void Show(void); // pushes the pixels to the LED strip
@@ -118,6 +120,7 @@ class TasmotaLED {
118120
uint16_t _type; // the composite type
119121
uint8_t _pixel_order; // permutation between RGB and position of W
120122
bool _w_before; // true if W channel comes first (4 channels only)
123+
bool _pixel_reverse; // display LED strip in reverse order
121124
uint8_t _timing; // timing code for strip, 0=WS2812, 1=SK6812...
122125
bool _started; // true if the hardware implementation is configured
123126
bool _dirty; // for NeoPixelBus compatibility, but ignored by `Push()`

tasmota/tasmota_xlgt_light/xlgt_01_ws2812_esp32.ino

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -636,6 +636,7 @@ bool Ws2812InitStrip(void)
636636
}
637637
uint16_t led_type = Ws2812SettingsToLedType();
638638
strip = new TasmotaLED(led_type, Settings->light_pixels);
639+
strip->SetPixelReverse(Settings->light_pixels_reverse);
639640
strip->SetPusher(pusher);
640641
strip->Begin();
641642

@@ -651,6 +652,7 @@ bool Ws2812ChangePixelCount(void)
651652
return true;
652653
}
653654
strip->SetPixelCount(Settings->light_pixels);
655+
strip->SetPixelReverse(Settings->light_pixels_reverse);
654656
Ws2812Clear();
655657
return true;
656658
}
@@ -662,6 +664,7 @@ bool Ws2812ChangePixelType(bool clear)
662664
}
663665
uint16_t led_type = Ws2812SettingsToLedType();
664666
strip->SetPixelSubType(led_type & 0xFF); // just submit the lower part
667+
strip->SetPixelReverse(Settings->light_pixels_reverse);
665668
if (clear) {
666669
Ws2812Clear();
667670
} else {

0 commit comments

Comments
 (0)