203 lines
8.0 KiB
C
203 lines
8.0 KiB
C
/*
|
|
* SPDX-FileCopyrightText: 2024-2026 Espressif Systems (Shanghai) CO LTD
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
#include "app_composition.h"
|
|
|
|
#include <stdio.h>
|
|
|
|
#include "control_plane.h"
|
|
#include "esp_log.h"
|
|
#include "freertos/FreeRTOS.h"
|
|
#include "freertos/task.h"
|
|
#include "sdkconfig.h"
|
|
|
|
#ifndef CONFIG_TQ_BOOT_SEQUENCE_DRY_RUN
|
|
#define CONFIG_TQ_BOOT_SEQUENCE_DRY_RUN 0
|
|
#endif
|
|
|
|
#ifndef CONFIG_TQ_BOOT_SOUND_TIMEOUT_MS
|
|
#define CONFIG_TQ_BOOT_SOUND_TIMEOUT_MS 3000
|
|
#endif
|
|
|
|
static const char *TAG = "app_comp_boot";
|
|
|
|
typedef enum {
|
|
APP_COMPOSITION_BOOT_STAGE_POWER_HOLD = 1,
|
|
APP_COMPOSITION_BOOT_STAGE_AUDIO_INIT,
|
|
APP_COMPOSITION_BOOT_STAGE_BOOT_SOUND,
|
|
APP_COMPOSITION_BOOT_STAGE_AUDIO_RELEASE,
|
|
APP_COMPOSITION_BOOT_STAGE_LCD_DEVICE,
|
|
APP_COMPOSITION_BOOT_STAGE_LCD_RENDER_LOOP,
|
|
APP_COMPOSITION_BOOT_STAGE_PLATFORM_DOMAIN,
|
|
APP_COMPOSITION_BOOT_STAGE_TURNTABLE_CALIBRATION,
|
|
APP_COMPOSITION_BOOT_STAGE_STORAGE_PREPARE,
|
|
APP_COMPOSITION_BOOT_STAGE_WIFI_BOOTSTRAP,
|
|
APP_COMPOSITION_BOOT_STAGE_RUNTIME_WORKERS,
|
|
APP_COMPOSITION_BOOT_STAGE_NETWORK_SERVICES,
|
|
} app_composition_boot_stage_t;
|
|
|
|
static void app_composition_log_stage(app_composition_boot_stage_t stage,
|
|
const char *name,
|
|
const char *event)
|
|
{
|
|
ESP_LOGI(TAG, "boot stage %02d %-24s event=%s", (int)stage, name, event);
|
|
}
|
|
|
|
static void app_composition_log_stage_result(app_composition_boot_stage_t stage,
|
|
const char *name,
|
|
esp_err_t result)
|
|
{
|
|
ESP_LOGI(TAG,
|
|
"boot stage %02d %-24s result=%s",
|
|
(int)stage,
|
|
name,
|
|
esp_err_to_name(result));
|
|
}
|
|
|
|
static void app_composition_log_stage_skipped(app_composition_boot_stage_t stage,
|
|
const char *name,
|
|
const char *reason)
|
|
{
|
|
ESP_LOGI(TAG, "boot stage %02d %-24s skipped=%s", (int)stage, name, reason);
|
|
}
|
|
|
|
static esp_err_t app_composition_run_plan_a_boot_sequence(void)
|
|
{
|
|
app_composition_log_stage(APP_COMPOSITION_BOOT_STAGE_POWER_HOLD,
|
|
"power_hold",
|
|
"already_asserted_by_platform_core");
|
|
|
|
app_composition_log_stage(APP_COMPOSITION_BOOT_STAGE_AUDIO_INIT,
|
|
"audio_init",
|
|
"boot_sound_policy_begin");
|
|
app_composition_log_stage(APP_COMPOSITION_BOOT_STAGE_BOOT_SOUND,
|
|
"boot_sound",
|
|
"play_boot_sound_with_timeout");
|
|
esp_err_t boot_sound_err =
|
|
control_plane_play_boot_sound(CONFIG_TQ_BOOT_SOUND_TIMEOUT_MS);
|
|
if (boot_sound_err != ESP_OK) {
|
|
ESP_LOGW(TAG,
|
|
"Boot sound unavailable, continue boot: %s",
|
|
esp_err_to_name(boot_sound_err));
|
|
}
|
|
app_composition_log_stage(APP_COMPOSITION_BOOT_STAGE_AUDIO_RELEASE,
|
|
"audio_release",
|
|
"boot_sound_policy_end");
|
|
|
|
#if CONFIG_TQ_SCREEN_ENABLE
|
|
app_composition_log_stage(APP_COMPOSITION_BOOT_STAGE_LCD_DEVICE,
|
|
"lcd_device",
|
|
"control_plane_init_lcd_device");
|
|
esp_err_t lcd_err = control_plane_init_lcd_device();
|
|
app_composition_log_stage_result(APP_COMPOSITION_BOOT_STAGE_LCD_DEVICE,
|
|
"lcd_device",
|
|
lcd_err);
|
|
bool lcd_ready = (lcd_err == ESP_OK);
|
|
if (lcd_ready) {
|
|
app_composition_log_stage(APP_COMPOSITION_BOOT_STAGE_LCD_RENDER_LOOP,
|
|
"lcd_render_loop",
|
|
"control_plane_start_lcd_render_worker");
|
|
esp_err_t lcd_worker_err = control_plane_start_lcd_render_worker();
|
|
app_composition_log_stage_result(APP_COMPOSITION_BOOT_STAGE_LCD_RENDER_LOOP,
|
|
"lcd_render_loop",
|
|
lcd_worker_err);
|
|
if (lcd_worker_err != ESP_OK) {
|
|
lcd_ready = false;
|
|
}
|
|
} else {
|
|
app_composition_log_stage_skipped(APP_COMPOSITION_BOOT_STAGE_LCD_RENDER_LOOP,
|
|
"lcd_render_loop",
|
|
"lcd_device_unavailable");
|
|
}
|
|
#else
|
|
app_composition_log_stage_skipped(APP_COMPOSITION_BOOT_STAGE_LCD_DEVICE,
|
|
"lcd_device",
|
|
"disabled_by_config");
|
|
app_composition_log_stage_skipped(APP_COMPOSITION_BOOT_STAGE_LCD_RENDER_LOOP,
|
|
"lcd_render_loop",
|
|
"disabled_by_config");
|
|
#endif
|
|
|
|
app_composition_log_stage(APP_COMPOSITION_BOOT_STAGE_PLATFORM_DOMAIN,
|
|
"platform_domain",
|
|
"control_plane_init");
|
|
esp_err_t err = control_plane_init();
|
|
if (err != ESP_OK) {
|
|
ESP_LOGE(TAG, "control_plane_init failed: %s", esp_err_to_name(err));
|
|
return err;
|
|
}
|
|
|
|
#if CONFIG_TQ_BOOT_TURNTABLE_CALIBRATION_ENABLE
|
|
app_composition_log_stage(APP_COMPOSITION_BOOT_STAGE_TURNTABLE_CALIBRATION,
|
|
"turntable_calibration",
|
|
"control_plane_calibrate");
|
|
esp_err_t calibration_err = control_plane_calibrate();
|
|
if (calibration_err != ESP_OK) {
|
|
ESP_LOGW(TAG,
|
|
"Boot turntable calibration failed, continue degraded: %s",
|
|
esp_err_to_name(calibration_err));
|
|
}
|
|
#else
|
|
app_composition_log_stage_skipped(APP_COMPOSITION_BOOT_STAGE_TURNTABLE_CALIBRATION,
|
|
"turntable_calibration",
|
|
"disabled_by_config");
|
|
#endif
|
|
|
|
app_composition_log_stage(APP_COMPOSITION_BOOT_STAGE_STORAGE_PREPARE,
|
|
"storage_prepare",
|
|
"control_plane_prepare_runtime_storage");
|
|
err = control_plane_prepare_runtime_storage();
|
|
if (err != ESP_OK) {
|
|
ESP_LOGE(TAG, "Runtime storage prepare failed: %s", esp_err_to_name(err));
|
|
return err;
|
|
}
|
|
|
|
app_composition_log_stage(APP_COMPOSITION_BOOT_STAGE_WIFI_BOOTSTRAP,
|
|
"wifi_bootstrap",
|
|
"control_plane_bootstrap_connectivity");
|
|
esp_err_t wifi_err = control_plane_bootstrap_connectivity(CONFIG_MULTIMODAL_WIFI_SSID,
|
|
CONFIG_MULTIMODAL_WIFI_PASSWORD,
|
|
CONFIG_MULTIMODAL_CONNECT_TIMEOUT_MS,
|
|
"TQ-CAT");
|
|
if (wifi_err != ESP_OK) {
|
|
ESP_LOGW(TAG, "Connectivity bootstrap failed: %s", esp_err_to_name(wifi_err));
|
|
}
|
|
|
|
app_composition_log_stage(APP_COMPOSITION_BOOT_STAGE_RUNTIME_WORKERS,
|
|
"runtime_workers",
|
|
"control_plane_start_runtime_workers");
|
|
err = control_plane_start_runtime_workers();
|
|
if (err != ESP_OK) {
|
|
ESP_LOGE(TAG, "Runtime worker start failed: %s", esp_err_to_name(err));
|
|
return err;
|
|
}
|
|
|
|
app_composition_log_stage(APP_COMPOSITION_BOOT_STAGE_NETWORK_SERVICES,
|
|
"network_services",
|
|
"started_by_runtime_workers_after_readiness");
|
|
|
|
return ESP_OK;
|
|
}
|
|
|
|
esp_err_t app_composition_start_default_runtime(void)
|
|
{
|
|
setvbuf(stdin, NULL, _IONBF, 0);
|
|
setvbuf(stdout, NULL, _IONBF, 0);
|
|
setvbuf(stderr, NULL, _IONBF, 0);
|
|
|
|
ESP_LOGI(TAG, "========================================");
|
|
ESP_LOGI(TAG, " App Composition Boot Plan A");
|
|
ESP_LOGI(TAG, " dry_run=%d", CONFIG_TQ_BOOT_SEQUENCE_DRY_RUN);
|
|
ESP_LOGI(TAG, "========================================");
|
|
|
|
#if CONFIG_TQ_BOOT_SEQUENCE_DRY_RUN
|
|
ESP_LOGE(TAG, "Plan A dry-run is enabled; disable CONFIG_TQ_BOOT_SEQUENCE_DRY_RUN");
|
|
return ESP_ERR_NOT_SUPPORTED;
|
|
#else
|
|
return app_composition_run_plan_a_boot_sequence();
|
|
#endif
|
|
}
|