From 99e010c3e651f5312758afb783e6fe1281ae3fc2 Mon Sep 17 00:00:00 2001 From: me-no-dev Date: Wed, 22 Oct 2025 14:16:10 +0300 Subject: [PATCH 1/3] feat(hosted): Add OTA and version functionality to esp-hosted --- cores/esp32/esp32-hal-hosted.c | 96 +++++++++++++++++++++++++++++++++- cores/esp32/esp32-hal-hosted.h | 7 +++ 2 files changed, 101 insertions(+), 2 deletions(-) diff --git a/cores/esp32/esp32-hal-hosted.c b/cores/esp32/esp32-hal-hosted.c index 0bb8023432a..f2bdf8fe923 100644 --- a/cores/esp32/esp32-hal-hosted.c +++ b/cores/esp32/esp32-hal-hosted.c @@ -18,9 +18,10 @@ #include "esp32-hal-hosted.h" #include "esp32-hal-log.h" +#include "esp_hosted.h" #include "esp_hosted_transport_config.h" -extern esp_err_t esp_hosted_init(); -extern esp_err_t esp_hosted_deinit(); +// extern esp_err_t esp_hosted_init(); +// extern esp_err_t esp_hosted_deinit(); static bool hosted_initialized = false; static bool hosted_ble_active = false; @@ -46,6 +47,91 @@ static sdio_pin_config_t sdio_pin_config = { #endif }; +static esp_hosted_coprocessor_fwver_t slave_version_struct = { + .major1 = 0, + .minor1 = 0, + .patch1 = 0 +}; +static esp_hosted_coprocessor_fwver_t host_version_struct = { + .major1 = ESP_HOSTED_VERSION_MAJOR_1, + .minor1 = ESP_HOSTED_VERSION_MINOR_1, + .patch1 = ESP_HOSTED_VERSION_PATCH_1 +}; + +void hostedGetHostVersion(uint32_t * major, uint32_t * minor, uint32_t * patch) { + *major = host_version_struct.major1; + *minor = host_version_struct.minor1; + *patch = host_version_struct.patch1; +} + +void hostedGetSlaveVersion(uint32_t * major, uint32_t * minor, uint32_t * patch) { + *major = slave_version_struct.major1; + *minor = slave_version_struct.minor1; + *patch = slave_version_struct.patch1; +} + +bool hostedHasUpdate() { + uint32_t host_version = ESP_HOSTED_VERSION_VAL(host_version_struct.major1, host_version_struct.minor1, host_version_struct.patch1); + uint32_t slave_version = ESP_HOSTED_VERSION_VAL(slave_version_struct.major1, slave_version_struct.minor1, slave_version_struct.patch1); + + esp_err_t ret = esp_hosted_get_coprocessor_fwversion(&slave_version_struct); + if (ret != ESP_OK) { + log_e("Could not get slave firmware version: %s", esp_err_to_name(ret)); + } else { + slave_version = ESP_HOSTED_VERSION_VAL(slave_version_struct.major1, slave_version_struct.minor1, slave_version_struct.patch1); + } + + log_i("Host firmware version: %" PRIu32 ".%" PRIu32 ".%" PRIu32, host_version_struct.major1, host_version_struct.minor1, host_version_struct.patch1); + log_i("Slave firmware version: %" PRIu32 ".%" PRIu32 ".%" PRIu32, slave_version_struct.major1, slave_version_struct.minor1, slave_version_struct.patch1); + + // compare major.minor only + // slave_version &= 0xFFFFFF00; + // host_version &= 0xFFFFFF00; + + if (host_version == slave_version) { + log_i("Versions Match!"); + } else if (host_version > slave_version) { + log_w("Version on Host is NEWER than version on co-processor"); + log_w("Update URL: %s", hostedGetUpdateURL()); + return true; + } else { + log_w("Version on Host is OLDER than version on co-processor"); + } + return false; +} + +char * hostedGetUpdateURL() { + // https://espressif.github.io/arduino-esp32/hosted/esp32c6-v1.2.3.bin + static char url[92] = {0}; + snprintf(url, 92, "https://espressif.github.io/arduino-esp32/hosted/%s-v%" PRIu32 ".%" PRIu32 ".%" PRIu32 ".bin", + CONFIG_ESP_HOSTED_IDF_SLAVE_TARGET, host_version_struct.major1, host_version_struct.minor1, host_version_struct.patch1); + return url; +} + +bool hostedBeginUpdate() { + esp_err_t err = esp_hosted_slave_ota_begin(); + if (err != ESP_OK) { + log_e("Failed to begin Update: %s", esp_err_to_name(err)); + } + return err == ESP_OK; +} + +bool hostedWriteUpdate(uint8_t* buf, uint32_t len) { + esp_err_t err = esp_hosted_slave_ota_write(buf, len); + if (err != ESP_OK) { + log_e("Failed to write Update: %s", esp_err_to_name(err)); + } + return err == ESP_OK; +} + +bool hostedEndUpdate() { + esp_err_t err = esp_hosted_slave_ota_end(); + if (err != ESP_OK) { + log_e("Failed to end Update: %s", esp_err_to_name(err)); + } + return err == ESP_OK; +} + static bool hostedInit() { if (!hosted_initialized) { log_i("Initializing ESP-Hosted"); @@ -69,6 +155,12 @@ static bool hostedInit() { return false; } log_i("ESP-Hosted initialized!"); + if (esp_hosted_connect_to_slave() != ESP_OK) { + log_e("Failed to connect to slave"); + return false; + } + hostedHasUpdate(); + return true; } // Attach pins to PeriMan here diff --git a/cores/esp32/esp32-hal-hosted.h b/cores/esp32/esp32-hal-hosted.h index 0a916bfac85..686aa6a0700 100644 --- a/cores/esp32/esp32-hal-hosted.h +++ b/cores/esp32/esp32-hal-hosted.h @@ -44,6 +44,13 @@ bool hostedIsBLEActive(); bool hostedIsWiFiActive(); bool hostedSetPins(int8_t clk, int8_t cmd, int8_t d0, int8_t d1, int8_t d2, int8_t d3, int8_t rst); void hostedGetPins(int8_t *clk, int8_t *cmd, int8_t *d0, int8_t *d1, int8_t *d2, int8_t *d3, int8_t *rst); +void hostedGetHostVersion(uint32_t * major, uint32_t * minor, uint32_t * patch); +void hostedGetSlaveVersion(uint32_t * major, uint32_t * minor, uint32_t * patch); +bool hostedHasUpdate(); +char * hostedGetUpdateURL(); +bool hostedBeginUpdate(); +bool hostedWriteUpdate(uint8_t* buf, uint32_t len); +bool hostedEndUpdate(); #ifdef __cplusplus } From d37b613393ae92c05fd53b45bb5a13320b744aad Mon Sep 17 00:00:00 2001 From: me-no-dev Date: Mon, 27 Oct 2025 01:22:35 +0200 Subject: [PATCH 2/3] feat(hosted): Add hostedActivateUpdate() function --- cores/esp32/esp32-hal-hosted.c | 13 +++++++++++++ cores/esp32/esp32-hal-hosted.h | 1 + 2 files changed, 14 insertions(+) diff --git a/cores/esp32/esp32-hal-hosted.c b/cores/esp32/esp32-hal-hosted.c index f2bdf8fe923..26e1a53d532 100644 --- a/cores/esp32/esp32-hal-hosted.c +++ b/cores/esp32/esp32-hal-hosted.c @@ -132,6 +132,19 @@ bool hostedEndUpdate() { return err == ESP_OK; } +bool hostedActivateUpdate() { + esp_err_t err = esp_hosted_slave_ota_activate(); + if (err != ESP_OK) { + log_e("Failed to activate Update: %s", esp_err_to_name(err)); + } + // else { + // hostedDeinit(); + // delay(1000); + // hostedInit(); + // } + return err == ESP_OK; +} + static bool hostedInit() { if (!hosted_initialized) { log_i("Initializing ESP-Hosted"); diff --git a/cores/esp32/esp32-hal-hosted.h b/cores/esp32/esp32-hal-hosted.h index 686aa6a0700..abc1522cd31 100644 --- a/cores/esp32/esp32-hal-hosted.h +++ b/cores/esp32/esp32-hal-hosted.h @@ -51,6 +51,7 @@ char * hostedGetUpdateURL(); bool hostedBeginUpdate(); bool hostedWriteUpdate(uint8_t* buf, uint32_t len); bool hostedEndUpdate(); +bool hostedActivateUpdate(); #ifdef __cplusplus } From 6e1c1f9cb8158ffd58fedea34058a4b881c49124 Mon Sep 17 00:00:00 2001 From: me-no-dev Date: Mon, 27 Oct 2025 09:50:30 +0200 Subject: [PATCH 3/3] feat(hosted): Add new BLE init/deinit API calls --- cores/esp32/esp32-hal-hosted.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/cores/esp32/esp32-hal-hosted.c b/cores/esp32/esp32-hal-hosted.c index 26e1a53d532..70d3433a634 100644 --- a/cores/esp32/esp32-hal-hosted.c +++ b/cores/esp32/esp32-hal-hosted.c @@ -206,6 +206,19 @@ static bool hostedDeinit() { bool hostedInitBLE() { log_i("Initializing ESP-Hosted for BLE"); + if (!hostedInit()) { + return false; + } + esp_err_t err = esp_hosted_bt_controller_init(); + if (err != ESP_OK) { + log_e("esp_hosted_bt_controller_init failed: %s", esp_err_to_name(err)); + return false; + } + err = esp_hosted_bt_controller_enable(); + if (err != ESP_OK) { + log_e("esp_hosted_bt_controller_enable failed: %s", esp_err_to_name(err)); + return false; + } hosted_ble_active = true; return hostedInit(); } @@ -218,6 +231,16 @@ bool hostedInitWiFi() { bool hostedDeinitBLE() { log_i("Deinitializing ESP-Hosted for BLE"); + esp_err_t err = esp_hosted_bt_controller_disable(); + if (err != ESP_OK) { + log_e("esp_hosted_bt_controller_disable failed: %s", esp_err_to_name(err)); + return false; + } + err = esp_hosted_bt_controller_deinit(false); + if (err != ESP_OK) { + log_e("esp_hosted_bt_controller_deinit failed: %s", esp_err_to_name(err)); + return false; + } hosted_ble_active = false; if (!hosted_wifi_active) { return hostedDeinit();