mirror of https://github.com/arendst/Tasmota.git
Add EFR32 upload framework
This commit is contained in:
parent
520558d381
commit
806a862cac
|
@ -44,7 +44,7 @@ const uint16_t HTTP_OTA_RESTART_RECONNECT_TIME = 28000; // milliseconds - Allow
|
||||||
uint8_t *efm8bb1_update = nullptr;
|
uint8_t *efm8bb1_update = nullptr;
|
||||||
#endif // USE_RF_FLASH
|
#endif // USE_RF_FLASH
|
||||||
|
|
||||||
enum UploadTypes { UPL_TASMOTA, UPL_SETTINGS, UPL_EFM8BB1, UPL_TASMOTACLIENT };
|
enum UploadTypes { UPL_TASMOTA, UPL_SETTINGS, UPL_EFM8BB1, UPL_TASMOTACLIENT, UPL_EFR32 };
|
||||||
|
|
||||||
static const char * HEADER_KEYS[] = { "User-Agent", };
|
static const char * HEADER_KEYS[] = { "User-Agent", };
|
||||||
|
|
||||||
|
@ -2627,20 +2627,26 @@ void HandleUploadDone(void)
|
||||||
WSContentSend_P(PSTR("%06x'>" D_SUCCESSFUL "</font></b><br>"), WebColor(COL_TEXT_SUCCESS));
|
WSContentSend_P(PSTR("%06x'>" D_SUCCESSFUL "</font></b><br>"), WebColor(COL_TEXT_SUCCESS));
|
||||||
WSContentSend_P(HTTP_MSG_RSTRT);
|
WSContentSend_P(HTTP_MSG_RSTRT);
|
||||||
ShowWebSource(SRC_WEBGUI);
|
ShowWebSource(SRC_WEBGUI);
|
||||||
|
restart_flag = 2; // Always restart to re-enable disabled features during update
|
||||||
|
#if defined(USE_ZIGBEE) && defined(USE_ZIGBEE_EZSP)
|
||||||
|
if (ZigbeeUploadOtaReady()) {
|
||||||
|
restart_flag = 0; // Hold restart as firmware still needs to be written to MCU EFR32
|
||||||
|
}
|
||||||
|
#endif // USE_ZIGBEE and USE_ZIGBEE_EZSP
|
||||||
#ifdef USE_TASMOTA_CLIENT
|
#ifdef USE_TASMOTA_CLIENT
|
||||||
if (TasmotaClient_GetFlagFlashing()) {
|
if (TasmotaClient_GetFlagFlashing()) {
|
||||||
restart_flag = 0;
|
restart_flag = 0; // Hold restart as code still needs to be trasnferred to Atmega
|
||||||
} else { // It was a normal firmware file, or we are ready to restart device
|
|
||||||
restart_flag = 2;
|
|
||||||
}
|
}
|
||||||
#else
|
#endif // USE_TASMOTA_CLIENT
|
||||||
restart_flag = 2; // Always restart to re-enable disabled features during update
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
SettingsBufferFree();
|
SettingsBufferFree();
|
||||||
WSContentSend_P(PSTR("</div><br>"));
|
WSContentSend_P(PSTR("</div><br>"));
|
||||||
WSContentSpaceButton(BUTTON_MAIN);
|
WSContentSpaceButton(BUTTON_MAIN);
|
||||||
WSContentStop();
|
WSContentStop();
|
||||||
|
|
||||||
|
#if defined(USE_ZIGBEE) && defined(USE_ZIGBEE_EZSP)
|
||||||
|
ZigbeeUploadXmodem();
|
||||||
|
#endif // USE_ZIGBEE and USE_ZIGBEE_EZSP
|
||||||
#ifdef USE_TASMOTA_CLIENT
|
#ifdef USE_TASMOTA_CLIENT
|
||||||
if (TasmotaClient_GetFlagFlashing()) {
|
if (TasmotaClient_GetFlagFlashing()) {
|
||||||
TasmotaClient_Flash();
|
TasmotaClient_Flash();
|
||||||
|
@ -2707,6 +2713,15 @@ void HandleUploadLoop(void)
|
||||||
Web.config_block_count = 0;
|
Web.config_block_count = 0;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
#if defined(USE_ZIGBEE) && defined(USE_ZIGBEE_EZSP)
|
||||||
|
if ((SONOFF_ZB_BRIDGE == my_module_type) && (upload.buf[0] == 0xEB)) { // Check if this is a Zigbee bridge FW file
|
||||||
|
Update.end(); // End esp8266 update session
|
||||||
|
Web.upload_file_type = UPL_EFR32;
|
||||||
|
|
||||||
|
Web.upload_error = ZigbeeUploadInit(); // 15
|
||||||
|
if (Web.upload_error != 0) { return; }
|
||||||
|
} else
|
||||||
|
#endif // USE_ZIGBEE and USE_ZIGBEE_EZSP
|
||||||
#ifdef USE_RF_FLASH
|
#ifdef USE_RF_FLASH
|
||||||
if ((SONOFF_BRIDGE == my_module_type) && (upload.buf[0] == ':')) { // Check if this is a RF bridge FW file
|
if ((SONOFF_BRIDGE == my_module_type) && (upload.buf[0] == ':')) { // Check if this is a RF bridge FW file
|
||||||
Update.end(); // End esp8266 update session
|
Update.end(); // End esp8266 update session
|
||||||
|
@ -2750,6 +2765,15 @@ void HandleUploadLoop(void)
|
||||||
Web.config_block_count++;
|
Web.config_block_count++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#if defined(USE_ZIGBEE) && defined(USE_ZIGBEE_EZSP)
|
||||||
|
else if (UPL_EFR32 == Web.upload_file_type) {
|
||||||
|
// Write buffers to MCU EFR32
|
||||||
|
if (!ZigbeeUploadWriteBuffer(upload.buf, upload.currentSize)) {
|
||||||
|
Web.upload_error = 9; // File too large
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif // USE_ZIGBEE and USE_ZIGBEE_EZSP
|
||||||
#ifdef USE_RF_FLASH
|
#ifdef USE_RF_FLASH
|
||||||
else if (UPL_EFM8BB1 == Web.upload_file_type) {
|
else if (UPL_EFM8BB1 == Web.upload_file_type) {
|
||||||
if (efm8bb1_update != nullptr) { // We have carry over data since last write, i. e. a start but not an end
|
if (efm8bb1_update != nullptr) { // We have carry over data since last write, i. e. a start but not an end
|
||||||
|
@ -2844,6 +2868,13 @@ void HandleUploadLoop(void)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#if defined(USE_ZIGBEE) && defined(USE_ZIGBEE_EZSP)
|
||||||
|
else if (UPL_EFR32 == Web.upload_file_type) {
|
||||||
|
// Zigbee FW upload to ESP8266 flash is done
|
||||||
|
ZigbeeUploadDone(); // Signal upload done and ready for delayed upload to MCU EFR32
|
||||||
|
Web.upload_file_type = UPL_TASMOTA;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
#ifdef USE_RF_FLASH
|
#ifdef USE_RF_FLASH
|
||||||
else if (UPL_EFM8BB1 == Web.upload_file_type) {
|
else if (UPL_EFM8BB1 == Web.upload_file_type) {
|
||||||
// RF FW flash done
|
// RF FW flash done
|
||||||
|
|
|
@ -0,0 +1,121 @@
|
||||||
|
/*
|
||||||
|
xdrv_23_zigbee_9_serial.ino - zigbee: serial communication with MCU
|
||||||
|
|
||||||
|
Copyright (C) 2020 Theo Arends and Stephan Hadinger
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef USE_ZIGBEE
|
||||||
|
|
||||||
|
#ifdef USE_ZIGBEE_EZSP
|
||||||
|
/*********************************************************************************************\
|
||||||
|
* MCU EFR32 firmware upload using xmodem
|
||||||
|
*
|
||||||
|
* Step 1 - Upload MCU firmware in ESP8266 flash free space (current size is about 200k)
|
||||||
|
* Step 2 - Upload MCU firmware from ESP8266 flash to MCU EFR32 using XMODEM protocol
|
||||||
|
* Step 3 - Restart
|
||||||
|
\*********************************************************************************************/
|
||||||
|
|
||||||
|
const uint8_t PIN_ZIGBEE_BOOTLOADER = 5;
|
||||||
|
|
||||||
|
struct ZBUPLOAD {
|
||||||
|
uint32_t ota_size = 0;
|
||||||
|
uint32_t sector_cursor = 0;
|
||||||
|
uint32_t sector_counter = 0;
|
||||||
|
bool ota_ready = false;
|
||||||
|
} ZbUpload;
|
||||||
|
|
||||||
|
bool ZigbeeUploadOtaReady(void) {
|
||||||
|
return ZbUpload.ota_ready;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t ZigbeeUploadFlashStart(void) {
|
||||||
|
return (ESP.getSketchSize() / SPI_FLASH_SEC_SIZE) + 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t ZigbeeUploadInit(void) {
|
||||||
|
if (!PinUsed(GPIO_ZIGBEE_RST) && (ZigbeeSerial == nullptr)) { return 1; } // Wrong pin configuration - No file selected
|
||||||
|
|
||||||
|
ZbUpload.sector_counter = ZigbeeUploadFlashStart();
|
||||||
|
ZbUpload.sector_cursor = 0;
|
||||||
|
ZbUpload.ota_size = 0;
|
||||||
|
ZbUpload.ota_ready = false;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ZigbeeUploadWriteBuffer(uint8_t *buf, size_t size) {
|
||||||
|
// Read complete file into ESP8266 flash
|
||||||
|
// Current files are about 200k
|
||||||
|
if (0 == ZbUpload.sector_cursor) { // Starting a new sector write so we need to erase it first
|
||||||
|
ESP.flashEraseSector(ZbUpload.sector_counter);
|
||||||
|
}
|
||||||
|
ZbUpload.sector_cursor++;
|
||||||
|
ESP.flashWrite((ZbUpload.sector_counter * SPI_FLASH_SEC_SIZE) + ((ZbUpload.sector_cursor-1) * 2048), (uint32_t*)buf, size);
|
||||||
|
ZbUpload.ota_size += size;
|
||||||
|
if (2 == ZbUpload.sector_cursor) { // The web upload sends 2048 bytes at a time so keep track of the cursor position to reset it for the next flash sector erase
|
||||||
|
ZbUpload.sector_cursor = 0;
|
||||||
|
ZbUpload.sector_counter++;
|
||||||
|
if (ZbUpload.sector_counter > (SPIFFS_END + 12)) {
|
||||||
|
return false; // File too large - Not enough free space
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ZigbeeUploadDone(void) {
|
||||||
|
ZbUpload.ota_ready = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ZigbeeUploadSetBootloader(uint8_t state) {
|
||||||
|
pinMode(PIN_ZIGBEE_BOOTLOADER, OUTPUT);
|
||||||
|
digitalWrite(PIN_ZIGBEE_BOOTLOADER, state); // Toggle Gecko bootloader
|
||||||
|
digitalWrite(Pin(GPIO_ZIGBEE_RST), 0);
|
||||||
|
delay(100); // Need to experiment to find a value as low as possible
|
||||||
|
digitalWrite(Pin(GPIO_ZIGBEE_RST), 1); // Reboot MCU EFR32
|
||||||
|
}
|
||||||
|
|
||||||
|
void ZigbeeUploadXmodem(void) {
|
||||||
|
if (!ZbUpload.ota_ready) { return; }
|
||||||
|
|
||||||
|
// Copy uploaded OTA file from ESP8266 flash to MCU EFR32 using xmodem
|
||||||
|
uint32_t sector_counter = ZigbeeUploadFlashStart() * SPI_FLASH_SEC_SIZE;
|
||||||
|
|
||||||
|
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("ZIG: Upload start 0x%08X, size 0x%08X"), sector_counter, ZbUpload.ota_size);
|
||||||
|
|
||||||
|
// TODO - implement XMODEM upload
|
||||||
|
|
||||||
|
// ZigbeeUploadSetBootloader(1); // Reboot MCU EFR32 which returns below text
|
||||||
|
// Gecko Bootloader v1.A.3
|
||||||
|
// 1. upload gbl
|
||||||
|
// 2. run
|
||||||
|
// 3. ebl info
|
||||||
|
// BL >
|
||||||
|
// Use ZigbeeInputLoop to flush received data
|
||||||
|
|
||||||
|
// Send option 1 to prepare for xmodem upload
|
||||||
|
// ZigbeeSerial->write('1');
|
||||||
|
// ZigbeeSerial->write(0x0d);
|
||||||
|
// ZigbeeSerial->write(0x0a);
|
||||||
|
|
||||||
|
// Start xmodem upload
|
||||||
|
|
||||||
|
ZbUpload.ota_ready = false;
|
||||||
|
// ZigbeeUploadSetBootloader(0); // Disable bootloader and reset MCU
|
||||||
|
restart_flag = 2; // Restart to disable bootloader and use new firmware
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // USE_ZIGBEE_EZSP
|
||||||
|
|
||||||
|
#endif // USE_ZIGBEE
|
Loading…
Reference in New Issue