mirror of https://github.com/arendst/Tasmota.git
Improved auto-selection of LED hardware support (RMT, SPI) (#22618)
This commit is contained in:
parent
c1834bd898
commit
bdf880cf84
|
@ -18,6 +18,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)
|
- 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)
|
- ESP32 support for WPA2/3 Enterprise conditional in core v3.1.0.241206 (#22600)
|
||||||
- Support for Sonoff POWCT Energy Export Active (#22596)
|
- Support for Sonoff POWCT Energy Export Active (#22596)
|
||||||
|
- Improved auto-selection of LED hardware support (RMT, SPI)
|
||||||
|
|
||||||
### Breaking Changed
|
### Breaking Changed
|
||||||
- ESP32 ArtNet switches from GRB to RGB encoding (#22556)
|
- ESP32 ArtNet switches from GRB to RGB encoding (#22556)
|
||||||
|
|
|
@ -44,10 +44,10 @@ enum TasmotaLEDTypesEncoding : uint16_t {
|
||||||
enum TasmotaLEDHardware : uint32_t {
|
enum TasmotaLEDHardware : uint32_t {
|
||||||
// low-order bits are reserved for channels numbers and hardware flags - currenlty not useds
|
// low-order bits are reserved for channels numbers and hardware flags - currenlty not useds
|
||||||
// bits 16..23
|
// bits 16..23
|
||||||
TasmotaLed_HW_Default = 0x0 << 16,
|
TasmotaLed_HW_Default = 0x000000,
|
||||||
TasmotaLed_RMT = 1 << 16,
|
TasmotaLed_RMT = (1 << 0) << 16,
|
||||||
TasmotaLed_SPI = 2 << 16,
|
TasmotaLed_SPI = (1 << 1) << 16,
|
||||||
TasmotaLed_I2S = 3 << 16,
|
TasmotaLed_I2S = (1 << 2) << 16,
|
||||||
TasmotaLed_HW_None = 0xFF << 16, // indicates that the specified HW is not supported
|
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
|
// convert to the appropriate hardware acceleration based on capacities of the SOC
|
||||||
uint32_t TasmotaLEDPusher::ResolveHardware(uint32_t hw) {
|
uint32_t TasmotaLEDPusher::ResolveHardware(uint32_t hw_input) {
|
||||||
uint32_t hw_orig = hw;
|
|
||||||
// Step 1. discard any unsupported hardware, and replace with TasmotaLed_HW_Default
|
// 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 !TASMOTALED_HARDWARE_RMT
|
||||||
if (hw_type == TasmotaLed_RMT) {
|
hw &= ~TasmotaLed_RMT; // remove RMT flag if not supported by hardware
|
||||||
hw = TasmotaLed_HW_None;
|
|
||||||
}
|
|
||||||
#endif // TASMOTALED_HARDWARE_RMT
|
#endif // TASMOTALED_HARDWARE_RMT
|
||||||
#if !TASMOTALED_HARDWARE_SPI
|
#if !TASMOTALED_HARDWARE_SPI
|
||||||
if (hw_type == TasmotaLed_SPI) {
|
hw &= ~TasmotaLed_SPI; // remove SPI flag if not supported by hardware
|
||||||
hw = TasmotaLed_HW_None;
|
|
||||||
}
|
|
||||||
#endif // TASMOTALED_HARDWARE_SPI
|
#endif // TASMOTALED_HARDWARE_SPI
|
||||||
#if !TASMOTALED_HARDWARE_I2S
|
#if !TASMOTALED_HARDWARE_I2S
|
||||||
if (hw_type == TasmotaLed_I2S) {
|
hw &= ~TasmotaLed_I2S; // remove I2S flag if not supported by hardware
|
||||||
hw = TasmotaLed_HW_None;
|
|
||||||
}
|
|
||||||
#endif // TASMOTALED_HARDWARE_I2S
|
#endif // TASMOTALED_HARDWARE_I2S
|
||||||
|
|
||||||
// Step 2. If TasmotaLed_HW_Default, find a suitable scheme, RMT preferred
|
// Step 2. If TasmotaLed_HW_Default, find a suitable scheme, RMT preferred
|
||||||
#if TASMOTALED_HARDWARE_RMT
|
#if TASMOTALED_HARDWARE_RMT
|
||||||
if ((hw & 0xFF0000) == TasmotaLed_HW_Default) {
|
if (hw == TasmotaLed_HW_Default) {
|
||||||
hw = TasmotaLed_RMT;
|
hw |= TasmotaLed_RMT;
|
||||||
}
|
}
|
||||||
#endif // TASMOTALED_HARDWARE_RMT
|
#endif // TASMOTALED_HARDWARE_RMT
|
||||||
#if TASMOTALED_HARDWARE_I2S
|
#if TASMOTALED_HARDWARE_I2S
|
||||||
if ((hw & 0xFF0000) == TasmotaLed_HW_Default) {
|
if (hw == TasmotaLed_HW_Default) {
|
||||||
hw = TasmotaLed_I2S;
|
hw |= TasmotaLed_I2S;
|
||||||
}
|
}
|
||||||
#endif // TASMOTALED_HARDWARE_I2S
|
#endif // TASMOTALED_HARDWARE_I2S
|
||||||
#if TASMOTALED_HARDWARE_SPI
|
#if TASMOTALED_HARDWARE_SPI
|
||||||
if ((hw & 0xFF0000) == TasmotaLed_HW_Default) {
|
if (hw == TasmotaLed_HW_Default) {
|
||||||
hw = TasmotaLed_SPI;
|
hw |= TasmotaLed_SPI;
|
||||||
}
|
}
|
||||||
#endif // TASMOTALED_HARDWARE_SPI
|
#endif // TASMOTALED_HARDWARE_SPI
|
||||||
return hw;
|
return hw;
|
||||||
|
@ -75,22 +68,30 @@ TasmotaLEDPusher * TasmotaLEDPusher::Create(uint32_t hw, int8_t gpio) {
|
||||||
|
|
||||||
hw = TasmotaLEDPusher::ResolveHardware(hw);
|
hw = TasmotaLEDPusher::ResolveHardware(hw);
|
||||||
|
|
||||||
switch (hw & 0XFF0000) {
|
|
||||||
#if TASMOTALED_HARDWARE_RMT
|
#if TASMOTALED_HARDWARE_RMT
|
||||||
case TasmotaLed_RMT:
|
if (pusher == nullptr && (hw & TasmotaLed_RMT)) {
|
||||||
pusher = new TasmotaLEDPusherRMT(gpio);
|
pusher = new TasmotaLEDPusherRMT(gpio);
|
||||||
|
if (pusher->Initialized()) {
|
||||||
AddLog(LOG_LEVEL_DEBUG, "LED: RMT gpio %i", gpio);
|
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
|
#endif // TASMOTALED_HARDWARE_RMT
|
||||||
#if TASMOTALED_HARDWARE_SPI
|
#if TASMOTALED_HARDWARE_SPI
|
||||||
case TasmotaLed_SPI:
|
if (pusher == nullptr && (hw & TasmotaLed_SPI)) {
|
||||||
pusher = new TasmotaLEDPusherSPI(gpio);
|
pusher = new TasmotaLEDPusherSPI(gpio);
|
||||||
|
if (pusher->Initialized()) {
|
||||||
AddLog(LOG_LEVEL_DEBUG, "LED: SPI gpio %i", gpio);
|
AddLog(LOG_LEVEL_DEBUG, "LED: SPI gpio %i", gpio);
|
||||||
break;
|
} else {
|
||||||
#endif // TASMOTALED_HARDWARE_SPI
|
AddLog(LOG_LEVEL_INFO, "LED: Error create %s bus failed %i err=%i", "SPI", gpio, pusher->Error());
|
||||||
default:
|
delete pusher;
|
||||||
break;
|
pusher = nullptr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
#endif // TASMOTALED_HARDWARE_SPI
|
||||||
return pusher;
|
return pusher;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -80,9 +80,11 @@ typedef struct TasmotaLED_Timing {
|
||||||
\*******************************************************************************************/
|
\*******************************************************************************************/
|
||||||
class TasmotaLEDPusher {
|
class TasmotaLEDPusher {
|
||||||
public:
|
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() {};
|
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) {
|
virtual bool Begin(uint16_t pixel_count, uint16_t pixel_size, const TasmotaLED_Timing * led_timing) {
|
||||||
_pixel_count = pixel_count;
|
_pixel_count = pixel_count;
|
||||||
_pixel_size = pixel_size;
|
_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
|
static TasmotaLEDPusher * Create(uint32_t hw, int8_t gpio); // create instance for the provided type, or nullptr if failed
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
bool _initialized; // did the hardware got correctly initialized
|
||||||
|
esp_err_t _err;
|
||||||
uint16_t _pixel_count;
|
uint16_t _pixel_count;
|
||||||
uint16_t _pixel_size;
|
uint16_t _pixel_size;
|
||||||
const TasmotaLED_Timing * _led_timing;
|
const TasmotaLED_Timing * _led_timing;
|
||||||
|
@ -110,7 +114,7 @@ protected:
|
||||||
#include "driver/rmt_tx.h"
|
#include "driver/rmt_tx.h"
|
||||||
class TasmotaLEDPusherRMT : public TasmotaLEDPusher {
|
class TasmotaLEDPusherRMT : public TasmotaLEDPusher {
|
||||||
public:
|
public:
|
||||||
TasmotaLEDPusherRMT(int8_t pin) : _pin(pin) {};
|
TasmotaLEDPusherRMT(int8_t pin);
|
||||||
~TasmotaLEDPusherRMT();
|
~TasmotaLEDPusherRMT();
|
||||||
|
|
||||||
bool Begin(uint16_t pixel_count, uint16_t pixel_size, const TasmotaLED_Timing * led_timing) override;
|
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 {
|
class TasmotaLEDPusherSPI : public TasmotaLEDPusher {
|
||||||
public:
|
public:
|
||||||
TasmotaLEDPusherSPI(int8_t pin) : _pin(pin), _spi_strip({}) {};
|
TasmotaLEDPusherSPI(int8_t pin);
|
||||||
~TasmotaLEDPusherSPI();
|
~TasmotaLEDPusherSPI();
|
||||||
|
|
||||||
bool Begin(uint16_t pixel_count, uint16_t pixel_size, const TasmotaLED_Timing * led_timing) override;
|
bool Begin(uint16_t pixel_count, uint16_t pixel_size, const TasmotaLED_Timing * led_timing) override;
|
||||||
|
@ -154,7 +158,8 @@ public:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
int8_t _pin;
|
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
|
#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) {
|
TasmotaLEDPusherRMT::TasmotaLEDPusherRMT(int8_t pin) : _pin(pin) {
|
||||||
TasmotaLEDPusher::Begin(pixel_count, pixel_size, led_timing);
|
|
||||||
|
|
||||||
esp_err_t ret = ESP_OK;
|
esp_err_t ret = ESP_OK;
|
||||||
rmt_tx_channel_config_t config = {};
|
rmt_tx_channel_config_t config = {};
|
||||||
config.clk_src = RMT_CLK_SRC_DEFAULT;
|
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.invert_out = false; // do not invert output signal
|
||||||
config.flags.with_dma = false; // do not need DMA backend
|
config.flags.with_dma = false; // do not need DMA backend
|
||||||
|
|
||||||
ret = rmt_new_tx_channel(&config, &_channel);
|
_err = rmt_new_tx_channel(&config, &_channel);
|
||||||
if (ret != ESP_OK) {
|
if (_err == ESP_OK) {
|
||||||
AddLog(LOG_LEVEL_INFO, "RMT: cannot initialize Gpio %i err=%i", _pin, ret);
|
_initialized = true;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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 = {
|
led_strip_encoder_config_t encoder_config = {
|
||||||
.resolution = RMT_LED_STRIP_RESOLUTION_HZ,
|
.resolution = RMT_LED_STRIP_RESOLUTION_HZ,
|
||||||
};
|
};
|
||||||
|
@ -198,13 +200,13 @@ bool TasmotaLEDPusherRMT::Begin(uint16_t pixel_count, uint16_t pixel_size, const
|
||||||
.level1 = 1,
|
.level1 = 1,
|
||||||
};
|
};
|
||||||
// AddLog(LOG_LEVEL_INFO, "RMT: RmtBit0 0x%08X RmtBit1 0x%08X RmtReset 0x%08X", RmtBit0.val, RmtBit1.val, RmtReset.val);
|
// 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);
|
_err = rmt_new_led_strip_encoder(&encoder_config, &_led_encoder, RmtBit0, RmtBit1, RmtReset);
|
||||||
if (ret != ESP_OK) {
|
if (_err != ESP_OK) {
|
||||||
// AddLog(LOG_LEVEL_INFO, "RMT: cannot initialize led strip encoder err=%i", ret);
|
// AddLog(LOG_LEVEL_INFO, "RMT: cannot initialize led strip encoder err=%i", ret);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
ret = rmt_enable(_channel);
|
_err = rmt_enable(_channel);
|
||||||
if (ret != ESP_OK) {
|
if (_err != ESP_OK) {
|
||||||
// AddLog(LOG_LEVEL_INFO, "RMT: cannot enable channel err=%i", ret);
|
// AddLog(LOG_LEVEL_INFO, "RMT: cannot enable channel err=%i", ret);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -212,7 +214,7 @@ bool TasmotaLEDPusherRMT::Begin(uint16_t pixel_count, uint16_t pixel_size, const
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TasmotaLEDPusherRMT::CanShow(void) {
|
bool TasmotaLEDPusherRMT::CanShow(void) {
|
||||||
if (_channel) {
|
if (_channel && _initialized) {
|
||||||
return (ESP_OK == rmt_tx_wait_all_done(_channel, 0));
|
return (ESP_OK == rmt_tx_wait_all_done(_channel, 0));
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
|
@ -220,6 +222,7 @@ bool TasmotaLEDPusherRMT::CanShow(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TasmotaLEDPusherRMT::Push(uint8_t *buf) {
|
bool TasmotaLEDPusherRMT::Push(uint8_t *buf) {
|
||||||
|
if (!_initialized) { return false; }
|
||||||
|
|
||||||
// wait for not actively sending data
|
// wait for not actively sending data
|
||||||
// this will time out at 1 second, an arbitrarily long period of time
|
// 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) {
|
TasmotaLEDPusherSPI::TasmotaLEDPusherSPI(int8_t pin) : _pin(pin) {
|
||||||
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;
|
|
||||||
spi_host_device_t spi_host = SPI2_HOST;
|
spi_host_device_t spi_host = SPI2_HOST;
|
||||||
bool with_dma = true; /// TODO: pass value or compute based on pixelcount
|
spi_bus_config_t spi_bus_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_bus_cfg = {
|
|
||||||
.mosi_io_num = _pin,
|
.mosi_io_num = _pin,
|
||||||
//Only use MOSI to generate the signal, set -1 when other pins are not used.
|
//Only use MOSI to generate the signal, set -1 when other pins are not used.
|
||||||
.miso_io_num = -1,
|
.miso_io_num = -1,
|
||||||
|
@ -128,32 +106,55 @@ bool TasmotaLEDPusherSPI::Begin(uint16_t pixel_count, uint16_t pixel_size, const
|
||||||
.quadhd_io_num = -1,
|
.quadhd_io_num = -1,
|
||||||
.max_transfer_sz = _pixel_count * _pixel_size * SPI_BYTES_PER_COLOR_BYTE,
|
.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);
|
_err = spi_bus_initialize(spi_host, &spi_bus_cfg, _with_dma ? SPI_DMA_CH_AUTO : SPI_DMA_DISABLED);
|
||||||
if (err != ESP_OK) {
|
if (_err == ESP_OK) {
|
||||||
AddLog(LOG_LEVEL_INFO, PSTR("LED: Error create SPI bus failed"));
|
_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;
|
goto err;
|
||||||
}
|
}
|
||||||
_spi_strip.spi_host = spi_host; // confirmed working, so keep it's value to free it later
|
|
||||||
|
|
||||||
spi_dev_cfg = {
|
spi_dev_cfg = {
|
||||||
.command_bits = 0,
|
.command_bits = 0,
|
||||||
.address_bits = 0,
|
.address_bits = 0,
|
||||||
.dummy_bits = 0,
|
.dummy_bits = 0,
|
||||||
.mode = 0,
|
.mode = 0,
|
||||||
//set -1 when CS is not used
|
//set -1 when CS is not used
|
||||||
.clock_source = SPI_CLK_SRC_DEFAULT, // clk_src,
|
.clock_source = SPI_CLK_SRC_DEFAULT, // clk_src,
|
||||||
.clock_speed_hz = LED_STRIP_SPI_DEFAULT_RESOLUTION,
|
.clock_speed_hz = LED_STRIP_SPI_DEFAULT_RESOLUTION,
|
||||||
.spics_io_num = -1,
|
.spics_io_num = -1,
|
||||||
.queue_size = LED_STRIP_SPI_DEFAULT_TRANS_QUEUE_SIZE,
|
.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);
|
_err = spi_bus_add_device(_spi_strip.spi_host, &spi_dev_cfg, &_spi_strip.spi_device);
|
||||||
if (err != ESP_OK) {
|
if (_err != ESP_OK) {
|
||||||
// AddLog(LOG_LEVEL_INFO, "LED: Error failed to add spi device");
|
// AddLog(LOG_LEVEL_INFO, "LED: Error failed to add spi device");
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
spi_device_get_actual_freq(_spi_strip.spi_device, &clock_resolution_khz);
|
_err = spi_device_get_actual_freq(_spi_strip.spi_device, &clock_resolution_khz);
|
||||||
if (err != ESP_OK) {
|
if (_err != ESP_OK) {
|
||||||
// AddLog(LOG_LEVEL_INFO, "LED: Error failed to get spi frequency");
|
// AddLog(LOG_LEVEL_INFO, "LED: Error failed to get spi frequency");
|
||||||
goto err;
|
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);
|
// AddLog(LOG_LEVEL_INFO, "LED: Error unsupported clock resolution: %dKHz", clock_resolution_khz);
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
err:
|
err:
|
||||||
if (_spi_strip.spi_device) {
|
if (_spi_strip.spi_device) {
|
||||||
|
@ -172,15 +172,16 @@ err:
|
||||||
if (_spi_strip.spi_host) {
|
if (_spi_strip.spi_host) {
|
||||||
spi_bus_free(_spi_strip.spi_host);
|
spi_bus_free(_spi_strip.spi_host);
|
||||||
}
|
}
|
||||||
|
_initialized = false;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TasmotaLEDPusherSPI::CanShow(void) {
|
bool TasmotaLEDPusherSPI::CanShow(void) {
|
||||||
return true; // TODO
|
return _initialized; // TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TasmotaLEDPusherSPI::Push(uint8_t *buf) {
|
bool TasmotaLEDPusherSPI::Push(uint8_t *buf) {
|
||||||
|
if (!_initialized) { return false; }
|
||||||
if (CanShow()) {
|
if (CanShow()) {
|
||||||
led_strip_transmit_buffer(&_spi_strip, buf);
|
led_strip_transmit_buffer(&_spi_strip, buf);
|
||||||
}
|
}
|
||||||
|
|
|
@ -95,20 +95,8 @@ const uint16_t kTasLed_PixelWhite = TasmotaLed_xxxW;
|
||||||
|
|
||||||
const uint16_t kTasLed_Type = kTasLed_PixelSize | kTasLed_PixelOrder | kTasLed_PixelWhite | kTasLed_Timing;
|
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
|
// select hardware acceleration - bitbanging is not supported on ESP32 due to interference of interrupts - use default
|
||||||
#if CONFIG_IDF_TARGET_ESP32C2
|
const uint32_t kTasLed_Hardware = TasmotaLed_HW_Default; // use whatever is available
|
||||||
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
|
|
||||||
|
|
||||||
#if (USE_WS2812_HARDWARE == NEO_HW_P9813)
|
#if (USE_WS2812_HARDWARE == NEO_HW_P9813)
|
||||||
#error "P9813 is not supported by this library"
|
#error "P9813 is not supported by this library"
|
||||||
|
|
Loading…
Reference in New Issue