Initial ESP32-S31 support (#25130)

* ESP32-S31 support (#588)

* Arduino IDF 6.1 based framework only for S31

* code review changes Thei for tasmota_types.h
This commit is contained in:
Jason2866 authored and GitHub committed 2026-10-10 17:50:13 +02:00
1 parent d9f4450293
commit c6b19bb70c
52 files changed
+1172 -346

No files matched your search

+17 -7
View File
@@ -21,6 +21,9 @@
#include <Arduino.h>
#include <IPAddress.h>
#include <SBuffer.hpp>
#ifdef ESP32
#include "esp_memory_utils.h"
#endif // ESP32
/*********************************************************************************************\
* va_list extended support
@@ -255,7 +258,14 @@ char * copyStr(const char * str) {
}
const char ext_invalid_mem[] PROGMEM = "<--INVALID-->";
const uint32_t min_valid_ptr = 0x3F000000; // addresses below this line are invalid
static bool ext_ptr_is_readable(uint32_t ptr) {
#ifdef ESP32
return esp_ptr_byte_accessible((const void *)(uintptr_t)ptr);
#else // ESP32
return ptr >= 0x3F000000;
#endif // ESP32
}
int32_t ext_vsnprintf_P(char * out_buf, size_t buf_len, const char * fmt_P, va_list va) {
va_list va_cpy;
@@ -315,7 +325,7 @@ int32_t ext_vsnprintf_P(char * out_buf, size_t buf_len, const char * fmt_P, va_l
case 'H': // Hex, decimals indicates the length, default 2
{
if (decimals < 0) { decimals = 0; }
if (cur_val < min_valid_ptr) { new_val_str = ext_invalid_mem; }
if (!ext_ptr_is_readable(cur_val)) { new_val_str = ext_invalid_mem; }
else if (decimals > 0) {
char * hex_char = (char*) malloc(decimals*2 + 2);
if (hex_char == nullptr) { goto free_allocs; }
@@ -329,7 +339,7 @@ int32_t ext_vsnprintf_P(char * out_buf, size_t buf_len, const char * fmt_P, va_l
case 'B': // Pointer to SBuffer
{
if (cur_val < min_valid_ptr) { new_val_str = ext_invalid_mem; }
if (!ext_ptr_is_readable(cur_val)) { new_val_str = ext_invalid_mem; }
else {
const SBuffer & buf = *(const SBuffer*)cur_val;
size_t buf_len = (&buf != nullptr) ? buf.len() : 0;
@@ -358,7 +368,7 @@ int32_t ext_vsnprintf_P(char * out_buf, size_t buf_len, const char * fmt_P, va_l
case 'V': // 2-byte values, decimals indicates the length, default 2
{
if (decimals < 0) { decimals = 0; }
if (cur_val < min_valid_ptr) { new_val_str = ext_invalid_mem; }
if (!ext_ptr_is_readable(cur_val)) { new_val_str = ext_invalid_mem; }
else if (decimals > 0) {
uint32_t val_size = decimals*6 + 2;
char * val_char = (char*) malloc(val_size);
@@ -402,7 +412,7 @@ int32_t ext_vsnprintf_P(char * out_buf, size_t buf_len, const char * fmt_P, va_l
// Note: float MUST be passed by address, because C alsays promoted float to double when in vararg
case 'f': // input is `float`, printed to float with 2 decimals
{
if (cur_val < min_valid_ptr) { new_val_str = ext_invalid_mem; }
if (!ext_ptr_is_readable(cur_val)) { new_val_str = ext_invalid_mem; }
else {
bool truncate = false;
if (decimals < 0) {
@@ -438,7 +448,7 @@ int32_t ext_vsnprintf_P(char * out_buf, size_t buf_len, const char * fmt_P, va_l
// '%_X' outputs a 64 bits unsigned int to uppercase HEX with 16 digits
case 'X': // input is `uint64_t*`, printed as 16 hex digits (no prefix 0x)
{
if (cur_val < min_valid_ptr) { new_val_str = ext_invalid_mem; }
if (!ext_ptr_is_readable(cur_val)) { new_val_str = ext_invalid_mem; }
else {
if ((decimals < 0) || (decimals > 16)) { decimals = 16; }
U64toHex(*(uint64_t*)cur_val, hex, decimals);
@@ -452,7 +462,7 @@ int32_t ext_vsnprintf_P(char * out_buf, size_t buf_len, const char * fmt_P, va_l
// '%_U' outputs a 64 bits unsigned int to decimal
case 'U': // input is `uint64_t*`, printed as decimal
{
if (cur_val < min_valid_ptr) { new_val_str = ext_invalid_mem; }
if (!ext_ptr_is_readable(cur_val)) { new_val_str = ext_invalid_mem; }
else {
U64toStr(*(uint64_t*)cur_val, hex);
new_val_str = copyStr(hex);
@@ -212,7 +212,12 @@ bool WiFiHelper::setPhyMode(WiFiPhyMode_t mode) {
Thus you are more likely to experience disturbances.
The response speed and stability is better at HT20 for ESP units.
*/
// IDF < 6: WIFI_BW_HT20 / IDF >= 6: renamed to WIFI_BW20
#if ESP_IDF_VERSION_MAJOR < 6
esp_wifi_set_bandwidth(WIFI_IF_STA, WIFI_BW_HT20);
#else
esp_wifi_set_bandwidth(WIFI_IF_STA, WIFI_BW20);
#endif
/*
ESPEasy:
Set to use "Long GI" making it more resilliant to reflections
@@ -405,13 +410,13 @@ int WiFiHelper::hostByName(const char* aHostname, IPAddress& aResult)
String WiFiHelper::macAddress(void) {
uint8_t mac[6] = {0,0,0,0,0,0};
char macStr[18] = { 0 };
#ifdef CONFIG_SOC_HAS_WIFI
#if defined(SOC_WIFI_SUPPORTED) || defined(CONFIG_SOC_HAS_WIFI)
esp_read_mac(mac, ESP_MAC_WIFI_STA); // Local WiFi station MAC address
#elif CONFIG_ESP_WIFI_REMOTE_ENABLED
WiFi.macAddress(mac); // Remote WiFi station MAC address (devices without WiFi but hostedMCU)
#else // No CONFIG_SOC_HAS_WIFI
#else // defined(SOC_WIFI_SUPPORTED) || defined(CONFIG_SOC_HAS_WIFI)
esp_read_mac(mac, ESP_MAC_BASE); // Local hardware base MAC address
#endif // CONFIG_SOC_HAS_WIFI
#endif // defined(SOC_WIFI_SUPPORTED) || defined(CONFIG_SOC_HAS_WIFI)
snprintf(macStr, sizeof(macStr), "%02X:%02X:%02X:%02X:%02X:%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
return String(macStr);
}
+1 -1
View File
@@ -64,7 +64,7 @@ int GetBufferLength(){return bufferpos;};
void Init();
int Parser1();
void Parser2();
int SAMMain();
int SAMMain( void (*cb)(void *, unsigned char), void *cbdata );
void CopyStress();
void SetPhonemeLength();
void AdjustLengths();
+6 -10
View File
@@ -10,6 +10,7 @@
#include "l3loop.h"
#include "bitstream.h"
#include "l3bitstream.h"
#include "esp_cpu.h"
#include "esp_heap_caps.h"
#include "esp_system.h"
#include "freertos/FreeRTOS.h"
@@ -226,8 +227,7 @@ Counters 2664123380 : 2664123448 : 2666717886 : 2668665908 : 2668859025
static unsigned char *shine_encode_buffer_internal(shine_global_config *config, int *written, int stride) {
counter[0] = portGET_RUN_TIME_COUNTER_VALUE(); // TASMOTA more portable solution
// counter[0] = xthal_get_ccount();
counter[0] = (uint32_t)esp_cpu_get_cycle_count();
if(config->mpeg.frac_slots_per_frame) {
config->mpeg.padding = (config->mpeg.slot_lag <= (config->mpeg.frac_slots_per_frame - 1.0));
config->mpeg.slot_lag += (config->mpeg.padding - config->mpeg.frac_slots_per_frame);
@@ -235,22 +235,18 @@ static unsigned char *shine_encode_buffer_internal(shine_global_config *config,
config->mpeg.bits_per_frame = 8*(config->mpeg.whole_slots_per_frame + config->mpeg.padding);
config->mean_bits = (config->mpeg.bits_per_frame - config->sideinfo_len)/config->mpeg.granules_per_frame;
counter[1] = portGET_RUN_TIME_COUNTER_VALUE(); // TASMOTA more portable solution
// counter[1] = xthal_get_ccount();
counter[1] = (uint32_t)esp_cpu_get_cycle_count();
/* apply mdct to the polyphase output */
// put on core 1
shine_mdct_sub(config, stride);
counter[2] = portGET_RUN_TIME_COUNTER_VALUE(); // TASMOTA more portable solution
// counter[2] = xthal_get_ccount();
counter[2] = (uint32_t)esp_cpu_get_cycle_count();
/* bit and noise allocation */
//put on core 0
shine_iteration_loop(config);
counter[3] = portGET_RUN_TIME_COUNTER_VALUE(); // TASMOTA more portable solution
// counter[3] = xthal_get_ccount();
counter[3] = (uint32_t)esp_cpu_get_cycle_count();
/* write the frame to the bitstream */
shine_format_bitstream(config);
counter[4] = portGET_RUN_TIME_COUNTER_VALUE(); // TASMOTA more portable solution
// counter[4] = xthal_get_ccount();
counter[4] = (uint32_t)esp_cpu_get_cycle_count();
/* Return data. */
*written = config->bs.data_position;
config->bs.data_position = 0;
@@ -32,6 +32,9 @@ License along with NeoPixel. If not, see
#if !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32C2) && !defined(CONFIG_IDF_TARGET_ESP32C5) && !defined(CONFIG_IDF_TARGET_ESP32C6)
#if !defined(ARDUINO_ARCH_ESP8266)
#include "soc/gpio_periph.h"
#if __has_include("soc/gpio_struct.h")
#include "soc/gpio_struct.h"
#endif
#endif
static inline uint32_t getCycleCount(void)
@@ -25,6 +25,12 @@
#if TASMOTALED_HARDWARE_RMT
#include <rom/gpio.h>
#include <esp_check.h>
#include "esp_idf_version.h"
#if ESP_IDF_VERSION_MAJOR >= 6
// IDF 6.x: gpio_matrix_out() renamed to gpio_matrix_output() in esp_private/gpio.h
#include <esp_private/gpio.h>
#define gpio_matrix_out(gpio, signal, out_inv, oen_inv) gpio_matrix_output((gpio_num_t)(gpio), signal, out_inv, oen_inv)
#endif
//**************************************************************************************************************
// enable AddLog support within a C++ library
@@ -24,6 +24,12 @@
#if TASMOTALED_HARDWARE_SPI
#include <rom/gpio.h>
#include "esp_idf_version.h"
#if ESP_IDF_VERSION_MAJOR >= 6
// IDF 6.x: gpio_matrix_out() renamed to gpio_matrix_output() in esp_private/gpio.h
#include <esp_private/gpio.h>
#define gpio_matrix_out(gpio, signal, out_inv, oen_inv) gpio_matrix_output((gpio_num_t)(gpio), signal, out_inv, oen_inv)
#endif
//**************************************************************************************************************
// enable AddLog support within a C++ library
@@ -226,6 +226,10 @@ bool directRead(IO_REG_TYPE mask)
#if ESP_IDF_VERSION_MAJOR >= 5
#include "soc/gpio_periph.h"
#endif // ESP_IDF_VERSION_MAJOR >= 5
#if __has_include("soc/gpio_struct.h")
// IDF 6.x: GPIO register struct no longer exported via gpio_periph.h
#include "soc/gpio_struct.h"
#endif
#define PIN_TO_BASEREG(pin) (0)
#define PIN_TO_BITMASK(pin) (pin)
#define IO_REG_TYPE uint32_t
@@ -237,6 +241,11 @@ IO_REG_TYPE directRead(IO_REG_TYPE pin)
{
#if SOC_GPIO_PIN_COUNT <= 32 || CONFIG_IDF_TARGET_ESP32P4
return (GPIO.in.val >> pin) & 0x1;
#elif CONFIG_IDF_TARGET_ESP32S31
if ( pin < 32 )
return (GPIO.in.val >> pin) & 0x1;
else
return (GPIO.in1.val >> (pin - 32)) & 0x1;
#else // ESP32 with over 32 gpios
if ( pin < 32 )
return (GPIO.in >> pin) & 0x1;
@@ -252,6 +261,11 @@ void directWriteLow(IO_REG_TYPE pin)
{
#if SOC_GPIO_PIN_COUNT <= 32 || CONFIG_IDF_TARGET_ESP32P4
GPIO.out_w1tc.val = ((uint32_t)1 << pin);
#elif CONFIG_IDF_TARGET_ESP32S31
if ( pin < 32 )
GPIO.out_w1tc.val = ((uint32_t)1 << pin);
else
GPIO.out1_w1tc.val = ((uint32_t)1 << (pin - 32));
#else // ESP32 with over 32 gpios
if ( pin < 32 )
GPIO.out_w1tc = ((uint32_t)1 << pin);
@@ -265,6 +279,11 @@ void directWriteHigh(IO_REG_TYPE pin)
{
#if SOC_GPIO_PIN_COUNT <= 32 || CONFIG_IDF_TARGET_ESP32P4
GPIO.out_w1ts.val = ((uint32_t)1 << pin);
#elif CONFIG_IDF_TARGET_ESP32S31
if ( pin < 32 )
GPIO.out_w1ts.val = ((uint32_t)1 << pin);
else
GPIO.out1_w1ts.val = ((uint32_t)1 << (pin - 32));
#else // ESP32 with over 32 gpios
if ( pin < 32 )
GPIO.out_w1ts = ((uint32_t)1 << pin);
@@ -282,6 +301,11 @@ void directModeInput(IO_REG_TYPE pin)
// Input
#if SOC_GPIO_PIN_COUNT <= 32 || CONFIG_IDF_TARGET_ESP32P4
GPIO.enable_w1tc.val = ((uint32_t)1 << (pin));
#elif CONFIG_IDF_TARGET_ESP32S31
if ( pin < 32 )
GPIO.enable_w1tc.val = ((uint32_t)1 << pin);
else
GPIO.enable1_w1tc.val = ((uint32_t)1 << (pin - 32));
#else // ESP32 with over 32 gpios
if ( pin < 32 )
GPIO.enable_w1tc = ((uint32_t)1 << pin);
@@ -300,6 +324,11 @@ void directModeOutput(IO_REG_TYPE pin)
// Output
#if SOC_GPIO_PIN_COUNT <= 32 || CONFIG_IDF_TARGET_ESP32P4
GPIO.enable_w1ts.val = ((uint32_t)1 << (pin));
#elif CONFIG_IDF_TARGET_ESP32S31
if ( pin < 32 )
GPIO.enable_w1ts.val = ((uint32_t)1 << pin);
else
GPIO.enable1_w1ts.val = ((uint32_t)1 << (pin - 32));
#else // ESP32 with over 32 gpios
if ( pin < 32 )
GPIO.enable_w1ts = ((uint32_t)1 << pin);
@@ -29,6 +29,10 @@
#define USE_ESP32_S3
#endif
#include "soc/gpio_periph.h"
#if __has_include("soc/gpio_struct.h")
// IDF 6.x: GPIO register struct no longer exported via gpio_periph.h
#include "soc/gpio_struct.h"
#endif
#include <rom/gpio.h>
// #include "driver/spi_master.h"
#endif
@@ -10,6 +10,10 @@
#include "esp32-hal-spi.h"
#include "driver/spi_master.h"
#include "soc/gpio_periph.h"
#if __has_include("soc/gpio_struct.h")
// IDF 6.x: GPIO register struct no longer exported via gpio_periph.h
#include "soc/gpio_struct.h"
#endif
#endif
#ifndef ESP32
@@ -4,7 +4,7 @@
#pragma once
#if CONFIG_IDF_TARGET_ESP32P4
#if CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32S31
#include "esp_cache.h"
#define CACHE_WRITEBACK_ADDR(addr, size) esp_cache_msync((void*)addr, size, ESP_CACHE_MSYNC_FLAG_DIR_C2M)
#else
+15
View File
@@ -313,10 +313,18 @@ uDisplay::uDisplay(char *lp) : Renderer(800, 600) {
// Parse data pins directly into RGB config
// Note: byte order may be swapped later based on lvgl_param.swap_color
for (uint32_t cnt = 0; cnt < 8; cnt++) {
#if ESP_IDF_VERSION_MAJOR < 6
panel_config->rgb.data_gpio_nums[cnt + 8] = next_val(&lp1);
#else
panel_config->rgb.data_gpio_nums[cnt + 8] = (gpio_num_t)next_val(&lp1);
#endif
}
for (uint32_t cnt = 0; cnt < 8; cnt++) {
#if ESP_IDF_VERSION_MAJOR < 6
panel_config->rgb.data_gpio_nums[cnt] = next_val(&lp1);
#else
panel_config->rgb.data_gpio_nums[cnt] = (gpio_num_t)next_val(&lp1);
#endif
}
spi_speed = next_val(&lp1);
#endif //SOC_LCD_RGB_SUPPORTED
@@ -1326,13 +1334,20 @@ if (interface == _UDSP_SPI) {
panel_config->rgb.timings.h_res = gxs;
panel_config->rgb.timings.v_res = gys;
panel_config->rgb.data_width = 16; // RGB565 in parallel mode, thus 16bit in width
#if ESP_IDF_VERSION_MAJOR < 6
// sram_trans_align / psram_trans_align removed in IDF 6.x
panel_config->rgb.sram_trans_align = 8;
panel_config->rgb.psram_trans_align = 64;
#endif
// Handle byte swapping by swapping the low and high byte pin assignments
if (lvgl_param.swap_color) {
for (uint32_t cnt = 0; cnt < 8; cnt++) {
#if ESP_IDF_VERSION_MAJOR < 6
int8_t temp = panel_config->rgb.data_gpio_nums[cnt];
#else
gpio_num_t temp = panel_config->rgb.data_gpio_nums[cnt];
#endif
panel_config->rgb.data_gpio_nums[cnt] = panel_config->rgb.data_gpio_nums[cnt + 8];
panel_config->rgb.data_gpio_nums[cnt + 8] = temp;
}
@@ -8,6 +8,7 @@
#include "esp_lcd_panel_ops.h"
#include "esp_lcd_mipi_dsi.h"
#include "esp_ldo_regulator.h"
#include "esp_idf_version.h"
#include "driver/gpio.h"
#include <rom/cache.h>
#include "esp_rom_sys.h"
@@ -70,7 +71,12 @@ DSIPanel::DSIPanel(const DSIPanelConfig& config)
dpi_config.dpi_clk_src = MIPI_DSI_DPI_CLK_SRC_DEFAULT;
dpi_config.dpi_clock_freq_mhz = cfg.pixel_clock_hz / 1000000;
dpi_config.virtual_channel = 0;
#if ESP_IDF_VERSION_MAJOR >= 6
dpi_config.in_color_format = LCD_COLOR_FMT_RGB565;
dpi_config.out_color_format = LCD_COLOR_FMT_RGB565;
#else
dpi_config.pixel_format = LCD_COLOR_PIXEL_FORMAT_RGB565;
#endif
dpi_config.num_fbs = 1;
dpi_config.video_timing.h_size = cfg.width;
dpi_config.video_timing.v_size = cfg.height;
@@ -80,8 +86,10 @@ DSIPanel::DSIPanel(const DSIPanelConfig& config)
dpi_config.video_timing.vsync_back_porch = cfg.timing.v_back_porch;
dpi_config.video_timing.vsync_pulse_width = cfg.timing.v_sync_pulse;
dpi_config.video_timing.vsync_front_porch = cfg.timing.v_front_porch;
#if ESP_IDF_VERSION_MAJOR < 6
dpi_config.flags.use_dma2d = 1;
#endif
AddLog(3, "DSI: DPI config: clk=%dMHz res=%dx%d", dpi_config.dpi_clock_freq_mhz, cfg.width, cfg.height);
AddLog(3, "DSI: H timing: BP=%d PW=%d FP=%d", cfg.timing.h_back_porch, cfg.timing.h_sync_pulse, cfg.timing.h_front_porch);
AddLog(3, "DSI: V timing: BP=%d PW=%d FP=%d", cfg.timing.v_back_porch, cfg.timing.v_sync_pulse, cfg.timing.v_front_porch);
@@ -94,6 +102,12 @@ DSIPanel::DSIPanel(const DSIPanelConfig& config)
return;
}
AddLog(3, "DSI: DPI panel created");
#if ESP_IDF_VERSION_MAJOR >= 6
ret = esp_lcd_dpi_panel_enable_dma2d(panel_handle);
if (ret != ESP_OK) {
AddLog(3, "DSI: Failed to enable DMA2D: %d", ret);
}
#endif
// Step 6: Reset via GPIO (from config)
if (cfg.reset_pin >= 0) {
@@ -9,7 +9,24 @@
#define GPIO_SET_SLOW(A) digitalWrite(A, HIGH)
#define GPIO_CLR_SLOW(A) digitalWrite(A, LOW)
#else // ESP32
#if CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C5 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32P4
#if CONFIG_IDF_TARGET_ESP32S31
static inline void uDisplayGpioClear(uint32_t pin) {
if (pin < 32) {
GPIO.out_w1tc.val = (1U << pin);
} else {
GPIO.out1_w1tc.val = (1U << (pin - 32));
}
}
static inline void uDisplayGpioSet(uint32_t pin) {
if (pin < 32) {
GPIO.out_w1ts.val = (1U << pin);
} else {
GPIO.out1_w1ts.val = (1U << (pin - 32));
}
}
#define GPIO_CLR(A) uDisplayGpioClear(A)
#define GPIO_SET(A) uDisplayGpioSet(A)
#elif CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C5 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32P4
#define GPIO_CLR(A) GPIO.out_w1tc.val = (1 << A)
#define GPIO_SET(A) GPIO.out_w1ts.val = (1 << A)
#else // plain ESP32 or S3
@@ -272,12 +289,16 @@ void SPIController::hw_write9(uint8_t val, uint8_t dc) {
else regvalue &= 0x7f;
if (val & 1) regvalue |= 0x8000;
REG_SET_BIT(SPI_USER_REG(3), SPI_USR_MOSI);
REG_WRITE(SPI_MOSI_DLEN_REG(3), 9 - 1);
uint32_t *dp = (uint32_t*)SPI_W0_REG(3);
uint8_t spi_index = 3;
#if CONFIG_IDF_TARGET_ESP32S31
if (spi_config.bus_nr == 1) spi_index = 2;
#endif
REG_SET_BIT(SPI_USER_REG(spi_index), SPI_USR_MOSI);
REG_WRITE(SPI_MOSI_DLEN_REG(spi_index), 9 - 1);
uint32_t *dp = (uint32_t*)SPI_W0_REG(spi_index);
*dp = regvalue;
REG_SET_BIT(SPI_CMD_REG(3), SPI_USR);
while (REG_GET_FIELD(SPI_CMD_REG(3), SPI_USR));
REG_SET_BIT(SPI_CMD_REG(spi_index), SPI_USR);
while (REG_GET_FIELD(SPI_CMD_REG(spi_index), SPI_USR));
}
}
#else
@@ -319,6 +340,9 @@ bool SPIController::initDMA(uint16_t width, uint16_t flushlines, uint8_t data) {
}
if (spi_config.bus_nr == 1){
AddLog(3,"DSP: dma spi 1");
#if CONFIG_IDF_TARGET_ESP32S31
spi_host = FSPI_HOST;
#endif
} else if (spi_config.bus_nr == 2){
AddLog(3,"DSP: dma spi 2");
spi_host = HSPI_HOST;
@@ -115,7 +115,13 @@ public:
uint8_t getMaxMessageLength () override { return ESPNOW_MAX_MESSAGE_LENGTH; }
void enableTransmit (bool enable) override;
bool setChannel (uint8_t channel, wifi_second_chan_t ch2 = WIFI_SECOND_CHAN_NONE);
bool setWiFiBandwidth (wifi_interface_t iface = WIFI_IF_AP, wifi_bandwidth_t bw = WIFI_BW_HT20);
bool setWiFiBandwidth (wifi_interface_t iface = WIFI_IF_AP, wifi_bandwidth_t bw =
#if ESP_IDF_VERSION_MAJOR < 6
WIFI_BW_HT20
#else
WIFI_BW20 // IDF 6.x: WIFI_BW_HT20 renamed to WIFI_BW20
#endif
);
bool readyToSendData ();
protected:
@@ -31,10 +31,16 @@
# error "No ESP capability header found"
#endif
#if SOC_MPI_SUPPORTED
#if SOC_MPI_SUPPORTED && __has_include("rom/bigint.h")
#include "rom/bigint.h"
#include "t_inner.h"
#ifdef CONFIG_IDF_TARGET_ESP32
// dport_access.h provides DPORT_STALL_OTHER_CPU_START/END for ESP32 dual-core safety.
// Must be included at file scope — picolibc's stdio.h (IDF 6.x) contains static inlines
// that are invalid inside a function body.
#include "dport_access.h"
#endif
#define WORDS 8 /* 8×32-bit limbs */
@@ -133,7 +139,6 @@ static inline void field_mul(uint32_t *dst, const uint32_t *a, const uint32_t *b
ets_bigint_getz(dst, WORDS);
ets_bigint_disable();
#else
#include "dport_access.h"
uint32_t ram_a[16] __attribute__((aligned(16)));
uint32_t ram_b[16] __attribute__((aligned(16)));
uint32_t ram_tmp[16] __attribute__((aligned(16)));
@@ -31,7 +31,7 @@
# error "No ESP capability header found"
#endif
#if SOC_MPI_SUPPORTED
#if SOC_MPI_SUPPORTED && __has_include("rom/bigint.h")
#include <stdint.h>
#include "rom/bigint.h"
@@ -50,8 +50,8 @@ enum LoggingLevels {LOG_LEVEL_NONE, LOG_LEVEL_ERROR, LOG_LEVEL_INFO, LOG_LEVEL_D
// replicated from `tasmota.h`
#if CONFIG_IDF_TARGET_ESP32
const uint8_t MAX_PWMS = 16; // ESP32: 16 ledc PWM channels in total - TODO for now
#elif CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
const uint8_t MAX_PWMS = 8; // ESP32S2/S3: 8 ledc PWM channels in total
#elif CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32S31
const uint8_t MAX_PWMS = 8; // ESP32S2/S3/S31: 8 ledc PWM channels in total
#elif CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C5 || CONFIG_IDF_TARGET_ESP32C6
const uint8_t MAX_PWMS = 6; // ESP32C2/C3/C6: 6 ledc PWM channels in total
#else
@@ -8,7 +8,14 @@
#include "be_constobj.h"
#include "be_mapping.h"
#if __has_include("rom/crc.h")
#include "rom/crc.h"
#else
#include "esp_rom_crc.h"
#define crc32_le esp_rom_crc32_le
#define crc16_le esp_rom_crc16_le
#define crc8_le esp_rom_crc8_le
#endif
static uint32_t c_crc32(uint32_t crc, const uint8_t* buf, size_t size) {
return crc32_le(crc, buf, size);
@@ -3,6 +3,9 @@
*
*/
/* ARM Helium/MVE SIMD implementation - only compiled on ARM targets */
#if defined(__arm__) || defined(__ARM_ARCH)
#ifndef __ASSEMBLY__
#define __ASSEMBLY__
#endif
@@ -711,3 +714,5 @@ export_set argb8888, argb8888, 32, 32, normal
#endif /*LV_USE_DRAW_SW_ASM == LV_DRAW_SW_ASM_HELIUM && defined(__ARM_FEATURE_MVE) && __ARM_FEATURE_MVE && LV_USE_NATIVE_HELIUM_ASM*/
#endif /* defined(__arm__) || defined(__ARM_ARCH) */