@@ -123,7 +123,12 @@ int ArduinoIoTCloudTCP::begin(String brokerAddress, uint16_t brokerPort)
123
123
* The bootloader is excluded from the calculation and occupies flash address
124
124
* range 0 to 0x2000, total flash size of 0x40000 bytes (256 kByte).
125
125
*/
126
+ #if defined(ARDUINO_PORTENTA_H7_M7)
127
+ // TODO: check if we need to checksum the whole flash or just the first megabyte
128
+ _ota_img_sha256 = FlashSHA256::calc (0x8040000 , 0x200000 - 0x40000 );
129
+ #else
126
130
_ota_img_sha256 = FlashSHA256::calc (0x2000 , 0x40000 - 0x2000 );
131
+ #endif
127
132
#endif /* OTA_ENABLED */
128
133
129
134
#ifdef BOARD_HAS_OFFLOADED_ECCX08
@@ -186,6 +191,21 @@ int ArduinoIoTCloudTCP::begin(String brokerAddress, uint16_t brokerPort)
186
191
addPropertyReal (_ota_req, " OTA_REQ" , Permission::ReadWrite).onSync (DEVICE_WINS);
187
192
#endif /* OTA_ENABLED */
188
193
194
+ #if OTA_STORAGE_PORTENTA_QSPI
195
+ #define BOOTLOADER_ADDR (0x8000000 )
196
+ uint32_t bootloader_data_offset = 0x1F000 ;
197
+ uint8_t * bootloader_data = (uint8_t *)(BOOTLOADER_ADDR + bootloader_data_offset);
198
+ uint8_t currentBootloaderVersion = bootloader_data[1 ];
199
+ if (currentBootloaderVersion < 22 ) {
200
+ _ota_cap = false ;
201
+ DEBUG_WARNING (" ArduinoIoTCloudTCP::%s In order to be ready for cloud OTA, update the bootloader" , __FUNCTION__);
202
+ DEBUG_WARNING (" ArduinoIoTCloudTCP::%s File -> Examples -> Portenta_System -> PortentaH7_updateBootloader" , __FUNCTION__);
203
+ }
204
+ else {
205
+ _ota_cap = true ;
206
+ }
207
+ #endif
208
+
189
209
#if OTA_STORAGE_SNU && OTA_ENABLED
190
210
String const nina_fw_version = WiFi.firmwareVersion ();
191
211
if (nina_fw_version < " 1.4.1" ) {
@@ -443,11 +463,6 @@ void ArduinoIoTCloudTCP::onOTARequest()
443
463
{
444
464
DEBUG_VERBOSE (" ArduinoIoTCloudTCP::%s _ota_url = %s" , __FUNCTION__, _ota_url.c_str ());
445
465
446
- /* Status flag to prevent the reset from being executed
447
- * when HTTPS download is not supported.
448
- */
449
- bool ota_download_success = false ;
450
-
451
466
#if OTA_STORAGE_SNU
452
467
/* Just to be safe delete any remains from previous updates. */
453
468
WiFiStorage.remove (" /fs/UPDATE.BIN.LZSS" );
@@ -462,15 +477,47 @@ void ArduinoIoTCloudTCP::onOTARequest()
462
477
return ;
463
478
}
464
479
465
- /* The download was a success . */
466
- ota_download_success = true ;
480
+ /* Perform the reset to reboot to SxU . */
481
+ NVIC_SystemReset () ;
467
482
#endif /* OTA_STORAGE_SNU */
468
483
469
- #ifndef __AVR__
470
- /* Perform the reset to reboot to SxU. */
471
- if (ota_download_success)
472
- NVIC_SystemReset ();
473
- #endif
484
+ #if OTA_STORAGE_PORTENTA_QSPI
485
+ Arduino_Portenta_OTA::Error ota_portenta_err = Arduino_Portenta_OTA::Error::None;
486
+ /* Use 2nd partition of QSPI (1st partition contains WiFi firmware) */
487
+ Arduino_Portenta_OTA_QSPI ota_portenta_qspi (QSPI_FLASH_FATFS_MBR, 2 );
488
+
489
+ /* Initialize the QSPI memory for OTA handling. */
490
+ if ((ota_portenta_err = ota_portenta_qspi.begin ()) != Arduino_Portenta_OTA::Error::None) {
491
+ DEBUG_ERROR (" Arduino_Portenta_OTA_QSPI::begin() failed with %d" , static_cast <int >(ota_portenta_err));
492
+ return ;
493
+ }
494
+
495
+ /* Just to be safe delete any remains from previous updates. */
496
+ remove (" /fs/UPDATE.BIN" );
497
+ remove (" /fs/UPDATE.BIN.LZSS" );
498
+
499
+ /* Download the OTA file from the web storage location. */
500
+ int const ota_portenta_qspi_download_ret_code = ota_portenta_qspi.download ((char *)(_ota_url.c_str ()), true /* is_https */ );
501
+ DEBUG_VERBOSE (" Arduino_Portenta_OTA_QSPI::download(%s) returns %d" , _ota_url.c_str (), ota_portenta_qspi_download_ret_code);
502
+
503
+ /* Decompress the LZSS compressed OTA file. */
504
+ int const ota_portenta_qspi_decompress_ret_code = ota_portenta_qspi.decompress ();
505
+ DEBUG_VERBOSE (" Arduino_Portenta_OTA_QSPI::decompress() returns %d" , ota_portenta_qspi_decompress_ret_code);
506
+ if (ota_portenta_qspi_decompress_ret_code < 0 )
507
+ {
508
+ DEBUG_ERROR (" Arduino_Portenta_OTA_QSPI::decompress() failed with %d" , ota_portenta_qspi_decompress_ret_code);
509
+ return ;
510
+ }
511
+
512
+ /* Schedule the firmware update. */
513
+ if ((ota_portenta_err = ota_portenta_qspi.update ()) != Arduino_Portenta_OTA::Error::None) {
514
+ DEBUG_ERROR (" Arduino_Portenta_OTA_QSPI::update() failed with %d" , static_cast <int >(ota_portenta_err));
515
+ return ;
516
+ }
517
+
518
+ /* Perform the reset to reboot - then the bootloader performs the actual application update. */
519
+ NVIC_SystemReset ();
520
+ #endif /* OTA_STORAGE_PORTENTA_QSPI */
474
521
}
475
522
#endif
476
523
0 commit comments