/** * @brief Perform a mass erase or erase the specified FLASH memory pages with interrupt enabled * @note To correctly run this function, the @ref HAL_FLASH_Unlock() function * must be called before. * Call the @ref HAL_FLASH_Lock() to disable the flash memory access * (recommended to protect the FLASH memory against possible unwanted operation) * @param pEraseInit pointer to an FLASH_EraseInitTypeDef structure that * contains the configuration information for the erasing. * * @retval HAL_StatusTypeDef HAL Status */ HAL_StatusTypeDef HAL_FLASHEx_Erase_IT(FLASH_EraseInitTypeDef *pEraseInit) { HAL_StatusTypeDef status = HAL_OK; /* Process Locked */ __HAL_LOCK(&pFlash); /* If procedure already ongoing, reject the next one */ if (pFlash.ProcedureOnGoing != FLASH_PROC_NONE) { return HAL_ERROR; } /* Check the parameters */ assert_param(IS_FLASH_TYPEERASE(pEraseInit->TypeErase)); /* Enable End of FLASH Operation and Error source interrupts */ __HAL_FLASH_ENABLE_IT(FLASH_IT_EOP | FLASH_IT_ERR); #if defined(FLASH_BANK2_END) /* Enable End of FLASH Operation and Error source interrupts */ __HAL_FLASH_ENABLE_IT(FLASH_IT_EOP_BANK2 | FLASH_IT_ERR_BANK2); #endif if (pEraseInit->TypeErase == FLASH_TYPEERASE_MASSERASE) { /*Mass erase to be done*/ pFlash.ProcedureOnGoing = FLASH_PROC_MASSERASE; FLASH_MassErase(pEraseInit->Banks); } else { /* Erase by page to be done*/ /* Check the parameters */ assert_param(IS_FLASH_PROGRAM_ADDRESS(pEraseInit->PageAddress)); assert_param(IS_FLASH_NB_PAGES(pEraseInit->PageAddress, pEraseInit->NbPages)); pFlash.ProcedureOnGoing = FLASH_PROC_PAGEERASE; pFlash.DataRemaining = pEraseInit->NbPages; pFlash.Address = pEraseInit->PageAddress; /*Erase 1st page and wait for IT*/ FLASH_PageErase(pEraseInit->PageAddress); } return status; }
/** * @brief Perform a mass erase or erase the specified FLASH memory sectors with interrupt enabled * @param pEraseInit: pointer to an FLASH_EraseInitTypeDef structure that * contains the configuration information for the erasing. * * @retval HAL Status */ HAL_StatusTypeDef HAL_FLASHEx_Erase_IT(FLASH_EraseInitTypeDef *pEraseInit) { HAL_StatusTypeDef status = HAL_OK; /* Process Locked */ __HAL_LOCK(&pFlash); /* Check the parameters */ assert_param(IS_FLASH_TYPEERASE(pEraseInit->TypeErase)); /* Enable End of FLASH Operation interrupt */ __HAL_FLASH_ENABLE_IT(FLASH_IT_EOP); /* Enable Error source interrupt */ __HAL_FLASH_ENABLE_IT(FLASH_IT_ERR); /* Clear pending flags (if any) */ __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR |\ FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR| FLASH_FLAG_PGSERR); if(pEraseInit->TypeErase == FLASH_TYPEERASE_MASSERASE) { /*Mass erase to be done*/ pFlash.ProcedureOnGoing = FLASH_PROC_MASSERASE; pFlash.Bank = pEraseInit->Banks; FLASH_MassErase((uint8_t) pEraseInit->VoltageRange, pEraseInit->Banks); } else { /* Erase by sector to be done*/ /* Check the parameters */ assert_param(IS_FLASH_NBSECTORS(pEraseInit->NbSectors + pEraseInit->Sector)); pFlash.ProcedureOnGoing = FLASH_PROC_SECTERASE; pFlash.NbSectorsToErase = pEraseInit->NbSectors; pFlash.Sector = pEraseInit->Sector; pFlash.VoltageForErase = (uint8_t)pEraseInit->VoltageRange; /*Erase 1st sector and wait for IT*/ FLASH_Erase_Sector(pEraseInit->Sector, pEraseInit->VoltageRange); } return status; }
/** * @brief Perform a mass erase or erase the specified FLASH memory pages * @note To correctly run this function, the @ref HAL_FLASH_Unlock() function * must be called before. * Call the @ref HAL_FLASH_Lock() to disable the flash memory access * (recommended to protect the FLASH memory against possible unwanted operation) * @param[in] pEraseInit pointer to an FLASH_EraseInitTypeDef structure that * contains the configuration information for the erasing. * * @param[out] PageError pointer to variable that * contains the configuration information on faulty page in case of error * (0xFFFFFFFF means that all the pages have been correctly erased) * * @retval HAL_StatusTypeDef HAL Status */ HAL_StatusTypeDef HAL_FLASHEx_Erase(FLASH_EraseInitTypeDef *pEraseInit, uint32_t *PageError) { HAL_StatusTypeDef status = HAL_ERROR; uint32_t address = 0; /* Process Locked */ __HAL_LOCK(&pFlash); /* Check the parameters */ assert_param(IS_FLASH_TYPEERASE(pEraseInit->TypeErase)); if (pEraseInit->TypeErase == FLASH_TYPEERASE_MASSERASE) { #if defined(FLASH_BANK2_END) if (pEraseInit->Banks == FLASH_BANK_BOTH) { /* Mass Erase requested for Bank1 and Bank2 */ /* Wait for last operation to be completed */ if ((FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE) == HAL_OK) && \ (FLASH_WaitForLastOperationBank2((uint32_t)FLASH_TIMEOUT_VALUE) == HAL_OK)) { /*Mass erase to be done*/ FLASH_MassErase(FLASH_BANK_BOTH); /* Wait for last operation to be completed */ if ((FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE) == HAL_OK) && \ (FLASH_WaitForLastOperationBank2((uint32_t)FLASH_TIMEOUT_VALUE) == HAL_OK)) { status = HAL_OK; } /* If the erase operation is completed, disable the MER Bit */ CLEAR_BIT(FLASH->CR, FLASH_CR_MER); CLEAR_BIT(FLASH->CR2, FLASH_CR2_MER); } } else if (pEraseInit->Banks == FLASH_BANK_2) { /* Mass Erase requested for Bank2 */ /* Wait for last operation to be completed */ if (FLASH_WaitForLastOperationBank2((uint32_t)FLASH_TIMEOUT_VALUE) == HAL_OK) { /*Mass erase to be done*/ FLASH_MassErase(FLASH_BANK_2); /* Wait for last operation to be completed */ status = FLASH_WaitForLastOperationBank2((uint32_t)FLASH_TIMEOUT_VALUE); /* If the erase operation is completed, disable the MER Bit */ CLEAR_BIT(FLASH->CR2, FLASH_CR2_MER); } } else #endif /* FLASH_BANK2_END */ { /* Mass Erase requested for Bank1 */ /* Wait for last operation to be completed */ if (FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE) == HAL_OK) { /*Mass erase to be done*/ FLASH_MassErase(FLASH_BANK_1); /* 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 */ CLEAR_BIT(FLASH->CR, FLASH_CR_MER); } } } else { /* Page Erase is requested */ /* Check the parameters */ assert_param(IS_FLASH_PROGRAM_ADDRESS(pEraseInit->PageAddress)); assert_param(IS_FLASH_NB_PAGES(pEraseInit->PageAddress, pEraseInit->NbPages)); #if defined(FLASH_BANK2_END) /* Page Erase requested on address located on bank2 */ if(pEraseInit->PageAddress > FLASH_BANK1_END) { /* Wait for last operation to be completed */ if (FLASH_WaitForLastOperationBank2((uint32_t)FLASH_TIMEOUT_VALUE) == HAL_OK) { /*Initialization of PageError variable*/ *PageError = 0xFFFFFFFF; /* Erase by page by page to be done*/ for(address = pEraseInit->PageAddress; address < (pEraseInit->PageAddress + (pEraseInit->NbPages)*FLASH_PAGE_SIZE); address += FLASH_PAGE_SIZE) { FLASH_PageErase(address); /* Wait for last operation to be completed */ status = FLASH_WaitForLastOperationBank2((uint32_t)FLASH_TIMEOUT_VALUE); /* If the erase operation is completed, disable the PER Bit */ CLEAR_BIT(FLASH->CR2, FLASH_CR2_PER); if (status != HAL_OK) { /* In case of error, stop erase procedure and return the faulty address */ *PageError = address; break; } } } } else #endif /* FLASH_BANK2_END */ { /* Page Erase requested on address located on bank1 */ /* Wait for last operation to be completed */ if (FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE) == HAL_OK) { /*Initialization of PageError variable*/ *PageError = 0xFFFFFFFF; /* Erase page by page to be done*/ for(address = pEraseInit->PageAddress; address < ((pEraseInit->NbPages * FLASH_PAGE_SIZE) + pEraseInit->PageAddress); address += FLASH_PAGE_SIZE) { FLASH_PageErase(address); /* Wait for last operation to be completed */ status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE); /* If the erase operation is completed, disable the PER Bit */ CLEAR_BIT(FLASH->CR, FLASH_CR_PER); if (status != HAL_OK) { /* In case of error, stop erase procedure and return the faulty address */ *PageError = address; break; } } } } } /* Process Unlocked */ __HAL_UNLOCK(&pFlash); return status; }
/** * @brief Perform a mass erase or erase the specified FLASH memory sectors with interrupt enabled * @param pEraseInit pointer to an FLASH_EraseInitTypeDef structure that * contains the configuration information for the erasing. * * @retval HAL Status */ HAL_StatusTypeDef HAL_FLASHEx_Erase_IT(FLASH_EraseInitTypeDef *pEraseInit) { HAL_StatusTypeDef status = HAL_OK; /* Process Locked */ __HAL_LOCK(&pFlash); /* Check the parameters */ assert_param(IS_FLASH_TYPEERASE(pEraseInit->TypeErase)); assert_param(IS_VOLTAGERANGE(pEraseInit->VoltageRange)); assert_param(IS_FLASH_BANK(pEraseInit->Banks)); if((pEraseInit->Banks & FLASH_BANK_1) == FLASH_BANK_1) { /* Clear bank 1 pending flags (if any) */ __HAL_FLASH_CLEAR_FLAG_BANK1(FLASH_FLAG_EOP_BANK1 | FLASH_FLAG_ALL_ERRORS_BANK1); /* Enable End of Operation and Error interrupts for Bank 1 */ __HAL_FLASH_ENABLE_IT_BANK1(FLASH_IT_EOP_BANK1 | FLASH_IT_WRPERR_BANK1 | FLASH_IT_PGSERR_BANK1 | \ FLASH_IT_STRBERR_BANK1 | FLASH_IT_INCERR_BANK1 | FLASH_IT_OPERR_BANK1); } if((pEraseInit->Banks & FLASH_BANK_2) == FLASH_BANK_2) { /* Clear bank 2 pending flags (if any) */ __HAL_FLASH_CLEAR_FLAG_BANK2(FLASH_FLAG_EOP_BANK2 | FLASH_FLAG_ALL_ERRORS_BANK2); /* Enable End of Operation and Error interrupts for Bank 2 */ __HAL_FLASH_ENABLE_IT_BANK2(FLASH_IT_EOP_BANK2 | FLASH_IT_WRPERR_BANK2 | FLASH_IT_PGSERR_BANK2 | \ FLASH_IT_STRBERR_BANK2 | FLASH_IT_INCERR_BANK2 | FLASH_IT_OPERR_BANK2); } if(pEraseInit->TypeErase == FLASH_TYPEERASE_MASSERASE) { /*Mass erase to be done*/ if(pEraseInit->Banks == FLASH_BANK_1) { pFlash.ProcedureOnGoing = FLASH_PROC_MASSERASE_BANK1; } else if(pEraseInit->Banks == FLASH_BANK_2) { pFlash.ProcedureOnGoing = FLASH_PROC_MASSERASE_BANK2; } else { pFlash.ProcedureOnGoing = FLASH_PROC_ALLBANK_MASSERASE; } FLASH_MassErase(pEraseInit->VoltageRange, pEraseInit->Banks); } else { /* Erase by sector to be done*/ /* Check the parameters */ assert_param(IS_FLASH_BANK_EXCLUSIVE(pEraseInit->Banks)); assert_param(IS_FLASH_NBSECTORS(pEraseInit->NbSectors + pEraseInit->Sector)); if(pEraseInit->Banks == FLASH_BANK_1) { pFlash.ProcedureOnGoing = FLASH_PROC_SECTERASE_BANK1; } else { pFlash.ProcedureOnGoing = FLASH_PROC_SECTERASE_BANK2; } pFlash.NbSectorsToErase = pEraseInit->NbSectors; pFlash.Sector = pEraseInit->Sector; pFlash.VoltageForErase = pEraseInit->VoltageRange; /*Erase 1st sector and wait for IT*/ FLASH_Erase_Sector(pEraseInit->Sector, pEraseInit->Banks, pEraseInit->VoltageRange); } return status; }
/** * @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_OK; uint32_t index = 0; /* Process Locked */ __HAL_LOCK(&pFlash); /* Check the parameters */ assert_param(IS_FLASH_TYPEERASE(pEraseInit->TypeErase)); assert_param(IS_VOLTAGERANGE(pEraseInit->VoltageRange)); assert_param(IS_FLASH_BANK(pEraseInit->Banks)); /* Wait for last operation to be completed */ if((pEraseInit->Banks & FLASH_BANK_1) == FLASH_BANK_1) { status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE, FLASH_BANK_1); } if((pEraseInit->Banks & FLASH_BANK_2) == FLASH_BANK_2) { status |= FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE, FLASH_BANK_2); } if(status == HAL_OK) { /*Initialization of SectorError variable*/ *SectorError = 0xFFFFFFFF; if(pEraseInit->TypeErase == FLASH_TYPEERASE_MASSERASE) { /*Mass erase to be done*/ FLASH_MassErase(pEraseInit->VoltageRange, pEraseInit->Banks); /* Wait for last operation to be completed */ if((pEraseInit->Banks & FLASH_BANK_1) == FLASH_BANK_1) { status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE, FLASH_BANK_1); /* if the erase operation is completed, disable the Bank1 BER Bit */ FLASH->CR1 &= (~FLASH_CR_BER); } if((pEraseInit->Banks & FLASH_BANK_2) == FLASH_BANK_2) { status |= FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE, FLASH_BANK_2); /* if the erase operation is completed, disable the Bank2 BER Bit */ FLASH->CR2 &= (~FLASH_CR_BER); } } else { /* Check the parameters */ assert_param(IS_FLASH_BANK_EXCLUSIVE(pEraseInit->Banks)); 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, pEraseInit->Banks, pEraseInit->VoltageRange); if((pEraseInit->Banks & FLASH_BANK_1) == FLASH_BANK_1) { /* Wait for last operation to be completed */ status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE, FLASH_BANK_1); /* If the erase operation is completed, disable the SER Bit */ FLASH->CR1 &= (~(FLASH_CR_SER | FLASH_CR_SNB)); } if((pEraseInit->Banks & FLASH_BANK_2) == FLASH_BANK_2) { /* Wait for last operation to be completed */ status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE, FLASH_BANK_2); /* If the erase operation is completed, disable the SER Bit */ FLASH->CR2 &= (~(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; } } } } /* Process Unlocked */ __HAL_UNLOCK(&pFlash); return status; }
/** * @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; }