Skip to content

Commit

Permalink
Merge branch 'arendst:development' into IDF55
Browse files Browse the repository at this point in the history
  • Loading branch information
Jason2866 authored Jan 24, 2025
2 parents 27ca545 + beb967c commit 6b878ac
Show file tree
Hide file tree
Showing 10 changed files with 116 additions and 30 deletions.
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ All notable changes to this project will be documented in this file.
- I2S command I2sLoop (#22807)
- Berry `serial.read()` read only `n` bytes (#22835)
- Display template for Waveshare ESP32-C6 LCD 1.47 (#22863)
- Berry `tasmota.global.tele_period` and `tasmota.settings.tele_period`
- Berry `tasmota.global.tele_period` and `tasmota.settings.tele_period` (#22865)
- Command `PixelType` to change the WS2812 color order and channel number

### Breaking Changed

Expand All @@ -20,6 +21,7 @@ All notable changes to this project will be documented in this file.
- Allow negative values for AdcParam/AdcGpio INPUT, TEMP and RANGE parameters (#22809)
- GPIOViewer from v1.5.9 to v1.6.0 (No functional change)
- ESP32 Platform from 2025.01.30 to 2025.01.31 (#22832)
- Berry `gpio.pin_mode` frees PWM on pin

### Fixed
- Sonoff SPM `PowerOnState` overrules `SSPMPowerOnState` in mixed 4Relay setup with 4Relay version 1.0.0
Expand Down
2 changes: 2 additions & 0 deletions RELEASENOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasm
- Berry add `bytes().appendhex()` [#22767](https://github.com/arendst/Tasmota/issues/22767)
- Berry WS2812 real-time Leds panel as app [#22788](https://github.com/arendst/Tasmota/issues/22788)
- Berry `serial.read()` read only `n` bytes [#22835](https://github.com/arendst/Tasmota/issues/22835)
- Berry `tasmota.global.tele_period` and `tasmota.settings.tele_period` [#22865](https://github.com/arendst/Tasmota/issues/22865)

### Breaking Changed

Expand All @@ -147,6 +148,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasm
- Allow negative values for AdcParam/AdcGpio INPUT, TEMP and RANGE parameters [#22809](https://github.com/arendst/Tasmota/issues/22809)
- Command `Pixels` has backwards compatible arguments fixing #22755 [#22791](https://github.com/arendst/Tasmota/issues/22791)
- ESP32 disable PSRAM check (and on restart some relay toggles) with `#define DISABLE_PSRAMCHECK true` [#21266](https://github.com/arendst/Tasmota/issues/21266)
- Berry `gpio.pin_mode` frees PWM on pin
- Berry bit-shift operators to `int64` [#22709](https://github.com/arendst/Tasmota/issues/22709)
- HASPmota use 'roboto.ttf' for automatic sizing of default font [#22697](https://github.com/arendst/Tasmota/issues/22697)
- HASPmota add 'tag' attribute for free-form JSON [#22698](https://github.com/arendst/Tasmota/issues/22698)
Expand Down
31 changes: 21 additions & 10 deletions lib/lib_basic/TasmotaLED/src/TasmotaLED.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,15 @@
#include "TasmotaLED.h"

// DRAM_ATTR to force in IRAM because we use this in show loop
static const DRAM_ATTR uint8_t TASMOTALED_CHANNEL_ORDERS[6][3] = {
{1, 0, 2}, // GRB (0)
{2, 0, 1}, // GBR (1)
static const DRAM_ATTR uint8_t TASMOTALED_CHANNEL_ORDERS[8][3] = {
{1, 0, 2}, // Def=GRB (0)
{1, 0, 2}, // GRB (1)
{0, 1, 2}, // RGB (2)
{0, 2, 1}, // RBG (3)
{2, 1, 0}, // BRG (4)
{1, 2, 0} // BGR (5)
{1, 2, 0}, // BGR (5)
{2, 0, 1}, // GBR (6)
{1, 0, 2} // GRB (7) // fallback if erroneous value
};

static const TasmotaLED_Timing TasmotaLED_Timings[] = {
Expand Down Expand Up @@ -61,28 +63,24 @@ 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_order((type >> 4) & 0x07),
_w_before(type & 0x08),
_timing((type >> 8) & 0xFF),
_started(false),
_dirty(true),
_raw_format(false),
_pixel_count(num_leds),
_buf_work(nullptr),
_buf_show(nullptr),
_pixel_matrix(&TASMOTALED_CHANNEL_ORDERS[0]),
_pusher(nullptr)
{
_adjustSubType(); // compute values for _pixel_order, _w_before, _pixel_matrix
if (_timing > (TasmotaLed_TimingEnd >> 8)) {
_timing = 0;
}
switch (_type & 0x0F) {
// case TasmotaLed_1_W:
// _pixel_size = 1;
// break;
case TasmotaLed_4_WRGB:
_pixel_size = 4;
break;
case TasmotaLed_1_Def:
case TasmotaLed_3_RGB:
default: // fallback
_pixel_size = 3;
Expand All @@ -109,6 +107,13 @@ TasmotaLED::~TasmotaLED() {
_buf_show = nullptr;
}

// Adjust all internal parameters accouring to sub-type
void TasmotaLED::_adjustSubType(void) {
_pixel_order = (_type >> 4) & 0x07;
_pixel_matrix = &TASMOTALED_CHANNEL_ORDERS[_pixel_order];
_w_before = _type & 0x08;
}

void TasmotaLED::SetPixelCount(uint16_t num_leds) {
if (num_leds != _pixel_count) {
_pixel_count = num_leds;
Expand All @@ -124,6 +129,12 @@ void TasmotaLED::SetPixelCount(uint16_t num_leds) {
}
}

void TasmotaLED::SetPixelSubType(uint8_t subtype) {
// subtype is only the 8 lower bits of _type
_type = (_type & 0xFF00) | (subtype & 0xFF);
_adjustSubType();
}


// Color is passed as 0xWWRRGGBB and copied as WWRRGGBB in _buf_work
void TasmotaLED::ClearTo(uint32_t wrgb, int32_t first, int32_t last) {
Expand Down
13 changes: 8 additions & 5 deletions lib/lib_basic/TasmotaLED/src/TasmotaLED.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,17 @@

enum TasmotaLEDTypesEncoding : uint16_t {
// bits 0..3 encode for number of bytes per pixel
TasmotaLed_1_W = 0x0, // 1 byte per pixel (not used yet)
TasmotaLed_3_RGB = 0x1, // 3 bytes per pixel
TasmotaLed_4_WRGB = 0x2, // 4 bytes per pixel
TasmotaLed_1_Def = 0x0, // Default value - identical to TasmotaLed_3_RGB
TasmotaLed_3_RGB = 0x1, // 3 bytes per pixel
TasmotaLed_4_WRGB = 0x2, // 4 bytes per pixel
// bits 4..6 encode for pixel order
TasmotaLed_GRB = 0b000 << 4,
TasmotaLed_GBR = 0b001 << 4,
TasmotaLed_Def = 0b000 << 4, // Default value - identical to TasmotaLed_GRB
TasmotaLed_GRB = 0b001 << 4,
TasmotaLed_RGB = 0b010 << 4,
TasmotaLed_RBG = 0b011 << 4,
TasmotaLed_BRG = 0b100 << 4,
TasmotaLed_BGR = 0b101 << 4,
TasmotaLed_GBR = 0b110 << 4,
// bit 7 sets the position for W channel
TasmotaLed_xxxW = 0b0 << 7, // W channel after color
TasmotaLed_Wxxx = 0b1 << 7, // W channel before color
Expand Down Expand Up @@ -92,6 +93,8 @@ class TasmotaLED {
~TasmotaLED();

void SetPixelCount(uint16_t num_leds);
void SetPixelSubType(uint8_t type); // change only Pixel order and pixel size
void _adjustSubType(void);

bool Begin(void);
void SetPusher(TasmotaLEDPusher *pusher); // needs to be called before `Begin()`, sets the hardware implementation
Expand Down
17 changes: 11 additions & 6 deletions lib/libesp32/ESP32-to-ESP8266-compat/src/esp8266toEsp32.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -326,15 +326,20 @@ int32_t analogAttach(uint32_t pin, bool output_invert) { // returns ledc chan
return chan;
}

void analogDetachAll(void) {
for (uint32_t pin = 0; pin < SOC_GPIO_PIN_COUNT; pin++) {
if (pin_to_channel[pin] > 0) {
void analogDetach(uint32_t pin) {
if (pin_to_channel[pin] > 0) {
#if ESP_IDF_VERSION_MAJOR < 5
ledcDetachPin(pin);
ledcDetachPin(pin);
#else
ledcDetach(pin);
ledcDetach(pin);
#endif
}
pin_to_channel[pin] = 0;
}
}

void analogDetachAll(void) {
for (uint32_t pin = 0; pin < SOC_GPIO_PIN_COUNT; pin++) {
analogDetach(pin);
}
}

Expand Down
5 changes: 5 additions & 0 deletions lib/libesp32/ESP32-to-ESP8266-compat/src/esp8266toEsp32.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,11 @@ uint8_t ledcReadResolution(uint8_t chan);
// Returns: hardware channel number, or -1 if it failed
int32_t analogAttach(uint32_t pin, bool output_invert = false); // returns the ledc channel, or -1 if failed. This is implicitly called by analogWrite if the channel was not already allocated

//
// analogDetach - detach attached GPIO from a hardware PWM
//
void analogDetach(uint32_t pin);

//
// analogDetachAll - detach all attached GPIOs from a hardware PWM
//
Expand Down
1 change: 1 addition & 0 deletions tasmota/include/i18n.h
Original file line number Diff line number Diff line change
Expand Up @@ -532,6 +532,7 @@
#define D_CMND_PALETTE "Palette"
#define D_CMND_PIXELS "Pixels"
#define D_CMND_STEPPIXELS "StepPixels"
#define D_CMND_PIXELTYPE "PixelType"
#define D_CMND_ARTNET "ArtNet"
#define D_CMND_ARTNET_CONFIG "ArtNetConfig"
#define D_SO_ARTNET_AUTORUN "ArtNetAutorun"
Expand Down
8 changes: 3 additions & 5 deletions tasmota/include/tasmota_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -242,11 +242,9 @@ typedef union {
uint32_t data; // Allow bit manipulation
struct {
uint32_t log_file_idx : 4; // bit 0.3 (v14.4.1.2) - FileLog log rotate index
uint32_t spare04 : 1; // bit 4
uint32_t spare05 : 1; // bit 5
uint32_t spare06 : 1; // bit 6
uint32_t spare07 : 1; // bit 7
uint32_t spare08 : 1; // bit 8
uint32_t light_pixels_order : 3; // bit 4.6 (v14.4.1.3) - LED light order <Compile>/GRB/RGB/RBG/BRG/BGR/GBR, high bit indicates W before (for RGBW)
uint32_t light_pixels_rgbw : 1; // bit 7 (v14.4.1.3) - LED true is 4 channels RGBW, false is 3 channels RGB
uint32_t light_pixels_w_first : 1; // bit 8 (v14.4.1.3) - LED true if W channel comes first, default is <RGB>W
uint32_t spare09 : 1; // bit 9
uint32_t spare10 : 1; // bit 10
uint32_t spare11 : 1; // bit 11
Expand Down
1 change: 1 addition & 0 deletions tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_gpio.ino
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ extern "C" {
if (pin >= 0) {
if (mode > 0) {
// standard ESP mode
analogDetach(pin);
pinMode(pin, mode);
} else {
// synthetic mode
Expand Down
64 changes: 61 additions & 3 deletions tasmota/tasmota_xlgt_light/xlgt_01_ws2812_esp32.ino
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,10 @@
const uint8_t WS2812_SCHEMES = 10; // Number of WS2812 schemes

const char kWs2812Commands[] PROGMEM = "|" // No prefix
D_CMND_LED "|" D_CMND_PIXELS "|" D_CMND_ROTATION "|" D_CMND_WIDTH "|" D_CMND_STEPPIXELS ;
D_CMND_LED "|" D_CMND_PIXELS "|" D_CMND_ROTATION "|" D_CMND_WIDTH "|" D_CMND_STEPPIXELS "|" D_CMND_PIXELTYPE ;

void (* const Ws2812Command[])(void) PROGMEM = {
&CmndLed, &CmndPixels, &CmndRotation, &CmndWidth, &CmndStepPixels };
&CmndLed, &CmndPixels, &CmndRotation, &CmndWidth, &CmndStepPixels, &CmndPixelType };

#include <TasmotaLED.h>

Expand Down Expand Up @@ -610,6 +610,17 @@ void Ws2812ShowScheme(void)
}
}

// convert the Settings to a Led type compatible with TasmotaLED
uint16_t Ws2812SettingsToLedType(void) {
uint16_t led_type = kTasLed_Type; // default value from compile options
if (Settings->mbflag2.light_pixels_order != 0) {
led_type = (led_type & 0xFF00) | (Settings->mbflag2.light_pixels_order << 4)
| (Settings->mbflag2.light_pixels_w_first ? TasmotaLed_Wxxx : 0)
| (Settings->mbflag2.light_pixels_rgbw ? TasmotaLed_4_WRGB : TasmotaLed_3_RGB);
}
return led_type;
}

bool Ws2812InitStrip(void)
{
if (strip != nullptr) {
Expand All @@ -623,7 +634,8 @@ bool Ws2812InitStrip(void)
AddLog(LOG_LEVEL_ERROR, "LED: No hardware supported");
return false;
}
strip = new TasmotaLED(kTasLed_Type, Settings->light_pixels);
uint16_t led_type = Ws2812SettingsToLedType();
strip = new TasmotaLED(led_type, Settings->light_pixels);
strip->SetPusher(pusher);
strip->Begin();

Expand All @@ -643,6 +655,21 @@ bool Ws2812ChangePixelCount(void)
return true;
}

bool Ws2812ChangePixelType(bool clear)
{
if (strip == nullptr) {
return true;
}
uint16_t led_type = Ws2812SettingsToLedType();
strip->SetPixelSubType(led_type & 0xFF); // just submit the lower part
if (clear) {
Ws2812Clear();
} else {
Ws2812LibStripShow();
}
return true;
}

void Ws2812ModuleSelected(void)
{
if (Ws2812InitStrip()) {
Expand Down Expand Up @@ -809,6 +836,37 @@ void CmndPixels(void)
Settings->light_pixels, Settings->light_pixels_reverse, Settings->light_pixels_height_1 + 1, Settings->light_pixels_alternate);
}

void CmndPixelType(void)
{
if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload < 32)) {
// Value is:
// 0 = use compile-time option (default value)
// 1..6 = Pixel Order: 1=GRB 2=RGB 3=RBG 4=BRG 5=BGR 6=GBR
// Modifiers:
// +8 = 4 channels RGBW strip - default is 3 channels RGB
// +16 = W channel is sent first - default W channel is sent last
uint32_t pixels_order = XdrvMailbox.payload & 0x07;
uint32_t pixels_w_first = (XdrvMailbox.payload & 0x08) ? 1 : 0;
uint32_t pixels_rgbw = (XdrvMailbox.payload & 0x10) ? 1 : 0;
// changing number of channels requires a reboot
bool reboot = pixels_rgbw != Settings->mbflag2.light_pixels_rgbw;
if (reboot) {
TasmotaGlobal.restart_flag = 2; // force restart if number of channels changed
}

Settings->mbflag2.light_pixels_order = pixels_order;
Settings->mbflag2.light_pixels_w_first = pixels_w_first;
Settings->mbflag2.light_pixels_rgbw = (XdrvMailbox.payload & 0x10) ? 1 : 0;
Ws2812ChangePixelType(reboot);
}
uint32_t pixel_type = 0;
if (Settings->mbflag2.light_pixels_order != 0) {
pixel_type = Settings->mbflag2.light_pixels_order | (Settings->mbflag2.light_pixels_w_first ? 0x08 : 0)
| (Settings->mbflag2.light_pixels_rgbw ? 0x10 : 0);
}
ResponseCmndNumber(pixel_type);
}

void CmndStepPixels(void)
{
if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 255)) {
Expand Down

0 comments on commit 6b878ac

Please sign in to comment.