feat: support ESP32-S3 new board bring-up
This commit is contained in:
@@ -74,10 +74,26 @@
|
||||
#define CONFIG_MULTIMODAL_PTT_BUTTON_PULLDOWN 0
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_MULTIMODAL_PTT_BUTTON_PULLUP
|
||||
#define CONFIG_MULTIMODAL_PTT_BUTTON_PULLUP 0
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_TQ_SLOT_SWITCH_PULLUP
|
||||
#define CONFIG_TQ_SLOT_SWITCH_PULLUP 0
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_TQ_SLOT_SWITCH_PULLDOWN
|
||||
#define CONFIG_TQ_SLOT_SWITCH_PULLDOWN 0
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_TQ_CALIBRATION_SWITCH_PULLUP
|
||||
#define CONFIG_TQ_CALIBRATION_SWITCH_PULLUP 0
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_TQ_CALIBRATION_SWITCH_PULLDOWN
|
||||
#define CONFIG_TQ_CALIBRATION_SWITCH_PULLDOWN 0
|
||||
#endif
|
||||
|
||||
static const char *TAG = "cp_key_input";
|
||||
|
||||
typedef struct {
|
||||
@@ -137,6 +153,20 @@ static const control_plane_key_config_t s_key_configs[] = {
|
||||
.enable_double_click = false,
|
||||
#endif
|
||||
},
|
||||
{
|
||||
.key_id = CONTROL_PLANE_KEY_ID_SW1,
|
||||
.gpio_num = CONFIG_TQ_CALIBRATION_SWITCH_GPIO,
|
||||
.active_level = CONFIG_TQ_CALIBRATION_SWITCH_ACTIVE_LEVEL,
|
||||
.pullup_enabled = CONFIG_TQ_CALIBRATION_SWITCH_PULLUP,
|
||||
.pulldown_enabled = CONFIG_TQ_CALIBRATION_SWITCH_PULLDOWN,
|
||||
.debounce_ms = CONFIG_TQ_KEY_DEBOUNCE_INTERVAL_MS,
|
||||
.long_press_ms = CONFIG_TQ_KEY_LONG_PRESS_MS,
|
||||
.double_click_ms = CONFIG_TQ_KEY_DOUBLE_CLICK_MS,
|
||||
.emit_press_release = true,
|
||||
.enable_short_press = true,
|
||||
.enable_long_press = true,
|
||||
.enable_double_click = true,
|
||||
},
|
||||
{
|
||||
.key_id = CONTROL_PLANE_KEY_ID_SW2,
|
||||
.gpio_num = CONFIG_TQ_SLOT_SWITCH_GPIO,
|
||||
|
||||
@@ -18,6 +18,7 @@ static const char *TAG = "domain_cal";
|
||||
#define DOMAIN_CALIBRATION_STEP_TIMEOUT_MS 1500
|
||||
#define DOMAIN_TURNTABLE_LIMIT_SEARCH_MAX_DEG 330.0f
|
||||
#define DOMAIN_TURNTABLE_LIMIT_TO_HOME_DEG 180.0f
|
||||
#define DOMAIN_TURNTABLE_RETURN_CHUNK_DEG 90.0f
|
||||
#define DOMAIN_TURNTABLE_HOME_ANGLE_DEG 0.0f
|
||||
|
||||
static float clamp_positive_default(float value, float default_value)
|
||||
@@ -110,6 +111,32 @@ static esp_err_t calibration_rotate_and_track(float delta, int rotate_speed_us,
|
||||
return domain_apply_rotation_delta(delta);
|
||||
}
|
||||
|
||||
static esp_err_t calibration_return_from_limit(float search_direction,
|
||||
int rotate_speed_us,
|
||||
TickType_t start_tick,
|
||||
TickType_t timeout_ticks)
|
||||
{
|
||||
float remaining_deg = DOMAIN_TURNTABLE_LIMIT_TO_HOME_DEG;
|
||||
while (remaining_deg > 0.0f) {
|
||||
float chunk_deg = remaining_deg < DOMAIN_TURNTABLE_RETURN_CHUNK_DEG ?
|
||||
remaining_deg :
|
||||
DOMAIN_TURNTABLE_RETURN_CHUNK_DEG;
|
||||
int remaining_timeout_ms = calibration_remaining_timeout_ms(start_tick, timeout_ticks);
|
||||
if (remaining_timeout_ms <= 0) {
|
||||
return ESP_ERR_TIMEOUT;
|
||||
}
|
||||
|
||||
esp_err_t err = calibration_rotate_and_track(-search_direction * chunk_deg,
|
||||
rotate_speed_us,
|
||||
remaining_timeout_ms);
|
||||
if (err != ESP_OK) {
|
||||
return err;
|
||||
}
|
||||
remaining_deg -= chunk_deg;
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t domain_calibrate_with_timeout(const domain_direction_calibration_t *config, int timeout_ms)
|
||||
{
|
||||
int effective_timeout_ms = timeout_ms > 0 ? timeout_ms : DOMAIN_CALIBRATION_TIMEOUT_MS;
|
||||
@@ -157,17 +184,17 @@ esp_err_t domain_calibrate_with_timeout(const domain_direction_calibration_t *co
|
||||
int rotate_speed_us = domain_get_rotate_speed_us();
|
||||
|
||||
ESP_LOGI(TAG,
|
||||
"Limit calibration start step=%.1f sweep=%.1f search=%s",
|
||||
"Boot motor test start: KEY1/SW1 search step=%.1f sweep=%.1f direction=%s",
|
||||
step_angle,
|
||||
max_sweep,
|
||||
calibration.search_clockwise ? "clockwise" : "counterclockwise");
|
||||
|
||||
if (is_calibration_switch_active(&calibration)) {
|
||||
ESP_LOGI(TAG, "Limit switch active at start; treating current position as 6 o'clock");
|
||||
int return_timeout_ms = calibration_step_timeout_ms(start_tick, timeout_ticks);
|
||||
err = calibration_rotate_and_track(-direction * DOMAIN_TURNTABLE_LIMIT_TO_HOME_DEG,
|
||||
rotate_speed_us,
|
||||
return_timeout_ms);
|
||||
ESP_LOGI(TAG, "KEY1/SW1 pressed at motor-test start; treating current position as 6 o'clock");
|
||||
err = calibration_return_from_limit(direction,
|
||||
rotate_speed_us,
|
||||
start_tick,
|
||||
timeout_ticks);
|
||||
if (err != ESP_OK) {
|
||||
domain_runtime_stepper_power_off();
|
||||
domain_direction_unlock_state();
|
||||
@@ -206,11 +233,13 @@ esp_err_t domain_calibrate_with_timeout(const domain_direction_calibration_t *co
|
||||
}
|
||||
|
||||
if (is_calibration_switch_active(&calibration)) {
|
||||
ESP_LOGI(TAG, "Limit switch detected after %.1f deg; current position is 6 o'clock", total_sweep);
|
||||
int return_timeout_ms = calibration_step_timeout_ms(start_tick, timeout_ticks);
|
||||
err = calibration_rotate_and_track(-direction * DOMAIN_TURNTABLE_LIMIT_TO_HOME_DEG,
|
||||
rotate_speed_us,
|
||||
return_timeout_ms);
|
||||
ESP_LOGI(TAG,
|
||||
"KEY1/SW1 press detected after %.1f deg; current position is 6 o'clock",
|
||||
total_sweep);
|
||||
err = calibration_return_from_limit(direction,
|
||||
rotate_speed_us,
|
||||
start_tick,
|
||||
timeout_ticks);
|
||||
if (err != ESP_OK) {
|
||||
domain_runtime_stepper_power_off();
|
||||
domain_direction_unlock_state();
|
||||
@@ -226,6 +255,6 @@ esp_err_t domain_calibrate_with_timeout(const domain_direction_calibration_t *co
|
||||
|
||||
domain_runtime_stepper_power_off();
|
||||
domain_direction_unlock_state();
|
||||
ESP_LOGW(TAG, "Limit switch not found after %.1f deg search", total_sweep);
|
||||
ESP_LOGW(TAG, "KEY1/SW1 not pressed during %.1f deg motor test", total_sweep);
|
||||
return ESP_ERR_TIMEOUT;
|
||||
}
|
||||
|
||||
@@ -761,7 +761,14 @@ esp_err_t domain_runtime_calibration_switch_init(void)
|
||||
config.active_level,
|
||||
config.pullup_enabled,
|
||||
config.pulldown_enabled);
|
||||
return domain_runtime_digital_input_configure(&config);
|
||||
esp_err_t err = domain_runtime_digital_input_configure(&config);
|
||||
if (err == ESP_OK) {
|
||||
ESP_LOGI(TAG,
|
||||
"KEY1/SW1 ready gpio=%d initial_state=%s",
|
||||
config.gpio_num,
|
||||
domain_runtime_digital_input_is_active(&config) ? "pressed" : "released");
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
bool domain_runtime_calibration_switch_is_active(void)
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -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,
|
||||
|
||||
@@ -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)",
|
||||
|
||||
Reference in New Issue
Block a user