mirror of https://github.com/arendst/Tasmota.git
Merge branch 'development' into prerelease-14.4.0
This commit is contained in:
commit
2f4ca9bbe9
|
@ -21,6 +21,7 @@ All notable changes to this project will be documented in this file.
|
|||
- Command `SetOption162 1` to disable adding export energy to energy today (#22578)
|
||||
- ESP32 support for WPA2/3 Enterprise conditional in core v3.1.0.241206 (#22600)
|
||||
- Support for Sonoff POWCT Energy Export Active (#22596)
|
||||
- Improved auto-selection of LED hardware support (RMT, SPI) (#22618)
|
||||
|
||||
### Breaking Changed
|
||||
- ESP32 ArtNet switches from GRB to RGB encoding (#22556)
|
||||
|
|
|
@ -44,10 +44,10 @@ enum TasmotaLEDTypesEncoding : uint16_t {
|
|||
enum TasmotaLEDHardware : uint32_t {
|
||||
// low-order bits are reserved for channels numbers and hardware flags - currenlty not useds
|
||||
// bits 16..23
|
||||
TasmotaLed_HW_Default = 0x0 << 16,
|
||||
TasmotaLed_RMT = 1 << 16,
|
||||
TasmotaLed_SPI = 2 << 16,
|
||||
TasmotaLed_I2S = 3 << 16,
|
||||
TasmotaLed_HW_Default = 0x000000,
|
||||
TasmotaLed_RMT = (1 << 0) << 16,
|
||||
TasmotaLed_SPI = (1 << 1) << 16,
|
||||
TasmotaLed_I2S = (1 << 2) << 16,
|
||||
TasmotaLed_HW_None = 0xFF << 16, // indicates that the specified HW is not supported
|
||||
};
|
||||
|
||||
|
|
|
@ -30,40 +30,33 @@ enum LoggingLevels {LOG_LEVEL_NONE, LOG_LEVEL_ERROR, LOG_LEVEL_INFO, LOG_LEVEL_D
|
|||
|
||||
|
||||
// convert to the appropriate hardware acceleration based on capacities of the SOC
|
||||
uint32_t TasmotaLEDPusher::ResolveHardware(uint32_t hw) {
|
||||
uint32_t hw_orig = hw;
|
||||
uint32_t TasmotaLEDPusher::ResolveHardware(uint32_t hw_input) {
|
||||
// Step 1. discard any unsupported hardware, and replace with TasmotaLed_HW_Default
|
||||
uint32_t hw_type = hw & 0xFF0000; // discard bits 0..15
|
||||
uint32_t hw = hw_input & 0xFF0000; // discard bits 0..15
|
||||
#if !TASMOTALED_HARDWARE_RMT
|
||||
if (hw_type == TasmotaLed_RMT) {
|
||||
hw = TasmotaLed_HW_None;
|
||||
}
|
||||
hw &= ~TasmotaLed_RMT; // remove RMT flag if not supported by hardware
|
||||
#endif // TASMOTALED_HARDWARE_RMT
|
||||
#if !TASMOTALED_HARDWARE_SPI
|
||||
if (hw_type == TasmotaLed_SPI) {
|
||||
hw = TasmotaLed_HW_None;
|
||||
}
|
||||
hw &= ~TasmotaLed_SPI; // remove SPI flag if not supported by hardware
|
||||
#endif // TASMOTALED_HARDWARE_SPI
|
||||
#if !TASMOTALED_HARDWARE_I2S
|
||||
if (hw_type == TasmotaLed_I2S) {
|
||||
hw = TasmotaLed_HW_None;
|
||||
}
|
||||
hw &= ~TasmotaLed_I2S; // remove I2S flag if not supported by hardware
|
||||
#endif // TASMOTALED_HARDWARE_I2S
|
||||
|
||||
// Step 2. If TasmotaLed_HW_Default, find a suitable scheme, RMT preferred
|
||||
#if TASMOTALED_HARDWARE_RMT
|
||||
if ((hw & 0xFF0000) == TasmotaLed_HW_Default) {
|
||||
hw = TasmotaLed_RMT;
|
||||
if (hw == TasmotaLed_HW_Default) {
|
||||
hw |= TasmotaLed_RMT;
|
||||
}
|
||||
#endif // TASMOTALED_HARDWARE_RMT
|
||||
#if TASMOTALED_HARDWARE_I2S
|
||||
if ((hw & 0xFF0000) == TasmotaLed_HW_Default) {
|
||||
hw = TasmotaLed_I2S;
|
||||
if (hw == TasmotaLed_HW_Default) {
|
||||
hw |= TasmotaLed_I2S;
|
||||
}
|
||||
#endif // TASMOTALED_HARDWARE_I2S
|
||||
#if TASMOTALED_HARDWARE_SPI
|
||||
if ((hw & 0xFF0000) == TasmotaLed_HW_Default) {
|
||||
hw = TasmotaLed_SPI;
|
||||
if (hw == TasmotaLed_HW_Default) {
|
||||
hw |= TasmotaLed_SPI;
|
||||
}
|
||||
#endif // TASMOTALED_HARDWARE_SPI
|
||||
return hw;
|
||||
|
@ -75,22 +68,30 @@ TasmotaLEDPusher * TasmotaLEDPusher::Create(uint32_t hw, int8_t gpio) {
|
|||
|
||||
hw = TasmotaLEDPusher::ResolveHardware(hw);
|
||||
|
||||
switch (hw & 0XFF0000) {
|
||||
#if TASMOTALED_HARDWARE_RMT
|
||||
case TasmotaLed_RMT:
|
||||
if (pusher == nullptr && (hw & TasmotaLed_RMT)) {
|
||||
pusher = new TasmotaLEDPusherRMT(gpio);
|
||||
if (pusher->Initialized()) {
|
||||
AddLog(LOG_LEVEL_DEBUG, "LED: RMT gpio %i", gpio);
|
||||
break;
|
||||
} else {
|
||||
AddLog(LOG_LEVEL_INFO, "LED: Error create %s bus failed %i err=%i", "RMT", gpio, pusher->Error());
|
||||
delete pusher;
|
||||
pusher = nullptr;
|
||||
}
|
||||
}
|
||||
#endif // TASMOTALED_HARDWARE_RMT
|
||||
#if TASMOTALED_HARDWARE_SPI
|
||||
case TasmotaLed_SPI:
|
||||
if (pusher == nullptr && (hw & TasmotaLed_SPI)) {
|
||||
pusher = new TasmotaLEDPusherSPI(gpio);
|
||||
if (pusher->Initialized()) {
|
||||
AddLog(LOG_LEVEL_DEBUG, "LED: SPI gpio %i", gpio);
|
||||
break;
|
||||
#endif // TASMOTALED_HARDWARE_SPI
|
||||
default:
|
||||
break;
|
||||
} else {
|
||||
AddLog(LOG_LEVEL_INFO, "LED: Error create %s bus failed %i err=%i", "SPI", gpio, pusher->Error());
|
||||
delete pusher;
|
||||
pusher = nullptr;
|
||||
}
|
||||
}
|
||||
#endif // TASMOTALED_HARDWARE_SPI
|
||||
return pusher;
|
||||
}
|
||||
|
||||
|
|
|
@ -80,9 +80,11 @@ typedef struct TasmotaLED_Timing {
|
|||
\*******************************************************************************************/
|
||||
class TasmotaLEDPusher {
|
||||
public:
|
||||
TasmotaLEDPusher() : _pixel_count(0), _pixel_size(0), _led_timing(nullptr) {};
|
||||
TasmotaLEDPusher() : _initialized(false), _err(ESP_OK), _pixel_count(0), _pixel_size(0), _led_timing(nullptr) {};
|
||||
virtual ~TasmotaLEDPusher() {};
|
||||
|
||||
bool Initialized(void) const { return _initialized; }
|
||||
esp_err_t Error(void) const { return _err; }
|
||||
virtual bool Begin(uint16_t pixel_count, uint16_t pixel_size, const TasmotaLED_Timing * led_timing) {
|
||||
_pixel_count = pixel_count;
|
||||
_pixel_size = pixel_size;
|
||||
|
@ -96,6 +98,8 @@ public:
|
|||
static TasmotaLEDPusher * Create(uint32_t hw, int8_t gpio); // create instance for the provided type, or nullptr if failed
|
||||
|
||||
protected:
|
||||
bool _initialized; // did the hardware got correctly initialized
|
||||
esp_err_t _err;
|
||||
uint16_t _pixel_count;
|
||||
uint16_t _pixel_size;
|
||||
const TasmotaLED_Timing * _led_timing;
|
||||
|
@ -110,7 +114,7 @@ protected:
|
|||
#include "driver/rmt_tx.h"
|
||||
class TasmotaLEDPusherRMT : public TasmotaLEDPusher {
|
||||
public:
|
||||
TasmotaLEDPusherRMT(int8_t pin) : _pin(pin) {};
|
||||
TasmotaLEDPusherRMT(int8_t pin);
|
||||
~TasmotaLEDPusherRMT();
|
||||
|
||||
bool Begin(uint16_t pixel_count, uint16_t pixel_size, const TasmotaLED_Timing * led_timing) override;
|
||||
|
@ -144,7 +148,7 @@ typedef struct led_strip_spi_obj_t {
|
|||
|
||||
class TasmotaLEDPusherSPI : public TasmotaLEDPusher {
|
||||
public:
|
||||
TasmotaLEDPusherSPI(int8_t pin) : _pin(pin), _spi_strip({}) {};
|
||||
TasmotaLEDPusherSPI(int8_t pin);
|
||||
~TasmotaLEDPusherSPI();
|
||||
|
||||
bool Begin(uint16_t pixel_count, uint16_t pixel_size, const TasmotaLED_Timing * led_timing) override;
|
||||
|
@ -154,7 +158,8 @@ public:
|
|||
|
||||
protected:
|
||||
int8_t _pin;
|
||||
struct led_strip_spi_obj_t _spi_strip;
|
||||
struct led_strip_spi_obj_t _spi_strip = {};;
|
||||
const bool _with_dma = true;
|
||||
};
|
||||
#endif // TASMOTALED_HARDWARE_SPI
|
||||
|
||||
|
|
|
@ -155,9 +155,7 @@ TasmotaLEDPusherRMT::~TasmotaLEDPusherRMT() {
|
|||
}
|
||||
}
|
||||
|
||||
bool TasmotaLEDPusherRMT::Begin(uint16_t pixel_count, uint16_t pixel_size, const TasmotaLED_Timing * led_timing) {
|
||||
TasmotaLEDPusher::Begin(pixel_count, pixel_size, led_timing);
|
||||
|
||||
TasmotaLEDPusherRMT::TasmotaLEDPusherRMT(int8_t pin) : _pin(pin) {
|
||||
esp_err_t ret = ESP_OK;
|
||||
rmt_tx_channel_config_t config = {};
|
||||
config.clk_src = RMT_CLK_SRC_DEFAULT;
|
||||
|
@ -168,11 +166,15 @@ bool TasmotaLEDPusherRMT::Begin(uint16_t pixel_count, uint16_t pixel_size, const
|
|||
config.flags.invert_out = false; // do not invert output signal
|
||||
config.flags.with_dma = false; // do not need DMA backend
|
||||
|
||||
ret = rmt_new_tx_channel(&config, &_channel);
|
||||
if (ret != ESP_OK) {
|
||||
AddLog(LOG_LEVEL_INFO, "RMT: cannot initialize Gpio %i err=%i", _pin, ret);
|
||||
return false;
|
||||
_err = rmt_new_tx_channel(&config, &_channel);
|
||||
if (_err == ESP_OK) {
|
||||
_initialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
bool TasmotaLEDPusherRMT::Begin(uint16_t pixel_count, uint16_t pixel_size, const TasmotaLED_Timing * led_timing) {
|
||||
if (!_initialized) { return false; }
|
||||
TasmotaLEDPusher::Begin(pixel_count, pixel_size, led_timing);
|
||||
led_strip_encoder_config_t encoder_config = {
|
||||
.resolution = RMT_LED_STRIP_RESOLUTION_HZ,
|
||||
};
|
||||
|
@ -198,13 +200,13 @@ bool TasmotaLEDPusherRMT::Begin(uint16_t pixel_count, uint16_t pixel_size, const
|
|||
.level1 = 1,
|
||||
};
|
||||
// AddLog(LOG_LEVEL_INFO, "RMT: RmtBit0 0x%08X RmtBit1 0x%08X RmtReset 0x%08X", RmtBit0.val, RmtBit1.val, RmtReset.val);
|
||||
ret = rmt_new_led_strip_encoder(&encoder_config, &_led_encoder, RmtBit0, RmtBit1, RmtReset);
|
||||
if (ret != ESP_OK) {
|
||||
_err = rmt_new_led_strip_encoder(&encoder_config, &_led_encoder, RmtBit0, RmtBit1, RmtReset);
|
||||
if (_err != ESP_OK) {
|
||||
// AddLog(LOG_LEVEL_INFO, "RMT: cannot initialize led strip encoder err=%i", ret);
|
||||
return false;
|
||||
}
|
||||
ret = rmt_enable(_channel);
|
||||
if (ret != ESP_OK) {
|
||||
_err = rmt_enable(_channel);
|
||||
if (_err != ESP_OK) {
|
||||
// AddLog(LOG_LEVEL_INFO, "RMT: cannot enable channel err=%i", ret);
|
||||
return false;
|
||||
}
|
||||
|
@ -212,7 +214,7 @@ bool TasmotaLEDPusherRMT::Begin(uint16_t pixel_count, uint16_t pixel_size, const
|
|||
}
|
||||
|
||||
bool TasmotaLEDPusherRMT::CanShow(void) {
|
||||
if (_channel) {
|
||||
if (_channel && _initialized) {
|
||||
return (ESP_OK == rmt_tx_wait_all_done(_channel, 0));
|
||||
} else {
|
||||
return false;
|
||||
|
@ -220,6 +222,7 @@ bool TasmotaLEDPusherRMT::CanShow(void) {
|
|||
}
|
||||
|
||||
bool TasmotaLEDPusherRMT::Push(uint8_t *buf) {
|
||||
if (!_initialized) { return false; }
|
||||
|
||||
// wait for not actively sending data
|
||||
// this will time out at 1 second, an arbitrarily long period of time
|
||||
|
|
|
@ -95,31 +95,9 @@ TasmotaLEDPusherSPI::~TasmotaLEDPusherSPI() {
|
|||
}
|
||||
}
|
||||
|
||||
bool TasmotaLEDPusherSPI::Begin(uint16_t pixel_count, uint16_t pixel_size, const TasmotaLED_Timing * led_timing) {
|
||||
TasmotaLEDPusher::Begin(pixel_count, pixel_size, led_timing);
|
||||
_spi_strip.bytes_per_pixel = _pixel_size;
|
||||
_spi_strip.strip_len = _pixel_count;
|
||||
|
||||
esp_err_t err = ESP_OK;
|
||||
uint32_t mem_caps = MALLOC_CAP_DEFAULT;
|
||||
// spi_clock_source_t clk_src = SPI_CLK_SRC_DEFAULT;
|
||||
spi_bus_config_t spi_bus_cfg;
|
||||
spi_device_interface_config_t spi_dev_cfg;
|
||||
TasmotaLEDPusherSPI::TasmotaLEDPusherSPI(int8_t pin) : _pin(pin) {
|
||||
spi_host_device_t spi_host = SPI2_HOST;
|
||||
bool with_dma = true; /// TODO: pass value or compute based on pixelcount
|
||||
int clock_resolution_khz = 0;
|
||||
|
||||
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"));
|
||||
goto err;
|
||||
}
|
||||
|
||||
spi_bus_cfg = {
|
||||
spi_bus_config_t spi_bus_cfg = {
|
||||
.mosi_io_num = _pin,
|
||||
//Only use MOSI to generate the signal, set -1 when other pins are not used.
|
||||
.miso_io_num = -1,
|
||||
|
@ -128,12 +106,35 @@ bool TasmotaLEDPusherSPI::Begin(uint16_t pixel_count, uint16_t pixel_size, const
|
|||
.quadhd_io_num = -1,
|
||||
.max_transfer_sz = _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) {
|
||||
AddLog(LOG_LEVEL_INFO, PSTR("LED: Error create SPI bus failed"));
|
||||
_err = spi_bus_initialize(spi_host, &spi_bus_cfg, _with_dma ? SPI_DMA_CH_AUTO : SPI_DMA_DISABLED);
|
||||
if (_err == ESP_OK) {
|
||||
_spi_strip.spi_host = spi_host; // confirmed working, so keep it's value to free it later
|
||||
_initialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
bool TasmotaLEDPusherSPI::Begin(uint16_t pixel_count, uint16_t pixel_size, const TasmotaLED_Timing * led_timing) {
|
||||
if (!_initialized) {
|
||||
return false;
|
||||
}
|
||||
TasmotaLEDPusher::Begin(pixel_count, pixel_size, led_timing);
|
||||
_spi_strip.bytes_per_pixel = _pixel_size;
|
||||
_spi_strip.strip_len = _pixel_count;
|
||||
|
||||
uint32_t mem_caps = MALLOC_CAP_DEFAULT;
|
||||
// spi_clock_source_t clk_src = SPI_CLK_SRC_DEFAULT;
|
||||
spi_device_interface_config_t spi_dev_cfg;
|
||||
int clock_resolution_khz = 0;
|
||||
|
||||
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"));
|
||||
goto err;
|
||||
}
|
||||
_spi_strip.spi_host = spi_host; // confirmed working, so keep it's value to free it later
|
||||
|
||||
spi_dev_cfg = {
|
||||
.command_bits = 0,
|
||||
|
@ -146,14 +147,14 @@ bool TasmotaLEDPusherSPI::Begin(uint16_t pixel_count, uint16_t pixel_size, const
|
|||
.spics_io_num = -1,
|
||||
.queue_size = LED_STRIP_SPI_DEFAULT_TRANS_QUEUE_SIZE,
|
||||
};
|
||||
err = spi_bus_add_device(_spi_strip.spi_host, &spi_dev_cfg, &_spi_strip.spi_device);
|
||||
if (err != ESP_OK) {
|
||||
_err = spi_bus_add_device(_spi_strip.spi_host, &spi_dev_cfg, &_spi_strip.spi_device);
|
||||
if (_err != ESP_OK) {
|
||||
// AddLog(LOG_LEVEL_INFO, "LED: Error failed to add spi device");
|
||||
goto err;
|
||||
}
|
||||
|
||||
spi_device_get_actual_freq(_spi_strip.spi_device, &clock_resolution_khz);
|
||||
if (err != ESP_OK) {
|
||||
_err = spi_device_get_actual_freq(_spi_strip.spi_device, &clock_resolution_khz);
|
||||
if (_err != ESP_OK) {
|
||||
// AddLog(LOG_LEVEL_INFO, "LED: Error failed to get spi frequency");
|
||||
goto err;
|
||||
}
|
||||
|
@ -163,7 +164,6 @@ bool TasmotaLEDPusherSPI::Begin(uint16_t pixel_count, uint16_t pixel_size, const
|
|||
// AddLog(LOG_LEVEL_INFO, "LED: Error unsupported clock resolution: %dKHz", clock_resolution_khz);
|
||||
goto err;
|
||||
}
|
||||
|
||||
return true;
|
||||
err:
|
||||
if (_spi_strip.spi_device) {
|
||||
|
@ -172,15 +172,16 @@ err:
|
|||
if (_spi_strip.spi_host) {
|
||||
spi_bus_free(_spi_strip.spi_host);
|
||||
}
|
||||
_initialized = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool TasmotaLEDPusherSPI::CanShow(void) {
|
||||
return true; // TODO
|
||||
return _initialized; // TODO
|
||||
}
|
||||
|
||||
bool TasmotaLEDPusherSPI::Push(uint8_t *buf) {
|
||||
|
||||
if (!_initialized) { return false; }
|
||||
if (CanShow()) {
|
||||
led_strip_transmit_buffer(&_spi_strip, buf);
|
||||
}
|
||||
|
|
|
@ -82,7 +82,7 @@ class Matter_UI
|
|||
# webserver.content_send("<p><form id=ac action='matterc' style='display: block;' method='get'><button>Configure Matter</button></form></p>")
|
||||
webserver.content_send("<p><form id=ac action='matterc' style='display: block;' method='get'><button>")
|
||||
webserver.content_send(matter._LOGO)
|
||||
webserver.content_send(" Configure Matter</button></form></p>")
|
||||
webserver.content_send(" Matter</button></form></p>")
|
||||
end
|
||||
|
||||
#- ---------------------------------------------------------------------- -#
|
||||
|
|
|
@ -191,7 +191,7 @@ static const bvalue be_ktab_class_Matter_UI[232] = {
|
|||
/* K182 */ be_nested_str_weak(_X3C_X2Ftable_X3E_X3Chr_X3E),
|
||||
/* K183 */ be_nested_str_weak(_X3Cp_X3E_X3Cform_X20id_X3Dac_X20action_X3D_X27matterc_X27_X20style_X3D_X27display_X3A_X20block_X3B_X27_X20method_X3D_X27get_X27_X3E_X3Cbutton_X3E),
|
||||
/* K184 */ be_nested_str_weak(_LOGO),
|
||||
/* K185 */ be_nested_str_weak(_X20Configure_X20Matter_X3C_X2Fbutton_X3E_X3C_X2Fform_X3E_X3C_X2Fp_X3E),
|
||||
/* K185 */ be_nested_str_weak(_X20Matter_X3C_X2Fbutton_X3E_X3C_X2Fform_X3E_X3C_X2Fp_X3E),
|
||||
/* K186 */ be_nested_str_weak(get_plugin_class_displayname),
|
||||
/* K187 */ be_nested_str_weak(Matter_X20Advanced_X20Configuration),
|
||||
/* K188 */ be_nested_str_weak(show_passcode_form),
|
||||
|
|
|
@ -1148,6 +1148,8 @@ int GetCommandCode(char* destination, size_t destination_size, const char* needl
|
|||
|
||||
bool DecodeCommand(const char* haystack, void (* const MyCommand[])(void), const uint8_t *synonyms = nullptr);
|
||||
bool DecodeCommand(const char* haystack, void (* const MyCommand[])(void), const uint8_t *synonyms) {
|
||||
SHOW_FREE_MEM(PSTR("DecodeCommand"));
|
||||
|
||||
GetTextIndexed(XdrvMailbox.command, CMDSZ, 0, haystack); // Get prefix if available
|
||||
int prefix_length = strlen(XdrvMailbox.command);
|
||||
if (prefix_length) {
|
||||
|
@ -2680,9 +2682,7 @@ void AddLogData(uint32_t loglevel, const char* log_data, const char* log_data_pa
|
|||
}
|
||||
snprintf_P(TasmotaGlobal.log_buffer, LOG_BUFFER_SIZE, PSTR("%s%c%c%s%s%s%s\1"),
|
||||
TasmotaGlobal.log_buffer, TasmotaGlobal.log_buffer_pointer++, '0'+loglevel, mxtime, log_data, log_data_payload, log_data_retained);
|
||||
if (too_long) {
|
||||
free(too_long);
|
||||
}
|
||||
if (too_long) { free(too_long); }
|
||||
TasmotaGlobal.log_buffer_pointer &= 0xFF;
|
||||
if (!TasmotaGlobal.log_buffer_pointer) {
|
||||
TasmotaGlobal.log_buffer_pointer++; // Index 0 is not allowed as it is the end of char string
|
||||
|
|
|
@ -702,8 +702,7 @@ void MqttPublishLoggingAsync(bool refresh) {
|
|||
|
||||
void MqttPublishPayload(const char* topic, const char* payload, uint32_t binary_length, bool retained) {
|
||||
// Publish <topic> payload string or binary when binary_length set with optional retained
|
||||
|
||||
SHOW_FREE_MEM(PSTR("MqttPublish"));
|
||||
SHOW_FREE_MEM(PSTR("MqttPublishPayload"));
|
||||
|
||||
bool binary_data = (binary_length > 0);
|
||||
if (!binary_data) {
|
||||
|
@ -794,14 +793,30 @@ void MqttPublishPayloadPrefixTopic_P(uint32_t prefix, const char* subtopic, cons
|
|||
prefix 5 = stat using subtopic or RESULT
|
||||
prefix 6 = tele using subtopic or RESULT
|
||||
*/
|
||||
char romram[64];
|
||||
SHOW_FREE_MEM(PSTR("MqttPublishPayloadPrefixTopic_P"));
|
||||
/*
|
||||
char romram[64]; // Claim 64 bytes from 4k stack
|
||||
snprintf_P(romram, sizeof(romram), ((prefix > 3) && !Settings->flag.mqtt_response) ? S_RSLT_RESULT : subtopic); // SetOption4 - Switch between MQTT RESULT or COMMAND
|
||||
UpperCase(romram, romram);
|
||||
|
||||
prefix &= 3;
|
||||
char stopic[TOPSZ];
|
||||
char stopic[TOPSZ]; // Claim TOPSZ bytes from 4k stack
|
||||
GetTopic_P(stopic, prefix, TasmotaGlobal.mqtt_topic, romram);
|
||||
MqttPublishPayload(stopic, payload, binary_length, retained);
|
||||
*/
|
||||
// Reduce important stack usage by 200 bytes but adding 52 bytes code
|
||||
char *romram = (char*)malloc(64); // Claim 64 bytes from 20k heap
|
||||
strcpy_P(romram, ((prefix > 3) && !Settings->flag.mqtt_response) ? S_RSLT_RESULT : subtopic);
|
||||
UpperCase(romram, romram);
|
||||
|
||||
prefix &= 3;
|
||||
char *htopic = (char*)malloc(TOPSZ); // Claim TOPSZ bytes from 16k heap
|
||||
GetTopic_P(htopic, prefix, TasmotaGlobal.mqtt_topic, romram);
|
||||
char stopic[strlen_P(htopic) +1]; // Claim only strlen_P bytes from 4k stack
|
||||
strcpy_P(stopic, htopic);
|
||||
free(htopic); // Free 16k heap from TOPSZ bytes
|
||||
free(romram); // Free 16k heap from 64 bytes
|
||||
MqttPublishPayload(stopic, payload, binary_length, retained);
|
||||
|
||||
#if defined(USE_MQTT_AWS_IOT) || defined(USE_MQTT_AWS_IOT_LIGHT)
|
||||
if ((prefix > 0) && (Settings->flag4.awsiot_shadow) && (Mqtt.connected)) { // placeholder for SetOptionXX
|
||||
|
@ -857,6 +872,8 @@ void MqttPublishPayloadPrefixTopicRulesProcess_P(uint32_t prefix, const char* su
|
|||
|
||||
void MqttPublishPrefixTopic_P(uint32_t prefix, const char* subtopic, bool retained) {
|
||||
// Publish <prefix>/<device>/<RESULT or <subtopic>> default ResponseData string with optional retained
|
||||
SHOW_FREE_MEM(PSTR("MqttPublishPrefixTopic_P"));
|
||||
|
||||
MqttPublishPayloadPrefixTopic_P(prefix, subtopic, ResponseData(), 0, retained);
|
||||
}
|
||||
|
||||
|
@ -868,6 +885,8 @@ void MqttPublishPrefixTopic_P(uint32_t prefix, const char* subtopic) {
|
|||
void MqttPublishPrefixTopicRulesProcess_P(uint32_t prefix, const char* subtopic, bool retained) {
|
||||
// Publish <prefix>/<device>/<RESULT or <subtopic>> default ResponseData string with optional retained
|
||||
// then process rules
|
||||
SHOW_FREE_MEM(PSTR("MqttPublishPrefixTopicRulesProcess_P"));
|
||||
|
||||
MqttPublishPrefixTopic_P(prefix, subtopic, retained);
|
||||
XdrvRulesProcess(0);
|
||||
}
|
||||
|
|
|
@ -186,12 +186,6 @@ extern "C" {
|
|||
pixels_size = strip->PixelCount() * strip->PixelSize();
|
||||
update_completed = strip->CanShow();
|
||||
}
|
||||
|
||||
// Wait for RMT/I2S to complete fixes distortion due to analogRead
|
||||
// 1ms is needed for 96 bytes
|
||||
if (!update_completed) {
|
||||
SystemBusyDelay((pixels_size + 95) / 96);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 3: // # 03 : CanShow void -> bool
|
||||
|
|
|
@ -95,20 +95,8 @@ const uint16_t kTasLed_PixelWhite = TasmotaLed_xxxW;
|
|||
|
||||
const uint16_t kTasLed_Type = kTasLed_PixelSize | kTasLed_PixelOrder | kTasLed_PixelWhite | kTasLed_Timing;
|
||||
|
||||
// select hardware acceleration - bitbanging is not supported on ESP32 due to interference of interrupts
|
||||
#if CONFIG_IDF_TARGET_ESP32C2
|
||||
const uint32_t kTasLed_Hardware = TasmotaLed_SPI; // no I2S for the C2
|
||||
#else // all other ESP32 variants
|
||||
#if defined(USE_WS2812_DMA)
|
||||
const uint32_t kTasLed_Hardware = TasmotaLed_RMT; // default DMA to RMT
|
||||
#elif defined(USE_WS2812_RMT)
|
||||
const uint32_t kTasLed_Hardware = TasmotaLed_RMT; // default DMA to RMT
|
||||
#elif defined(USE_WS2812_I2S)
|
||||
const uint32_t kTasLed_Hardware = TasmotaLed_I2S; // I2S
|
||||
#else
|
||||
const uint32_t kTasLed_Hardware = TasmotaLed_RMT; // default DMA to RMT
|
||||
#endif
|
||||
#endif
|
||||
// select hardware acceleration - bitbanging is not supported on ESP32 due to interference of interrupts - use default
|
||||
const uint32_t kTasLed_Hardware = TasmotaLed_HW_Default; // use whatever is available
|
||||
|
||||
#if (USE_WS2812_HARDWARE == NEO_HW_P9813)
|
||||
#error "P9813 is not supported by this library"
|
||||
|
@ -186,12 +174,6 @@ long wsmap(long x, long in_min, long in_max, long out_min, long out_max) {
|
|||
|
||||
void Ws2812LibStripShow(void) {
|
||||
strip->Show();
|
||||
|
||||
#if defined(USE_WS2812_DMA) || defined(USE_WS2812_RMT) || defined(USE_WS2812_I2S)
|
||||
// Wait for DMA/RMT/I2S to complete fixes distortion due to analogRead
|
||||
// delay((Settings->light_pixels >> 6) +1); // 256 / 64 = 4 +1 = 5
|
||||
SystemBusyDelay( (Settings->light_pixels + 31) >> 5); // (256 + 32) / 32 = 8
|
||||
#endif
|
||||
}
|
||||
|
||||
void Ws2812StripShow(void)
|
||||
|
|
|
@ -1105,10 +1105,10 @@ bool XdrvRulesProcess(bool teleperiod) {
|
|||
|
||||
#ifdef USE_DEBUG_DRIVER
|
||||
void ShowFreeMem(const char *where) {
|
||||
char stemp[30];
|
||||
snprintf_P(stemp, sizeof(stemp), where);
|
||||
XdrvMailbox.data = stemp;
|
||||
char *XdrvMailboxData = XdrvMailbox.data;
|
||||
XdrvMailbox.data = (char*)where;
|
||||
XdrvCall(FUNC_FREE_MEM);
|
||||
XdrvMailbox.data = XdrvMailboxData;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
Loading…
Reference in New Issue