diff --git a/libraries/AP_HAL_ChibiOS/hwdef/common/flash.c b/libraries/AP_HAL_ChibiOS/hwdef/common/flash.c index 769eea67993709..5deb3e090da153 100644 --- a/libraries/AP_HAL_ChibiOS/hwdef/common/flash.c +++ b/libraries/AP_HAL_ChibiOS/hwdef/common/flash.c @@ -452,6 +452,57 @@ bool stm32_flash_ispageerased(uint32_t page) static uint32_t last_erase_ms; #endif +#if defined(STM32H7) + +/* + corrupt a flash to trigger ECC fault +*/ +void stm32_flash_corrupt(uint32_t addr) +{ + stm32_flash_unlock(); + + volatile uint32_t *CR = &FLASH->CR1; + volatile uint32_t *CCR = &FLASH->CCR1; + volatile uint32_t *SR = &FLASH->SR1; +#if STM32_FLASH_NBANKS > 1 + if (addr - STM32_FLASH_BASE >= STM32_FLASH_FIXED_PAGE_PER_BANK * STM32_FLASH_FIXED_PAGE_SIZE * 1024) { + CR = &FLASH->CR2; + CCR = &FLASH->CCR2; + SR = &FLASH->SR2; + } +#endif + stm32_flash_wait_idle(); + + *CCR = ~0; + *CR |= FLASH_CR_PG; + + for (uint32_t i=0; i<2; i++) { + while (*SR & (FLASH_SR_BSY|FLASH_SR_QW)) ; + putreg32(0xAAAA5555, addr); + addr += 4; + } + + *CR |= FLASH_CR_FW; // force write + stm32_flash_wait_idle(); + + for (uint32_t i=0; i<2; i++) { + while (*SR & (FLASH_SR_BSY|FLASH_SR_QW)) ; + putreg32(0x5555AAAA, addr); + addr += 4; + } + + *CR |= FLASH_CR_FW; // force write + stm32_flash_wait_idle(); + __DSB(); + + stm32_flash_wait_idle(); + *CCR = ~0; + *CR &= ~FLASH_CR_PG; + + stm32_flash_lock(); +} +#endif + /* erase a page */ diff --git a/libraries/AP_HAL_ChibiOS/hwdef/common/flash.h b/libraries/AP_HAL_ChibiOS/hwdef/common/flash.h index 7ec7c17031a2af..cbc7233aa6defe 100644 --- a/libraries/AP_HAL_ChibiOS/hwdef/common/flash.h +++ b/libraries/AP_HAL_ChibiOS/hwdef/common/flash.h @@ -30,6 +30,9 @@ bool stm32_flash_ispageerased(uint32_t page); void stm32_flash_protect_flash(bool bootloader, bool protect); void stm32_flash_unprotect_flash(void); void stm32_flash_set_NRST_MODE(uint8_t nrst_mode); +#if defined(STM32H7) +void stm32_flash_corrupt(uint32_t addr); +#endif #ifndef HAL_BOOTLOADER_BUILD bool stm32_flash_recent_erase(void); #endif