feat: support ESP32-S3 new board bring-up

This commit is contained in:
2026-08-03 14:06:06 +08:00
parent 404389f1ea
commit d5409ea4e3
16 changed files with 297 additions and 150 deletions
Binary file not shown.
Binary file not shown.
Binary file not shown.
+60 -11
View File
@@ -1,5 +1,5 @@
/*
* Direct ST7789 LCD backend.
* Direct ST7789P3 LCD backend.
*
* This backend owns the low-level panel initialization, a serialized render
* loop, and a minimal presentation queue.
@@ -18,6 +18,7 @@
#include "driver/gpio.h"
#include "driver/spi_master.h"
#include "esp_attr.h"
#include "esp_check.h"
#include "esp_lcd_panel_io.h"
#include "esp_lcd_panel_ops.h"
@@ -29,11 +30,19 @@
#include "sdkconfig.h"
#define LCD_DIRECT_SPI_HOST SPI2_HOST
#define LCD_DIRECT_WIDTH 320U
#define LCD_DIRECT_HEIGHT 240U
#define LCD_DIRECT_NATIVE_WIDTH 240U
#define LCD_DIRECT_NATIVE_HEIGHT 320U
#if CONFIG_TQ_SCREEN_SWAP_XY
#define LCD_DIRECT_WIDTH LCD_DIRECT_NATIVE_HEIGHT
#define LCD_DIRECT_HEIGHT LCD_DIRECT_NATIVE_WIDTH
#else
#define LCD_DIRECT_WIDTH LCD_DIRECT_NATIVE_WIDTH
#define LCD_DIRECT_HEIGHT LCD_DIRECT_NATIVE_HEIGHT
#endif
#define LCD_DIRECT_ROWS_PER_TRANSFER 8U
#define LCD_DIRECT_PIXELS_PER_TRANSFER (LCD_DIRECT_WIDTH * LCD_DIRECT_ROWS_PER_TRANSFER)
#define LCD_DIRECT_PRESENTATION_WAIT_POLL_MS 20U
#define LCD_DIRECT_TRANSFER_TIMEOUT_MS 100U
#define LCD_CMD_MADCTL 0x36
#define LCD_CMD_RAMCTRL 0xB0
@@ -88,6 +97,7 @@ static esp_lcd_panel_io_handle_t s_panel_io;
static esp_lcd_panel_handle_t s_panel;
static SemaphoreHandle_t s_lock;
static SemaphoreHandle_t s_completion_sem;
static SemaphoreHandle_t s_transfer_done_sem;
static TaskHandle_t s_render_task;
static bool s_initialized;
static bool s_render_loop_running;
@@ -101,6 +111,21 @@ static lcd_direct_rle_run_t s_rle_file_chunk[128];
static void lcd_direct_signal_completion(void);
static bool IRAM_ATTR lcd_direct_on_color_trans_done(esp_lcd_panel_io_handle_t panel_io,
esp_lcd_panel_io_event_data_t *event_data,
void *user_ctx)
{
(void)panel_io;
(void)event_data;
(void)user_ctx;
BaseType_t higher_priority_task_woken = pdFALSE;
if (s_transfer_done_sem != NULL) {
(void)xSemaphoreGiveFromISR(s_transfer_done_sem, &higher_priority_task_woken);
}
return higher_priority_task_woken == pdTRUE;
}
static uint16_t lcd_direct_swap_color(uint16_t color)
{
#if CONFIG_TQ_SCREEN_SWAP_COLOR_BYTES
@@ -113,12 +138,26 @@ static uint16_t lcd_direct_swap_color(uint16_t color)
static esp_err_t lcd_direct_draw_rows(uint16_t row_start, uint16_t row_count)
{
ESP_RETURN_ON_FALSE(s_panel != NULL, ESP_ERR_INVALID_STATE, TAG, "panel is not ready");
return esp_lcd_panel_draw_bitmap(s_panel,
0,
row_start,
LCD_DIRECT_WIDTH,
row_start + row_count,
s_line_buffer);
ESP_RETURN_ON_FALSE(s_transfer_done_sem != NULL,
ESP_ERR_INVALID_STATE,
TAG,
"transfer semaphore is not ready");
(void)xSemaphoreTake(s_transfer_done_sem, 0);
ESP_RETURN_ON_ERROR(esp_lcd_panel_draw_bitmap(s_panel,
0,
row_start,
LCD_DIRECT_WIDTH,
row_start + row_count,
s_line_buffer),
TAG,
"panel draw failed");
ESP_RETURN_ON_FALSE(xSemaphoreTake(s_transfer_done_sem,
pdMS_TO_TICKS(LCD_DIRECT_TRANSFER_TIMEOUT_MS)) == pdTRUE,
ESP_ERR_TIMEOUT,
TAG,
"panel transfer timed out");
return ESP_OK;
}
static esp_err_t lcd_direct_gpio_init(void)
@@ -168,7 +207,8 @@ static esp_err_t lcd_direct_panel_init(void)
.lcd_cmd_bits = 8,
.lcd_param_bits = 8,
.spi_mode = 0,
.trans_queue_depth = 10,
.trans_queue_depth = 1,
.on_color_trans_done = lcd_direct_on_color_trans_done,
};
ESP_RETURN_ON_ERROR(esp_lcd_new_panel_io_spi((esp_lcd_spi_bus_handle_t)LCD_DIRECT_SPI_HOST,
&io_config,
@@ -871,13 +911,22 @@ esp_err_t lcd_direct_init_device(void)
ESP_RETURN_ON_FALSE(s_lock != NULL, ESP_ERR_NO_MEM, TAG, "lock create failed");
s_completion_sem = xSemaphoreCreateBinary();
ESP_RETURN_ON_FALSE(s_completion_sem != NULL, ESP_ERR_NO_MEM, TAG, "completion sem create failed");
s_transfer_done_sem = xSemaphoreCreateBinary();
ESP_RETURN_ON_FALSE(s_transfer_done_sem != NULL,
ESP_ERR_NO_MEM,
TAG,
"transfer sem create failed");
ESP_RETURN_ON_ERROR(lcd_direct_gpio_init(), TAG, "gpio init failed");
ESP_RETURN_ON_ERROR(lcd_direct_panel_init(), TAG, "esp_lcd panel init failed");
s_initialized = true;
ESP_LOGI(TAG,
"Direct LCD initialized (MOSI=%d SCLK=%d CS=%d DC=%d RST=%d BL=%d clock=%d)",
"Direct ST7789P3 LCD initialized (native=%ux%u logical=%ux%u MOSI=%d SCLK=%d CS=%d DC=%d RST=%d BL=%d clock=%d)",
(unsigned)LCD_DIRECT_NATIVE_WIDTH,
(unsigned)LCD_DIRECT_NATIVE_HEIGHT,
(unsigned)LCD_DIRECT_WIDTH,
(unsigned)LCD_DIRECT_HEIGHT,
CONFIG_TQ_SCREEN_SPI_MOSI_GPIO,
CONFIG_TQ_SCREEN_SPI_CLK_GPIO,
CONFIG_TQ_SCREEN_SPI_CS_GPIO,
+3 -3
View File
@@ -12,15 +12,15 @@ static const lcd_direct_image_t s_default_image = {
static const lcd_direct_image_t s_basic_face_frames[] = {
{
.path = LCD_ASSET_BASE_PATH "jichubiaoqing0.rle",
.run_count = 5893U,
.run_count = 5411U,
},
{
.path = LCD_ASSET_BASE_PATH "jichubiaoqing1.rle",
.run_count = 4581U,
.run_count = 4099U,
},
{
.path = LCD_ASSET_BASE_PATH "jichubiaoqing2.rle",
.run_count = 3651U,
.run_count = 3169U,
},
};
@@ -324,7 +324,16 @@ esp_err_t platform_stepper_driver_init(void)
.intr_type = GPIO_INTR_DISABLE
};
return gpio_config(&io_conf);
esp_err_t err = gpio_config(&io_conf);
if (err == ESP_OK) {
ESP_LOGI(TAG,
"Stepper ready IN1=%d IN2=%d IN3=%d IN4=%d",
PLATFORM_STEPPER_IN1_PIN,
PLATFORM_STEPPER_IN2_PIN,
PLATFORM_STEPPER_IN3_PIN,
PLATFORM_STEPPER_IN4_PIN);
}
return err;
}
esp_err_t platform_stepper_driver_rotate_angle_with_accel(float angle,
@@ -15,7 +15,12 @@
#include "sdkconfig.h"
#include "ssid_manager.h"
#include "wifi_manager.h"
#if __has_include("wifi_storage_hooks.h")
#include "wifi_storage_hooks.h"
#define WIFI_PORTAL_HAS_STORAGE_HOOKS 1
#else
#define WIFI_PORTAL_HAS_STORAGE_HOOKS 0
#endif
static const char *TAG = "wifi_portal";
@@ -49,6 +54,7 @@ static void install_wifi_storage_hooks(void)
return;
}
#if WIFI_PORTAL_HAS_STORAGE_HOOKS
const wifi_storage_hooks_t hooks = {
.set_string = platform_storage_set_string,
.get_string = platform_storage_get_string,
@@ -59,6 +65,9 @@ static void install_wifi_storage_hooks(void)
.erase = platform_storage_erase,
};
wifi_storage_set_hooks(&hooks);
#else
ESP_LOGW(TAG, "Wi-Fi storage hook API unavailable; using component default storage");
#endif
s_installed = true;
}
@@ -198,6 +207,21 @@ static void seed_default_credentials(const char *ssid, const char *password)
return;
}
bool configured_ssid_saved = false;
for (const auto &item : manager.GetSsidList()) {
if (item.ssid == ssid) {
configured_ssid_saved = true;
break;
}
}
if (saved_count > 0U && !configured_ssid_saved) {
ESP_LOGI(TAG,
"Configured seed SSID changed to \"%s\"; replacing %u stale credential candidate(s)",
ssid,
(unsigned)saved_count);
manager.Clear();
}
manager.AddSsid(ssid, password != NULL ? password : "");
ESP_LOGI(TAG,
"Ensured configured Wi-Fi credentials for SSID \"%s\" with %u previous candidate(s)",