TasmotaLED change dynamically the number of pixels (#22754)

* TasmotaLED change dynamically the number of pixels

* fix compilation
This commit is contained in:
s-hadinger 2025-01-02 22:30:19 +01:00 committed by GitHub
parent ed7b58291a
commit 64a2fe8aee
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 65 additions and 1 deletions

View File

@ -7,6 +7,7 @@ All notable changes to this project will be documented in this file.
### Added
- Support for ESP32 Two-Wire Automotive Interface (TWAI) or Controller Area Network (CAN) busses
- Support for Senseair S88 CO2 sensor (#22733)
- TasmotaLED change dynamically the number of pixels
### Breaking Changed

View File

@ -109,6 +109,22 @@ TasmotaLED::~TasmotaLED() {
_buf_show = nullptr;
}
void TasmotaLED::SetPixelCount(uint16_t num_leds) {
if (num_leds != _pixel_count) {
_pixel_count = num_leds;
delete _buf_work;
_buf_work = new uint8_t[_pixel_count * _pixel_size];
memset(_buf_work, 0, _pixel_count * _pixel_size);
delete _buf_show;
_buf_show = new uint8_t[_pixel_count * _pixel_size];
memset(_buf_show, 0, _pixel_count * _pixel_size);
if (_pusher) {
_pusher->SetPixelCount(_pixel_count);
}
}
}
// Color is passed as 0xWWRRGGBB and copied as WWRRGGBB in _buf_work
void TasmotaLED::ClearTo(uint32_t wrgb, int32_t first, int32_t last) {
// adjust first and last to be in range of 0 to _pixel_count-1

View File

@ -91,6 +91,8 @@ public:
TasmotaLED(uint16_t type, uint16_t num_leds);
~TasmotaLED();
void SetPixelCount(uint16_t num_leds);
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

View File

@ -93,6 +93,7 @@ public:
}
virtual bool Push(uint8_t *buf) = 0;
virtual bool CanShow(void) = 0;
virtual bool SetPixelCount(uint16_t pixel_count) = 0;
static uint32_t ResolveHardware(uint32_t hw); // convert to the appropriate hardware acceleration based on capacities of the SOC
static TasmotaLEDPusher * Create(uint32_t hw, int8_t gpio); // create instance for the provided type, or nullptr if failed
@ -118,6 +119,7 @@ public:
~TasmotaLEDPusherRMT();
bool Begin(uint16_t pixel_count, uint16_t pixel_size, const TasmotaLED_Timing * led_timing) override;
bool SetPixelCount(uint16_t pixel_count) override;
bool Push(uint8_t *buf) override;
bool CanShow(void) override;
@ -152,6 +154,7 @@ public:
~TasmotaLEDPusherSPI();
bool Begin(uint16_t pixel_count, uint16_t pixel_size, const TasmotaLED_Timing * led_timing) override;
bool SetPixelCount(uint16_t pixel_count) override;
bool Push(uint8_t *buf) override;
bool CanShow(void) override;

View File

@ -213,6 +213,15 @@ bool TasmotaLEDPusherRMT::Begin(uint16_t pixel_count, uint16_t pixel_size, const
return true;
}
bool TasmotaLEDPusherRMT::SetPixelCount(uint16_t pixel_count) {
if (!_initialized) { return false; }
if (pixel_count > 0 && _pixel_count != pixel_count) {
_pixel_count = pixel_count;
return true;
}
return true;
}
bool TasmotaLEDPusherRMT::CanShow(void) {
if (_channel && _initialized) {
return (ESP_OK == rmt_tx_wait_all_done(_channel, 0));

View File

@ -104,7 +104,7 @@ TasmotaLEDPusherSPI::TasmotaLEDPusherSPI(int8_t pin) : _pin(pin) {
.sclk_io_num = -1,
.quadwp_io_num = -1,
.quadhd_io_num = -1,
.max_transfer_sz = _pixel_count * _pixel_size * SPI_BYTES_PER_COLOR_BYTE,
.max_transfer_sz = 0, // _pixel_count * _pixel_size * SPI_BYTES_PER_COLOR_BYTE,
};
_err = spi_bus_initialize(spi_host, &spi_bus_cfg, _with_dma ? SPI_DMA_CH_AUTO : SPI_DMA_DISABLED);
if (_err == ESP_OK) {
@ -176,6 +176,39 @@ err:
return false;
}
bool TasmotaLEDPusherSPI::SetPixelCount(uint16_t pixel_count) {
if (!_initialized) { return false; }
if (pixel_count > 0 && _pixel_count != pixel_count) {
_pixel_count = pixel_count;
if (_spi_strip.pixel_buf) {
heap_caps_free(_spi_strip.pixel_buf);
_spi_strip.pixel_buf = nullptr;
}
_spi_strip.strip_len = _pixel_count;
uint32_t mem_caps = MALLOC_CAP_DEFAULT;
if (_with_dma) { // TODO
// DMA buffer must be placed in internal SRAM
mem_caps |= MALLOC_CAP_INTERNAL | MALLOC_CAP_DMA;
}
_spi_strip.pixel_buf = (uint8_t *)heap_caps_calloc(1, _pixel_count * _pixel_size * SPI_BYTES_PER_COLOR_BYTE, mem_caps);
if (_spi_strip.pixel_buf == nullptr) {
AddLog(LOG_LEVEL_INFO, PSTR("LED: Error no mem for spi strip"));
if (_spi_strip.spi_device) {
spi_bus_remove_device(_spi_strip.spi_device);
}
if (_spi_strip.spi_host) {
spi_bus_free(_spi_strip.spi_host);
}
_initialized = false;
return false;
}
return true;
}
return true;
}
bool TasmotaLEDPusherSPI::CanShow(void) {
return _initialized; // TODO
}