feat(control-plane): add configurable Wi-Fi reset button
This commit is contained in:
@@ -14,6 +14,7 @@ idf_component_register(
|
||||
"src/runtime/control_plane_fortune_service.c"
|
||||
"src/runtime/control_plane_system_events.c"
|
||||
"src/runtime/control_plane_key_input.c"
|
||||
"src/runtime/control_plane_reset_service.c"
|
||||
"src/runtime/control_plane_remote_log_service.c"
|
||||
"src/runtime/control_plane_runtime_workers.c"
|
||||
"src/runtime/control_plane_ota.c"
|
||||
|
||||
@@ -24,6 +24,7 @@ typedef enum {
|
||||
CONTROL_PLANE_KEY_ID_PTT = 0,
|
||||
CONTROL_PLANE_KEY_ID_SW1,
|
||||
CONTROL_PLANE_KEY_ID_SW2,
|
||||
CONTROL_PLANE_KEY_ID_RESET,
|
||||
} control_plane_key_id_t;
|
||||
|
||||
typedef enum {
|
||||
@@ -54,4 +55,3 @@ typedef struct {
|
||||
control_plane_key_event_t key;
|
||||
} data;
|
||||
} control_plane_system_event_t;
|
||||
|
||||
|
||||
@@ -158,6 +158,7 @@ const char *control_plane_key_event_type_name(control_plane_key_event_type_t typ
|
||||
|
||||
esp_err_t control_plane_start_key_input_task(void);
|
||||
void control_plane_stop_key_input_task(void);
|
||||
void control_plane_reset_wifi_provisioning_and_restart(void);
|
||||
esp_err_t control_plane_schedule_websocket_wait_task(void);
|
||||
void control_plane_set_ptt_active(bool active);
|
||||
esp_err_t control_plane_enter_mini_program_reprovisioning(const char *reason);
|
||||
|
||||
@@ -94,6 +94,18 @@
|
||||
#define CONFIG_TQ_CALIBRATION_SWITCH_PULLDOWN 0
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_TQ_RESET_BUTTON_ENABLE
|
||||
#define CONFIG_TQ_RESET_BUTTON_ENABLE 0
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_TQ_RESET_BUTTON_PULLUP
|
||||
#define CONFIG_TQ_RESET_BUTTON_PULLUP 0
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_TQ_RESET_BUTTON_PULLDOWN
|
||||
#define CONFIG_TQ_RESET_BUTTON_PULLDOWN 0
|
||||
#endif
|
||||
|
||||
static const char *TAG = "cp_key_input";
|
||||
|
||||
typedef struct {
|
||||
@@ -181,6 +193,22 @@ static const control_plane_key_config_t s_key_configs[] = {
|
||||
.enable_long_press = true,
|
||||
.enable_double_click = true,
|
||||
},
|
||||
#if CONFIG_TQ_RESET_BUTTON_ENABLE
|
||||
{
|
||||
.key_id = CONTROL_PLANE_KEY_ID_RESET,
|
||||
.gpio_num = CONFIG_TQ_RESET_BUTTON_GPIO,
|
||||
.active_level = CONFIG_TQ_RESET_BUTTON_ACTIVE_LEVEL,
|
||||
.pullup_enabled = CONFIG_TQ_RESET_BUTTON_PULLUP,
|
||||
.pulldown_enabled = CONFIG_TQ_RESET_BUTTON_PULLDOWN,
|
||||
.debounce_ms = CONFIG_TQ_KEY_DEBOUNCE_INTERVAL_MS,
|
||||
.long_press_ms = CONFIG_TQ_RESET_BUTTON_LONG_PRESS_MS,
|
||||
.double_click_ms = 0,
|
||||
.emit_press_release = false,
|
||||
.enable_short_press = false,
|
||||
.enable_long_press = true,
|
||||
.enable_double_click = false,
|
||||
},
|
||||
#endif
|
||||
};
|
||||
|
||||
static QueueHandle_t s_gpio_irq_queue;
|
||||
@@ -262,6 +290,31 @@ static esp_err_t control_plane_configure_key_gpio(const control_plane_key_config
|
||||
return gpio_intr_enable(config->gpio_num);
|
||||
}
|
||||
|
||||
static esp_err_t control_plane_validate_key_configs(void)
|
||||
{
|
||||
for (size_t i = 0; i < sizeof(s_key_configs) / sizeof(s_key_configs[0]); ++i) {
|
||||
const control_plane_key_config_t *config = &s_key_configs[i];
|
||||
if (config->pullup_enabled && config->pulldown_enabled) {
|
||||
ESP_LOGE(TAG,
|
||||
"key=%s gpio=%d cannot enable pull-up and pull-down together",
|
||||
control_plane_key_id_name(config->key_id),
|
||||
(int)config->gpio_num);
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
for (size_t j = 0; j < i; ++j) {
|
||||
if (s_key_configs[j].gpio_num == config->gpio_num) {
|
||||
ESP_LOGE(TAG,
|
||||
"key GPIO conflict: key=%s and key=%s both use gpio=%d",
|
||||
control_plane_key_id_name(s_key_configs[j].key_id),
|
||||
control_plane_key_id_name(config->key_id),
|
||||
(int)config->gpio_num);
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static void control_plane_emit_key_event(const control_plane_key_config_t *config,
|
||||
control_plane_key_event_type_t type,
|
||||
int level,
|
||||
@@ -469,6 +522,12 @@ static void control_plane_key_input_task(void *arg)
|
||||
|
||||
esp_err_t setup_err = ESP_OK;
|
||||
memset(s_key_states, 0, sizeof(s_key_states));
|
||||
setup_err = control_plane_validate_key_configs();
|
||||
if (setup_err != ESP_OK) {
|
||||
s_key_input_task = NULL;
|
||||
vTaskDelete(NULL);
|
||||
return;
|
||||
}
|
||||
for (size_t i = 0; i < sizeof(s_key_configs) / sizeof(s_key_configs[0]); ++i) {
|
||||
const control_plane_key_config_t *config = &s_key_configs[i];
|
||||
s_key_states[i].initialized = true;
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "control_plane_internal.h"
|
||||
|
||||
#include "esp_log.h"
|
||||
|
||||
static const char *TAG = "cp_reset";
|
||||
|
||||
void control_plane_reset_wifi_provisioning_and_restart(void)
|
||||
{
|
||||
ESP_LOGW(TAG, "Wi-Fi reset requested; clearing saved credentials");
|
||||
|
||||
esp_err_t err = domain_runtime_wifi_portal_clear_saved_credentials();
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG,
|
||||
"Wi-Fi credential reset failed; device will not restart: %s",
|
||||
esp_err_to_name(err));
|
||||
return;
|
||||
}
|
||||
|
||||
ESP_LOGW(TAG, "Saved Wi-Fi credentials cleared; restarting device");
|
||||
domain_runtime_restart();
|
||||
}
|
||||
@@ -84,6 +84,8 @@ const char *control_plane_key_id_name(control_plane_key_id_t key_id)
|
||||
return "SW1";
|
||||
case CONTROL_PLANE_KEY_ID_SW2:
|
||||
return "SW2";
|
||||
case CONTROL_PLANE_KEY_ID_RESET:
|
||||
return "RESET";
|
||||
default:
|
||||
return "UNKNOWN";
|
||||
}
|
||||
@@ -128,6 +130,13 @@ static void control_plane_dispatch_key_event(const control_plane_key_event_t *ev
|
||||
event->press_duration_ms,
|
||||
event->click_count);
|
||||
|
||||
if (event->key_id == CONTROL_PLANE_KEY_ID_RESET) {
|
||||
if (event->type == CONTROL_PLANE_KEY_EVENT_LONG_PRESS_START) {
|
||||
control_plane_reset_wifi_provisioning_and_restart();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (event->key_id == CONTROL_PLANE_KEY_ID_SW2) {
|
||||
if (event->type == CONTROL_PLANE_KEY_EVENT_SHORT_PRESS) {
|
||||
esp_err_t request_err = control_plane_request_cloud_chouqian();
|
||||
|
||||
@@ -20,6 +20,7 @@ the ESP32-S3 MCU perspective.
|
||||
| 11 | `CONFIG_MULTIMODAL_AUDIO_PA_GPIO` | Output | Audio amplifier | PA enable | Managed by codec GPIO interface |
|
||||
| 12 | `CONFIG_TQ_CALIBRATION_SWITCH_GPIO` | Input | Turntable calibration | Button 1 / SW1 direction calibration | Active-low, external and internal pull-up |
|
||||
| 13 | `CONFIG_MULTIMODAL_PTT_BUTTON_GPIO` | Input | Keys / multimodal | Button 2 / K2 push-to-talk | Active-low, external and internal pull-up |
|
||||
| 14 | `CONFIG_TQ_RESET_BUTTON_GPIO` | Input when enabled | Optional reset key | Hold to clear saved Wi-Fi credentials and restart | Disabled by default; active-low with internal pull-up when enabled |
|
||||
| 15 | `CONFIG_TQ_SCREEN_SPI_CS_GPIO` | Output | LCD | ST7789P3 SPI chip select | SPI2 host |
|
||||
| 16 | `CONFIG_TQ_SCREEN_DC_GPIO` | Output | LCD | ST7789P3 data/command select | Initialized low |
|
||||
| 17 | `CONFIG_TQ_SCREEN_RESET_PIN` | Output | LCD | ST7789P3 panel reset | Active-low reset; `-1` disables hardware reset |
|
||||
|
||||
+1
-1
@@ -30,7 +30,7 @@ hold net; that assignment is not valid for the current board.
|
||||
| 19 | GPIO11 | PA_CTRL | Output | Audio power-amplifier enable | Amplifier control |
|
||||
| 20 | GPIO12 | SW1 | Input | Button 1 / turntable calibration switch | External 10 kOhm pull-up; active low |
|
||||
| 21 | GPIO13 | SW2 | Input | Button 2 / K2 push-to-talk input | External 10 kOhm pull-up; active low |
|
||||
| 22 | GPIO14 | UNASSIGNED | N/A | No connection assigned | Reserved; no signal assigned |
|
||||
| 22 | GPIO14 | UNASSIGNED / RESET_KEY | Optional input | Configurable Wi-Fi reset button | Unassigned and disabled by default; active-low with internal pull-up when enabled |
|
||||
| 23 | GPIO21 | IN4 | Output | ULN2003 IN4 | Stepper motor phase control |
|
||||
| 24 | GPIO47 | IN3 | Output | ULN2003 IN3 | Stepper motor phase control |
|
||||
| 25 | GPIO48 | IN2 | Output | ULN2003 IN2 | Stepper motor phase control |
|
||||
|
||||
+52
-2
@@ -389,8 +389,9 @@ menu "Example Configuration"
|
||||
default y
|
||||
help
|
||||
Start the staged GPIO interrupt key input task for PTT, SW1,
|
||||
and SW2. SW1 remains the turntable calibration input and is
|
||||
also reported for post-boot button diagnostics.
|
||||
SW2, and the optional Wi-Fi reset button. SW1 remains the
|
||||
turntable calibration input and is also reported for post-boot
|
||||
button diagnostics.
|
||||
|
||||
config TQ_KEY_INPUT_TASK_STACK
|
||||
int "Key input task stack size"
|
||||
@@ -448,6 +449,55 @@ menu "Example Configuration"
|
||||
help
|
||||
Ignore raw GPIO chatter briefly after a double-click has been emitted.
|
||||
|
||||
config TQ_RESET_BUTTON_ENABLE
|
||||
bool "Enable Wi-Fi reset button"
|
||||
default n
|
||||
depends on TQ_KEY_INPUT_ENABLE
|
||||
help
|
||||
Enable a dedicated reset button. Holding the button for the
|
||||
configured duration clears saved Wi-Fi credentials and then
|
||||
restarts the device. Other persisted data is not changed.
|
||||
|
||||
config TQ_RESET_BUTTON_GPIO
|
||||
int "Wi-Fi reset button GPIO"
|
||||
default 14
|
||||
range 0 48
|
||||
depends on TQ_RESET_BUTTON_ENABLE
|
||||
help
|
||||
GPIO used for the dedicated Wi-Fi reset button when enabled.
|
||||
GPIO14 is unassigned on the current board revision.
|
||||
|
||||
config TQ_RESET_BUTTON_ACTIVE_LEVEL
|
||||
int "Wi-Fi reset button active level"
|
||||
default 0
|
||||
range 0 1
|
||||
depends on TQ_RESET_BUTTON_ENABLE
|
||||
help
|
||||
Logic level that means the Wi-Fi reset button is pressed.
|
||||
|
||||
config TQ_RESET_BUTTON_PULLUP
|
||||
bool "Enable Wi-Fi reset button pull-up"
|
||||
default y
|
||||
depends on TQ_RESET_BUTTON_ENABLE
|
||||
help
|
||||
Enable the internal pull-up for active-low wiring.
|
||||
|
||||
config TQ_RESET_BUTTON_PULLDOWN
|
||||
bool "Enable Wi-Fi reset button pull-down"
|
||||
default n
|
||||
depends on TQ_RESET_BUTTON_ENABLE
|
||||
help
|
||||
Enable the internal pull-down for active-high wiring.
|
||||
|
||||
config TQ_RESET_BUTTON_LONG_PRESS_MS
|
||||
int "Wi-Fi reset button hold duration (ms)"
|
||||
default 5000
|
||||
range 1000 15000
|
||||
depends on TQ_RESET_BUTTON_ENABLE
|
||||
help
|
||||
Continuous press duration required before saved Wi-Fi
|
||||
credentials are cleared and the device restarts.
|
||||
|
||||
choice TQ_PTT_INTERACTION_MODE
|
||||
prompt "PTT interaction mode"
|
||||
default TQ_PTT_MODE_CLICK_TO_TALK
|
||||
|
||||
@@ -181,6 +181,7 @@ CONFIG_MULTIMODAL_PTT_BUTTON_GPIO=13
|
||||
CONFIG_MULTIMODAL_PTT_BUTTON_ACTIVE_LEVEL=0
|
||||
CONFIG_MULTIMODAL_PTT_BUTTON_PULLUP=y
|
||||
# CONFIG_MULTIMODAL_PTT_BUTTON_PULLDOWN is not set
|
||||
# CONFIG_TQ_RESET_BUTTON_ENABLE is not set
|
||||
# CONFIG_MULTIMODAL_AUDIO_CHANNEL_PROBE_ON_INIT is not set
|
||||
CONFIG_MULTIMODAL_HEARTBEAT_INTERVAL_MS=50000
|
||||
CONFIG_MULTIMODAL_NO_RESPONSE_TIMEOUT_MS=60000
|
||||
|
||||
Reference in New Issue
Block a user