Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ set(ARDUINO_ALL_LIBRARIES
ESP_I2S
ESP_NOW
ESP_SR
ESP_HostedOTA
ESPmDNS
Ethernet
FFat
Expand Down Expand Up @@ -146,6 +147,9 @@ set(ARDUINO_LIBRARY_ESP_SR_SRCS
libraries/ESP_SR/src/ESP_SR.cpp
libraries/ESP_SR/src/esp32-hal-sr.c)

set(ARDUINO_LIBRARY_ESP_HostedOTA_SRCS
libraries/ESP_HostedOTA/src/ESP_HostedOTA.cpp)

set(ARDUINO_LIBRARY_ESPmDNS_SRCS libraries/ESPmDNS/src/ESPmDNS.cpp)

set(ARDUINO_LIBRARY_Ethernet_SRCS libraries/Ethernet/src/ETH.cpp)
Expand Down
70 changes: 58 additions & 12 deletions cores/esp32/esp32-hal-hosted.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

#include "esp32-hal-hosted.h"
#include "esp32-hal-log.h"
#include "esp32-hal.h"
#include "pins_arduino.h"

#include "esp_hosted.h"
Expand Down Expand Up @@ -53,6 +54,9 @@ 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
};

static bool hostedInit();
static bool hostedDeinit();

void hostedGetHostVersion(uint32_t *major, uint32_t *minor, uint32_t *patch) {
*major = host_version_struct.major1;
*minor = host_version_struct.minor1;
Expand All @@ -66,6 +70,11 @@ void hostedGetSlaveVersion(uint32_t *major, uint32_t *minor, uint32_t *patch) {
}

bool hostedHasUpdate() {
if (!hosted_initialized) {
log_e("ESP-Hosted is not initialized");
return false;
}

uint32_t host_version = ESP_HOSTED_VERSION_VAL(host_version_struct.major1, host_version_struct.minor1, host_version_struct.patch1);
uint32_t slave_version = 0;

Expand Down Expand Up @@ -106,6 +115,11 @@ char *hostedGetUpdateURL() {
}

bool hostedBeginUpdate() {
if (!hosted_initialized) {
log_e("ESP-Hosted is not initialized");
return false;
}

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));
Expand All @@ -114,6 +128,11 @@ bool hostedBeginUpdate() {
}

bool hostedWriteUpdate(uint8_t *buf, uint32_t len) {
if (!hosted_initialized) {
log_e("ESP-Hosted is not initialized");
return false;
}

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));
Expand All @@ -122,6 +141,11 @@ bool hostedWriteUpdate(uint8_t *buf, uint32_t len) {
}

bool hostedEndUpdate() {
if (!hosted_initialized) {
log_e("ESP-Hosted is not initialized");
return false;
}

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));
Expand All @@ -130,16 +154,31 @@ bool hostedEndUpdate() {
}

