hal: flash: added 3 seconds timeout when waiting for C2 to unlock flash controller. On timeout, triggers furi_check

This commit is contained in:
hedger
2023-04-23 00:48:47 +04:00
parent a782a5ad29
commit ffae861bc2

View File

@@ -27,6 +27,16 @@
#define FURI_HAL_FLASH_OPT_KEY2 0x4C5D6E7F #define FURI_HAL_FLASH_OPT_KEY2 0x4C5D6E7F
#define FURI_HAL_FLASH_OB_TOTAL_WORDS (0x80 / (sizeof(uint32_t) * 2)) #define FURI_HAL_FLASH_OB_TOTAL_WORDS (0x80 / (sizeof(uint32_t) * 2))
/* lib/STM32CubeWB/Projects/P-NUCLEO-WB55.Nucleo/Applications/BLE/BLE_RfWithFlash/Core/Src/flash_driver.c
* ProcessSingleFlashOperation, quote:
> In most BLE application, the flash should not be blocked by the CPU2 longer than FLASH_TIMEOUT_VALUE (1000ms)
> However, it could be that for some marginal application, this time is longer.
> ... there is no other way than waiting the operation to be completed.
> If for any reason this test is never passed, this means there is a failure in the system and there is no other
> way to recover than applying a device reset.
*/
#define FURI_HAL_FLASH_C2_LOCK_TIMEOUT_MS 3000u /* 3 seconds */
#define IS_ADDR_ALIGNED_64BITS(__VALUE__) (((__VALUE__)&0x7U) == (0x00UL)) #define IS_ADDR_ALIGNED_64BITS(__VALUE__) (((__VALUE__)&0x7U) == (0x00UL))
#define IS_FLASH_PROGRAM_ADDRESS(__VALUE__) \ #define IS_FLASH_PROGRAM_ADDRESS(__VALUE__) \
(((__VALUE__) >= FLASH_BASE) && ((__VALUE__) <= (FLASH_BASE + FLASH_SIZE - 8UL)) && \ (((__VALUE__) >= FLASH_BASE) && ((__VALUE__) <= (FLASH_BASE + FLASH_SIZE - 8UL)) && \
@@ -132,9 +142,11 @@ static void furi_hal_flash_begin_with_core2(bool erase_flag) {
for(volatile uint32_t i = 0; i < 35; i++) for(volatile uint32_t i = 0; i < 35; i++)
; ;
FuriHalCortexTimer timer = furi_hal_cortex_timer_get(FURI_HAL_FLASH_C2_LOCK_TIMEOUT_MS * 1000);
while(true) { while(true) {
/* Wait till flash controller become usable */ /* Wait till flash controller become usable */
while(LL_FLASH_IsActiveFlag_OperationSuspended()) { while(LL_FLASH_IsActiveFlag_OperationSuspended()) {
furi_check(!furi_hal_cortex_timer_is_expired(timer));
furi_thread_yield(); furi_thread_yield();
}; };
@@ -144,6 +156,7 @@ static void furi_hal_flash_begin_with_core2(bool erase_flag) {
/* Actually we already have mutex for it, but specification is specification */ /* Actually we already have mutex for it, but specification is specification */
if(LL_HSEM_IsSemaphoreLocked(HSEM, CFG_HW_BLOCK_FLASH_REQ_BY_CPU1_SEMID)) { if(LL_HSEM_IsSemaphoreLocked(HSEM, CFG_HW_BLOCK_FLASH_REQ_BY_CPU1_SEMID)) {
taskEXIT_CRITICAL(); taskEXIT_CRITICAL();
furi_check(!furi_hal_cortex_timer_is_expired(timer));
furi_thread_yield(); furi_thread_yield();
continue; continue;
} }
@@ -151,6 +164,7 @@ static void furi_hal_flash_begin_with_core2(bool erase_flag) {
/* Take sempahopre and prevent core2 from anything funky */ /* Take sempahopre and prevent core2 from anything funky */
if(LL_HSEM_1StepLock(HSEM, CFG_HW_BLOCK_FLASH_REQ_BY_CPU2_SEMID) != 0) { if(LL_HSEM_1StepLock(HSEM, CFG_HW_BLOCK_FLASH_REQ_BY_CPU2_SEMID) != 0) {
taskEXIT_CRITICAL(); taskEXIT_CRITICAL();
furi_check(!furi_hal_cortex_timer_is_expired(timer));
furi_thread_yield(); furi_thread_yield();
continue; continue;
} }
@@ -237,7 +251,6 @@ bool furi_hal_flash_wait_last_operation(uint32_t timeout) {
Even if the FLASH operation fails, the BUSY flag will be reset and an error Even if the FLASH operation fails, the BUSY flag will be reset and an error
flag will be set */ flag will be set */
FuriHalCortexTimer timer = furi_hal_cortex_timer_get(timeout * 1000); FuriHalCortexTimer timer = furi_hal_cortex_timer_get(timeout * 1000);
while(READ_BIT(FLASH->SR, FLASH_SR_BSY)) { while(READ_BIT(FLASH->SR, FLASH_SR_BSY)) {
if(furi_hal_cortex_timer_is_expired(timer)) { if(furi_hal_cortex_timer_is_expired(timer)) {
return false; return false;
@@ -263,7 +276,6 @@ bool furi_hal_flash_wait_last_operation(uint32_t timeout) {
/* Wait for control register to be written */ /* Wait for control register to be written */
timer = furi_hal_cortex_timer_get(timeout * 1000); timer = furi_hal_cortex_timer_get(timeout * 1000);
while(READ_BIT(FLASH->SR, FLASH_SR_CFGBSY)) { while(READ_BIT(FLASH->SR, FLASH_SR_CFGBSY)) {
if(furi_hal_cortex_timer_is_expired(timer)) { if(furi_hal_cortex_timer_is_expired(timer)) {
return false; return false;