From 7b9f8f6c8679955f5ea26004c12b14abe3de4499 Mon Sep 17 00:00:00 2001 From: bugobliterator Date: Thu, 18 Jul 2024 16:20:01 +1000 Subject: [PATCH] AP_Bootloader: add ecc check while in bootloader --- AP_Bootloader/AP_Bootloader.cpp | 4 ++- AP_Bootloader/support.cpp | 50 +++++++++++++++++++++++++++++++++ AP_Bootloader/support.h | 4 +++ 3 files changed, 57 insertions(+), 1 deletion(-) diff --git a/AP_Bootloader/AP_Bootloader.cpp b/AP_Bootloader/AP_Bootloader.cpp index 1d11906..271fe03 100644 --- a/AP_Bootloader/AP_Bootloader.cpp +++ b/AP_Bootloader/AP_Bootloader.cpp @@ -171,7 +171,9 @@ int main(void) can_start(); #endif flash_init(); - +#ifdef STM32H7 + check_ecc_errors(); +#endif #if EXT_FLASH_SIZE_MB while (!ext_flash.init()) { diff --git a/AP_Bootloader/support.cpp b/AP_Bootloader/support.cpp index b1382d2..7b84fe3 100644 --- a/AP_Bootloader/support.cpp +++ b/AP_Bootloader/support.cpp @@ -485,3 +485,53 @@ void port_setbaud(uint32_t baudrate) #endif } #endif // BOOTLOADER_DEV_LIST + + +#ifdef STM32H7 +/* + check if flash has any ECC errors and if it does then erase all of + flash + */ +#define ECC_CHECK_CHUNK_SIZE 32 +void check_ecc_errors(void) +{ + __disable_fault_irq(); + auto *dma = dmaStreamAlloc(STM32_DMA_STREAM_ID(1, 1), 0, nullptr, nullptr); + + uint32_t *buf = (uint32_t*)malloc_dma(ECC_CHECK_CHUNK_SIZE); + + if (buf == nullptr) { + // DMA'ble memory not available + return; + } + uint32_t ofs = 0; + while (ofs < BOARD_FLASH_SIZE*1024) { + if (FLASH->SR1 != 0) { + break; + } +#if BOARD_FLASH_SIZE > 1024 + if (FLASH->SR2 != 0) { + break; + } +#endif + dmaStartMemCopy(dma, + STM32_DMA_CR_PL(0) | STM32_DMA_CR_PSIZE_BYTE | + STM32_DMA_CR_MSIZE_BYTE, + ofs+(uint8_t*)FLASH_BASE, buf, sizeof(buf)); + dmaWaitCompletion(dma); + ofs += sizeof(buf); + } + dmaStreamFree(dma); + + if (ofs < BOARD_FLASH_SIZE*1024) { + // we must have ECC errors in flash + flash_set_keep_unlocked(true); + for (uint32_t i=0; i