From c05f231b1378f6f16ecb7588af14473758ebf41a Mon Sep 17 00:00:00 2001 From: Gordon Williams Date: Tue, 15 Oct 2024 11:32:33 +0100 Subject: [PATCH] Bangle.js2: DFU update from flash now retries if CRC doesn't match --- ChangeLog | 1 + targets/nrf5x_dfu/flash.c | 86 +++++++++++++++++++++------------------ 2 files changed, 47 insertions(+), 40 deletions(-) diff --git a/ChangeLog b/ChangeLog index 3e5d38eea8..f811bc4944 100644 --- a/ChangeLog +++ b/ChangeLog @@ -43,6 +43,7 @@ Bangle.js2: GPS now detects binary CASIC packets and splits them into their own GPS-raw event Bangle.js2: Pass the modified touch event on through both E.showScroller and E.showMenu (to enable more complex interaction with menus). Bangle.js: Add Bangle.setOptions({manualWatchdog:true}) to enable users to supply their own JS watchdog + Bangle.js2: DFU update from flash now retries if CRC doesn't match 2v24 : Bangle.js2: Add 'Bangle.touchRd()', 'Bangle.touchWr()' Bangle.js2: After Bangle.showTestScreen, put Bangle.js into a hard off state (not soft off) diff --git a/targets/nrf5x_dfu/flash.c b/targets/nrf5x_dfu/flash.c index cfe46ef0e4..65ce2d1b92 100644 --- a/targets/nrf5x_dfu/flash.c +++ b/targets/nrf5x_dfu/flash.c @@ -264,48 +264,54 @@ void flashDoUpdate(FlashHeader header, uint32_t headerAddr) { __disable_irq(); // No IRQs - if we're updating bootloader it could really screw us up! - int percent = 0; - // Erase - size = header.size; - addr = header.address; - while (size>0) { - intFlashErase(addr); - addr += 4096; - size -= 4096; - percent = (addr-header.address)*120/header.size; - if (percent>120) percent=120; - xlcd_rect(60,182,60+percent,188,true); - NRF_WDT->RR[0] = 0x6E524635; // kick watchdog - } - // Write - size = header.size; - int inaddr = headerAddr + sizeof(FlashHeader); - int outaddr = header.address; - while (size>0) { - unsigned int l = size; - if (l>sizeof(buf)) l=sizeof(buf); - spiFlashReadAddr(buf, inaddr, l); - intFlashWrite(outaddr, buf, l); - inaddr += l; - outaddr += l; - size -= l; - percent = (outaddr-header.address)*120/header.size; - if (percent>120) percent=120; - xlcd_rect(60,192,60+percent,198,true); + while (true) { + int percent = 0; + // Erase + size = header.size; + addr = header.address; + while (size>0) { + intFlashErase(addr); + addr += 4096; + size -= 4096; + percent = (addr-header.address)*120/header.size; + if (percent>120) percent=120; + xlcd_rect(60,182,60+percent,188,true); + NRF_WDT->RR[0] = 0x6E524635; // kick watchdog + } + // Write + size = header.size; + int inaddr = headerAddr + sizeof(FlashHeader); + int outaddr = header.address; + while (size>0) { + unsigned int l = size; + if (l>sizeof(buf)) l=sizeof(buf); + spiFlashReadAddr(buf, inaddr, l); + intFlashWrite(outaddr, buf, l); + inaddr += l; + outaddr += l; + size -= l; + percent = (outaddr-header.address)*120/header.size; + if (percent>120) percent=120; + xlcd_rect(60,192,60+percent,198,true); + NRF_WDT->RR[0] = 0x6E524635; // kick watchdog + } + // clear progress bar + xlcd_rect(60,180,180,200,false); + // re-read all data to try and clear any caches (CRC does this anyway!) + lcd_println("CRC CHECK"); + uint32_t crc = 0; + crc = crc32_compute(header.address, header.size, &crc); NRF_WDT->RR[0] = 0x6E524635; // kick watchdog + if (crc != header.CRC) { + // if CRC failed, redo! + lcd_println("CRC FAIL! RETRY"); + } else { + // otherwise we're done! + lcd_println("CRC OK"); + while (true) NVIC_SystemReset(); // reset + } } - // clear progress bar - xlcd_rect(60,180,180,200,false); - // re-read all data just to try and clear any caches - size = header.size; - outaddr = header.address; - volatile int v; - while (size--) { - v = *(char*)outaddr; - outaddr++; - } - // done! - while (true) NVIC_SystemReset(); // reset! + } /// Return the size in bytes of a file based on the header