/** * @brief Perform a mass erase or erase the specified FLASH memory sectors * @param[in] pEraseInit: pointer to an FLASH_EraseInitTypeDef structure that * contains the configuration information for the erasing. * * @param[out] SectorError: pointer to variable that * contains the configuration information on faulty sector in case of error * (0xFFFFFFFF means that all the sectors have been correctly erased) * * @retval HAL Status */ HAL_StatusTypeDef HAL_FLASHEx_Erase(FLASH_EraseInitTypeDef *pEraseInit, uint32_t *SectorError) { HAL_StatusTypeDef status = HAL_ERROR; uint32_t index = 0; /* Process Locked */ __HAL_LOCK(&pFlash); /* Check the parameters */ assert_param(IS_FLASH_TYPEERASE(pEraseInit->TypeErase)); /* Wait for last operation to be completed */ status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE); if(status == HAL_OK) { /*Initialization of SectorError variable*/ *SectorError = 0xFFFFFFFF; if(pEraseInit->TypeErase == FLASH_TYPEERASE_MASSERASE) { /*Mass erase to be done*/ FLASH_MassErase((uint8_t) pEraseInit->VoltageRange, pEraseInit->Banks); /* Wait for last operation to be completed */ status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE); /* if the erase operation is completed, disable the MER Bit */ FLASH->CR &= (~FLASH_MER_BIT); } else { /* Check the parameters */ assert_param(IS_FLASH_NBSECTORS(pEraseInit->NbSectors + pEraseInit->Sector)); /* Erase by sector by sector to be done*/ for(index = pEraseInit->Sector; index < (pEraseInit->NbSectors + pEraseInit->Sector); index++) { FLASH_Erase_Sector(index, (uint8_t) pEraseInit->VoltageRange); /* Wait for last operation to be completed */ status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE); /* If the erase operation is completed, disable the SER and SNB Bits */ CLEAR_BIT(FLASH->CR, (FLASH_CR_SER | FLASH_CR_SNB)); if(status != HAL_OK) { /* In case of error, stop erase procedure and return the faulty sector*/ *SectorError = index; break; } } } /* Flush the caches to be sure of the data consistency */ FLASH_FlushCaches(); } /* Process Unlocked */ __HAL_UNLOCK(&pFlash); return status; }
/** * @brief This function handles FLASH interrupt request. * @retval None */ void HAL_FLASH_IRQHandler(void) { uint32_t addresstmp = 0U; /* Check FLASH operation error flags */ if(__HAL_FLASH_GET_FLAG((FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR | \ FLASH_FLAG_PGPERR | FLASH_FLAG_PGSERR | FLASH_FLAG_RDERR)) != RESET) { if(pFlash.ProcedureOnGoing == FLASH_PROC_SECTERASE) { /*return the faulty sector*/ addresstmp = pFlash.Sector; pFlash.Sector = 0xFFFFFFFFU; } else if(pFlash.ProcedureOnGoing == FLASH_PROC_MASSERASE) { /*return the faulty bank*/ addresstmp = pFlash.Bank; } else { /*return the faulty address*/ addresstmp = pFlash.Address; } /*Save the Error code*/ FLASH_SetErrorCode(); /* FLASH error interrupt user callback */ HAL_FLASH_OperationErrorCallback(addresstmp); /*Stop the procedure ongoing*/ pFlash.ProcedureOnGoing = FLASH_PROC_NONE; } /* Check FLASH End of Operation flag */ if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_EOP) != RESET) { /* Clear FLASH End of Operation pending bit */ __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP); if(pFlash.ProcedureOnGoing == FLASH_PROC_SECTERASE) { /*Nb of sector to erased can be decreased*/ pFlash.NbSectorsToErase--; /* Check if there are still sectors to erase*/ if(pFlash.NbSectorsToErase != 0U) { addresstmp = pFlash.Sector; /*Indicate user which sector has been erased*/ HAL_FLASH_EndOfOperationCallback(addresstmp); /*Increment sector number*/ pFlash.Sector++; addresstmp = pFlash.Sector; FLASH_Erase_Sector(addresstmp, pFlash.VoltageForErase); } else { /*No more sectors to Erase, user callback can be called.*/ /*Reset Sector and stop Erase sectors procedure*/ pFlash.Sector = addresstmp = 0xFFFFFFFFU; pFlash.ProcedureOnGoing = FLASH_PROC_NONE; /* Flush the caches to be sure of the data consistency */ FLASH_FlushCaches() ; /* FLASH EOP interrupt user callback */ HAL_FLASH_EndOfOperationCallback(addresstmp); } } else { if(pFlash.ProcedureOnGoing == FLASH_PROC_MASSERASE) { /* MassErase ended. Return the selected bank */ /* Flush the caches to be sure of the data consistency */ FLASH_FlushCaches() ; /* FLASH EOP interrupt user callback */ HAL_FLASH_EndOfOperationCallback(pFlash.Bank); } else { /*Program ended. Return the selected address*/ /* FLASH EOP interrupt user callback */ HAL_FLASH_EndOfOperationCallback(pFlash.Address); } pFlash.ProcedureOnGoing = FLASH_PROC_NONE; } } if(pFlash.ProcedureOnGoing == FLASH_PROC_NONE) { /* Operation is completed, disable the PG, SER, SNB and MER Bits */ CLEAR_BIT(FLASH->CR, (FLASH_CR_PG | FLASH_CR_SER | FLASH_CR_SNB | FLASH_MER_BIT)); /* Disable End of FLASH Operation interrupt */ __HAL_FLASH_DISABLE_IT(FLASH_IT_EOP); /* Disable Error source interrupt */ __HAL_FLASH_DISABLE_IT(FLASH_IT_ERR); /* Process Unlocked */ __HAL_UNLOCK(&pFlash); } }
/** * @brief Handle FLASH interrupt request. * @retval None */ void HAL_FLASH_IRQHandler(void) { uint32_t tmp_page; /* If the operation is completed, disable the PG, PNB, MER1, MER2 and PER Bit */ CLEAR_BIT(FLASH->CR, (FLASH_CR_PG | FLASH_CR_MER1 | FLASH_CR_MER2 | FLASH_CR_PER | FLASH_CR_PNB)); /* Disable the FSTPG Bit only if it is the last row programmed */ if(pFlash.ProcedureOnGoing == FLASH_PROC_PROGRAM_LAST) { CLEAR_BIT(FLASH->CR, FLASH_CR_FSTPG); } /* Check FLASH operation error flags */ if((__HAL_FLASH_GET_FLAG(FLASH_FLAG_OPERR)) || (__HAL_FLASH_GET_FLAG(FLASH_FLAG_PROGERR)) || (__HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR)) || (__HAL_FLASH_GET_FLAG(FLASH_FLAG_PGAERR)) || (__HAL_FLASH_GET_FLAG(FLASH_FLAG_SIZERR)) || (__HAL_FLASH_GET_FLAG(FLASH_FLAG_PGSERR)) || (__HAL_FLASH_GET_FLAG(FLASH_FLAG_MISERR)) || (__HAL_FLASH_GET_FLAG(FLASH_FLAG_FASTERR)) || (__HAL_FLASH_GET_FLAG(FLASH_FLAG_RDERR)) || (__HAL_FLASH_GET_FLAG(FLASH_FLAG_OPTVERR)) || (__HAL_FLASH_GET_FLAG(FLASH_FLAG_ECCD))) { /*Save the error code*/ FLASH_SetErrorCode(); /* FLASH error interrupt user callback */ if(pFlash.ProcedureOnGoing == FLASH_PROC_PAGE_ERASE) { HAL_FLASH_EndOfOperationCallback(pFlash.Page); } else if(pFlash.ProcedureOnGoing == FLASH_PROC_MASS_ERASE) { HAL_FLASH_EndOfOperationCallback(pFlash.Bank); } else if((pFlash.ProcedureOnGoing == FLASH_PROC_PROGRAM) || (pFlash.ProcedureOnGoing == FLASH_PROC_PROGRAM_LAST)) { HAL_FLASH_OperationErrorCallback(pFlash.Address); } HAL_FLASH_OperationErrorCallback(pFlash.Address); /*Stop the procedure ongoing*/ pFlash.ProcedureOnGoing = FLASH_PROC_NONE; } /* Check FLASH End of Operation flag */ if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_EOP)) { /* Clear FLASH End of Operation pending bit */ __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP); if(pFlash.ProcedureOnGoing == FLASH_PROC_PAGE_ERASE) { /* Nb of pages to erased can be decreased */ pFlash.NbPagesToErase--; /* Check if there are still pages to erase*/ if(pFlash.NbPagesToErase != 0) { /* Indicate user which page has been erased*/ HAL_FLASH_EndOfOperationCallback(pFlash.Page); /* Increment page number */ pFlash.Page++; tmp_page = pFlash.Page; FLASH_PageErase(tmp_page, pFlash.Bank); } else { /* No more pages to Erase */ /* Reset Address and stop Erase pages procedure */ pFlash.Page = 0xFFFFFFFF; pFlash.ProcedureOnGoing = FLASH_PROC_NONE; /* Flush the caches to be sure of the data consistency */ FLASH_FlushCaches() ; /* FLASH EOP interrupt user callback */ HAL_FLASH_EndOfOperationCallback(pFlash.Page); } } else { if(pFlash.ProcedureOnGoing == FLASH_PROC_MASS_ERASE) { /* MassErase ended. Return the selected bank */ /* Flush the caches to be sure of the data consistency */ FLASH_FlushCaches() ; /* FLASH EOP interrupt user callback */ HAL_FLASH_EndOfOperationCallback(pFlash.Bank); } else if((pFlash.ProcedureOnGoing == FLASH_PROC_PROGRAM) || (pFlash.ProcedureOnGoing == FLASH_PROC_PROGRAM_LAST)) { /* Program ended. Return the selected address */ /* FLASH EOP interrupt user callback */ HAL_FLASH_EndOfOperationCallback(pFlash.Address); } /*Clear the procedure ongoing*/ pFlash.ProcedureOnGoing = FLASH_PROC_NONE; } } if(pFlash.ProcedureOnGoing == FLASH_PROC_NONE) { /* Disable End of Operation and Error interrupts */ __HAL_FLASH_DISABLE_IT(FLASH_IT_EOP | FLASH_IT_OPERR); /* Process Unlocked */ __HAL_UNLOCK(&pFlash); } }