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;
|
||||
#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", };
|
||||
|
||||
|
@ -2627,20 +2627,26 @@ void HandleUploadDone(void)
|
|||
WSContentSend_P(PSTR("%06x'>" D_SUCCESSFUL "</font></b><br>"), WebColor(COL_TEXT_SUCCESS));
|
||||
WSContentSend_P(HTTP_MSG_RSTRT);
|
||||
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
|
||||
if (TasmotaClient_GetFlagFlashing()) {
|
||||
restart_flag = 0;
|
||||
} else { // It was a normal firmware file, or we are ready to restart device
|
||||
restart_flag = 2;
|
||||
restart_flag = 0; // Hold restart as code still needs to be trasnferred to Atmega
|
||||
}
|
||||
#else
|
||||
restart_flag = 2; // Always restart to re-enable disabled features during update
|
||||
#endif
|
||||
#endif // USE_TASMOTA_CLIENT
|
||||
}
|
||||
SettingsBufferFree();
|
||||
WSContentSend_P(PSTR("</div><br>"));
|
||||
WSContentSpaceButton(BUTTON_MAIN);
|
||||
WSContentStop();
|
||||
|
||||
#if defined(USE_ZIGBEE) && defined(USE_ZIGBEE_EZSP)
|
||||
ZigbeeUploadXmodem();
|
||||
#endif // USE_ZIGBEE and USE_ZIGBEE_EZSP
|
||||
#ifdef USE_TASMOTA_CLIENT
|
||||
if (TasmotaClient_GetFlagFlashing()) {
|
||||
TasmotaClient_Flash();
|
||||
|
@ -2707,6 +2713,15 @@ void HandleUploadLoop(void)
|
|||
Web.config_block_count = 0;
|
||||
}
|
||||
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
|
||||
if ((SONOFF_BRIDGE == my_module_type) && (upload.buf[0] == ':')) { // Check if this is a RF bridge FW file
|
||||
Update.end(); // End esp8266 update session
|
||||
|
@ -2750,6 +2765,15 @@ void HandleUploadLoop(void)
|
|||
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
|
||||
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
|
||||
|
@ -2844,6 +2868,13 @@ void HandleUploadLoop(void)
|
|||
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
|
||||
else if (UPL_EFM8BB1 == Web.upload_file_type) {
|
||||
// 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