WS2812 and Berry animation support for reverse-order LED strip (#24138)
This commit is contained in:
parent
9340e218bd
commit
4676db2ede
@ -5,6 +5,7 @@ All notable changes to this project will be documented in this file.
|
||||
|
||||
## [15.1.0.2]
|
||||
### Added
|
||||
- WS2812 and Berry animation support for reverse-order LED strip
|
||||
|
||||
### Breaking Changed
|
||||
|
||||
|
||||
@ -57,10 +57,10 @@ TasmotaLED is designed with the following principles:
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ TasmotaLED Class │
|
||||
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
|
||||
│ │ _buf_work │ │ _buf_show │ │ Pixel Format │ │
|
||||
│ │ (editable) │─▶│ (internal) │ │ Conversion │ │
|
||||
│ └──────────────┘ └──────────────┘ └──────────────┘ │
|
||||
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
|
||||
│ │ _buf_work │ │ _buf_show │ │ Pixel Format │ │
|
||||
│ │ (editable) │─▶│ (internal) │ │ Conversion │ │
|
||||
│ └──────────────┘ └──────────────┘ └──────────────┘ │
|
||||
└────────────────────┬────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
@ -116,6 +116,7 @@ TasmotaLED uses a dual-buffer system:
|
||||
│ - _type: uint16_t │
|
||||
│ - _pixel_order: uint8_t │
|
||||
│ - _w_before: bool │
|
||||
│ - _pixel_reverse: bool │
|
||||
│ - _timing: uint8_t │
|
||||
│ - _started: bool │
|
||||
│ - _dirty: bool │
|
||||
@ -144,6 +145,7 @@ TasmotaLED uses a dual-buffer system:
|
||||
│ + GetType(): uint8_t │
|
||||
│ + IsDirty(): bool │
|
||||
│ + Dirty(): void │
|
||||
│ + SetPixelReverse(bool): void │
|
||||
│ + SetRawFormat(raw): void │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
│
|
||||
@ -171,18 +173,18 @@ TasmotaLED uses a dual-buffer system:
|
||||
│
|
||||
┌─────────────────┼─────────────────┐
|
||||
│ │ │
|
||||
┌─────────┴──────────┐ ┌────┴────────┐ ┌─────┴──────────┐
|
||||
│ TasmotaLEDPusherRMT│ │TasmotaLED │ │ TasmotaLED │
|
||||
│ │ │PusherSPI │ │PusherI2S │
|
||||
├────────────────────┤ ├─────────────┤ ├────────────────┤
|
||||
┌─────────┴──────────┐ ┌────┴─────────┐ ┌─────┴──────────┐
|
||||
│ TasmotaLEDPusherRMT│ │TasmotaLED │ │ TasmotaLED │
|
||||
│ │ │PusherSPI │ │PusherI2S │
|
||||
├────────────────────┤ ├──────────────┤ ├────────────────┤
|
||||
│ - _pin: int8_t │ │- _pin: int8_t│ │(Future) │
|
||||
│ - _channel: handle │ │- _spi_strip │ │ │
|
||||
│ - _led_encoder │ │- _with_dma │ │ │
|
||||
│ - _tx_config │ │ │ │ │
|
||||
├────────────────────┤ ├─────────────┤ ├────────────────┤
|
||||
│ - _channel: handle │ │- _spi_strip │ │ │
|
||||
│ - _led_encoder │ │- _with_dma │ │ │
|
||||
│ - _tx_config │ │ │ │ │
|
||||
├────────────────────┤ ├──────────────┤ ├────────────────┤
|
||||
│ + Push(): bool │ │+ Push(): bool│ │ │
|
||||
│ + CanShow(): bool │ │+ CanShow() │ │ │
|
||||
└────────────────────┘ └─────────────┘ └────────────────┘
|
||||
│ + CanShow(): bool │ │+ CanShow() │ │ │
|
||||
└────────────────────┘ └──────────────┘ └────────────────┘
|
||||
```
|
||||
|
||||
|
||||
|
||||
@ -63,6 +63,7 @@ enum LoggingLevels {LOG_LEVEL_NONE, LOG_LEVEL_ERROR, LOG_LEVEL_INFO, LOG_LEVEL_D
|
||||
|
||||
TasmotaLED::TasmotaLED(uint16_t type, uint16_t num_leds) :
|
||||
_type(type),
|
||||
_pixel_reverse(false),
|
||||
_timing((type >> 8) & 0xFF),
|
||||
_started(false),
|
||||
_dirty(true),
|
||||
@ -175,6 +176,11 @@ void TasmotaLED::Show(void) {
|
||||
} else {
|
||||
uint8_t *buf_from = _buf_work;
|
||||
uint8_t *buf_to = _buf_show;
|
||||
int32_t pixel_incr = _pixel_size; // will be set to negative if reverse
|
||||
if (_pixel_reverse) {
|
||||
buf_from += (_pixel_count - 1) * _pixel_size;
|
||||
pixel_incr = -pixel_incr;
|
||||
}
|
||||
if (_pixel_size == 3) {
|
||||
// copying with swapping 512 pixels (1536 bytes) takes 124 microseconds to copy, so it's negligeable
|
||||
for (uint32_t i = 0; i < _pixel_count; i++) {
|
||||
@ -182,7 +188,7 @@ void TasmotaLED::Show(void) {
|
||||
buf_to[(*_pixel_matrix)[1]] = buf_from[1]; // G
|
||||
buf_to[(*_pixel_matrix)[2]] = buf_from[2]; // B
|
||||
buf_to += 3;
|
||||
buf_from += 3;
|
||||
buf_from += pixel_incr;
|
||||
}
|
||||
} else if (_pixel_size == 4) {
|
||||
for (uint32_t i = 0; i < _pixel_count; i++) {
|
||||
@ -191,8 +197,8 @@ void TasmotaLED::Show(void) {
|
||||
buf_to[(*_pixel_matrix)[1]] = buf_from[1]; // G
|
||||
buf_to[(*_pixel_matrix)[2]] = buf_from[2]; // B
|
||||
if (!_w_before) { *buf_to++ = buf_from[3]; }
|
||||
buf_to += 3; // one increment already happened
|
||||
buf_from += 4;
|
||||
buf_to += 4; // one increment already happened
|
||||
buf_from += pixel_incr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -96,6 +96,8 @@ public:
|
||||
void SetPixelSubType(uint8_t type); // change only Pixel order and pixel size
|
||||
void _adjustSubType(void);
|
||||
|
||||
inline void SetPixelReverse(bool reverse) { _pixel_reverse = reverse; }
|
||||
|
||||
bool Begin(void);
|
||||
void SetPusher(TasmotaLEDPusher *pusher); // needs to be called before `Begin()`, sets the hardware implementation
|
||||
void Show(void); // pushes the pixels to the LED strip
|
||||
@ -118,6 +120,7 @@ protected:
|
||||
uint16_t _type; // the composite type
|
||||
uint8_t _pixel_order; // permutation between RGB and position of W
|
||||
bool _w_before; // true if W channel comes first (4 channels only)
|
||||
bool _pixel_reverse; // display LED strip in reverse order
|
||||
uint8_t _timing; // timing code for strip, 0=WS2812, 1=SK6812...
|
||||
bool _started; // true if the hardware implementation is configured
|
||||
bool _dirty; // for NeoPixelBus compatibility, but ignored by `Push()`
|
||||
|
||||
@ -636,6 +636,7 @@ bool Ws2812InitStrip(void)
|
||||
}
|
||||
uint16_t led_type = Ws2812SettingsToLedType();
|
||||
strip = new TasmotaLED(led_type, Settings->light_pixels);
|
||||
strip->SetPixelReverse(Settings->light_pixels_reverse);
|
||||
strip->SetPusher(pusher);
|
||||
strip->Begin();
|
||||
|
||||
@ -651,6 +652,7 @@ bool Ws2812ChangePixelCount(void)
|
||||
return true;
|
||||
}
|
||||
strip->SetPixelCount(Settings->light_pixels);
|
||||
strip->SetPixelReverse(Settings->light_pixels_reverse);
|
||||
Ws2812Clear();
|
||||
return true;
|
||||
}
|
||||
@ -662,6 +664,7 @@ bool Ws2812ChangePixelType(bool clear)
|
||||
}
|
||||
uint16_t led_type = Ws2812SettingsToLedType();
|
||||
strip->SetPixelSubType(led_type & 0xFF); // just submit the lower part
|
||||
strip->SetPixelReverse(Settings->light_pixels_reverse);
|
||||
if (clear) {
|
||||
Ws2812Clear();
|
||||
} else {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user