bool hostedActivateUpdate() {
if (!hosted_initialized) {
log_e("ESP-Hosted is not initialized");
return false;
}

// Activate can fail on older firmwares and that is not critical
uint32_t slave_version = ESP_HOSTED_VERSION_VAL(slave_version_struct.major1, slave_version_struct.minor1, slave_version_struct.patch1);
uint32_t min_version = ESP_HOSTED_VERSION_VAL(2, 6, 0);

if (slave_version < min_version) {
// Silence messages caused by earlier versions
esp_log_level_set("rpc_core", ESP_LOG_NONE);
}

esp_err_t err = esp_hosted_slave_ota_activate();
if (err != ESP_OK) {

// Any further communication will result in logged errors
esp_log_level_set("sdmmc_io", ESP_LOG_NONE);
esp_log_level_set("H_SDIO_DRV", ESP_LOG_NONE);

if (err != ESP_OK && slave_version >= min_version) {
log_e("Failed to activate Update: %s", esp_err_to_name(err));
return false;
}
// else {
// hostedDeinit();
// delay(1000);
// hostedInit();
// }
return err == ESP_OK;
return true;
}

static bool hostedInit() {
Expand All @@ -158,15 +197,22 @@ static bool hostedInit() {
conf.pin_d2.pin = sdio_pin_config.pin_d2;
conf.pin_d3.pin = sdio_pin_config.pin_d3;
conf.pin_reset.pin = sdio_pin_config.pin_reset;
// esp_hosted_sdio_set_config() will fail on second attempt but here temporarily to not cause exception on reinit
if (esp_hosted_sdio_set_config(&conf) != ESP_OK || esp_hosted_init() != ESP_OK) {
log_e("esp_hosted_init failed!");
esp_err_t err = esp_hosted_sdio_set_config(&conf);
if (err != ESP_OK) { //&& err != ESP_ERR_NOT_ALLOWED) { // uncomment when second init is fixed
log_e("esp_hosted_sdio_set_config failed: %s", esp_err_to_name(err));
return false;
}
err = esp_hosted_init();
if (err != ESP_OK) {
log_e("esp_hosted_init failed: %s", esp_err_to_name(err));
hosted_initialized = false;
return false;
}
log_i("ESP-Hosted initialized!");
if (esp_hosted_connect_to_slave() != ESP_OK) {
log_e("Failed to connect to slave");
err = esp_hosted_connect_to_slave();
if (err != ESP_OK) {
log_e("esp_hosted_connect_to_slave failed: %s", esp_err_to_name(err));
hosted_initialized = false;
return false;
}
hostedHasUpdate();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#include "WiFi.h"
#include "ESP_HostedOTA.h"

const char *ssid = "your-ssid"; // Change this to your WiFi SSID
const char *password = "your-password"; // Change this to your WiFi password

void setup() {
Serial.begin(115200);

WiFi.STA.begin();

Serial.println();
Serial.println("******************************************************");
Serial.print("Connecting to ");
Serial.println(ssid);

WiFi.STA.connect(ssid, password);

while (WiFi.STA.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println();

Serial.println("WiFi connected");
Serial.print("IP address: ");
Serial.println(WiFi.STA.localIP());

if (updateEspHostedSlave()) {
// Currently it's required to restart the host
ESP.restart();
}
}

void loop() {
delay(1000);
}
17 changes: 17 additions & 0 deletions libraries/ESP_HostedOTA/keywords.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#######################################
# Syntax Coloring Map For ESP_HostedOTA
#######################################

#######################################
# Datatypes (KEYWORD1)
#######################################

#######################################
# Methods and Functions (KEYWORD2)
#######################################

updateEspHostedSlave KEYWORD2

#######################################
# Constants (LITERAL1)
#######################################
9 changes: 9 additions & 0 deletions libraries/ESP_HostedOTA/library.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
name=ESP_HostedOTA
version=3.3.4
author=me-no-dev
maintainer=me-no-dev
sentence=Library for updating the ESP-Hosted co-processor
paragraph=Supports ESP32 Arduino platforms.
category=Communication
url=https://github.com/espressif/arduino-esp32/
architectures=esp32
104 changes: 104 additions & 0 deletions libraries/ESP_HostedOTA/src/ESP_HostedOTA.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
#include "sdkconfig.h"
#if CONFIG_ESP_WIFI_REMOTE_ENABLED
#include "Arduino.h"
#include "esp32-hal-hosted.h"
#include "Network.h"
#include "HTTPClient.h"
#include "NetworkClientSecure.h"
#endif

bool updateEspHostedSlave() {
#if CONFIG_ESP_WIFI_REMOTE_ENABLED
bool updateSuccess = false;
if (!hostedIsInitialized()) {
Serial.println("ERROR: esp-hosted is not initialized. Did you call WiFi.STA.begin()?");
return updateSuccess;
}
if (!hostedHasUpdate()) {
// esp-hosted is already the latest version
return updateSuccess;
}
if (!Network.isOnline()) {
Serial.println("ERROR: Network is not online! Did you call WiFi.STA.connect(ssid, password)?");
return updateSuccess;
}
Serial.print("Updating esp-hosted co-processor from ");
Serial.println(hostedGetUpdateURL());
NetworkClientSecure *client = new NetworkClientSecure();
if (!client) {
Serial.println("ERROR: Could not allocate client!");
return updateSuccess;
}
client->setInsecure();
HTTPClient https;
int httpCode = 0;
if (!https.begin(*client, hostedGetUpdateURL())) {
Serial.println("ERROR: HTTP begin failed!");
goto finish_ota;
}
httpCode = https.GET();
if (httpCode == HTTP_CODE_OK) {
int len = https.getSize();
if (len < 0) {
Serial.println("ERROR: Update size not received!");
https.end();
goto finish_ota;
}
NetworkClient *stream = https.getStreamPtr();
if (!hostedBeginUpdate()) {
Serial.println("ERROR: esp-hosted update start failed!");
https.end();
goto finish_ota;
}
#define HOSTED_OTA_BUF_SIZE 2048
uint8_t * buff = (uint8_t*)malloc(HOSTED_OTA_BUF_SIZE);
if (!buff) {
Serial.println("ERROR: Could not allocate OTA buffer!");
https.end();
goto finish_ota;
}
while (https.connected() && len > 0) {
size_t size = stream->available();
if (size > 0) {
Serial.print(".");
if (size > HOSTED_OTA_BUF_SIZE) {
size = HOSTED_OTA_BUF_SIZE;
}
if (size > len) {
Serial.printf("\nERROR: Update received extra bytes: %u!", size - len);
break;
}
int readLen = stream->readBytes(buff, size);
len -= readLen;
if (!hostedWriteUpdate(buff, readLen)) {
Serial.println("\nERROR: esp-hosted update write failed!");
break;
}
if (len == 0) {
if (!hostedEndUpdate()) {
Serial.println("\nERROR: esp-hosted update end failed!");
break;
}
if (!hostedActivateUpdate()) {
Serial.println("\nERROR: esp-hosted update activate failed!");
break;
}
updateSuccess = true;
Serial.println("\nSUCCESS: esp-hosted co-processor updated!");
break;
}
}
delay(1);
}
free(buff);
Serial.println();
}

https.end();
finish_ota:
delete client;
return updateSuccess;
#else
return false;
#endif
}
5 changes: 5 additions & 0 deletions libraries/ESP_HostedOTA/src/ESP_HostedOTA.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#pragma once

#include <stdbool.h>

bool updateEspHostedSlave();
Loading