2022-04-21 11:28 AM
I have a program that writes to flash using HAL_FLASH_Program().
Before it does, I erase the flash with this function:
bool Erase_Flash(void) {
static FLASH_EraseInitTypeDef EraseInitStruct;
uint32_t PAGEError = 0;
HAL_StatusTypeDef status;
printf("Erasing flash...");
HAL_FLASH_Unlock();
/* Clear OPTVERR bit set on virgin samples */
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_OPTVERR);
/* Fill EraseInit structure*/
EraseInitStruct.TypeErase = FLASH_TYPEERASE_MASSERASE;
EraseInitStruct.Banks = FLASH_BANK_2;
status = HAL_FLASHEx_Erase(&EraseInitStruct, &PAGEError);
if (status != HAL_OK) {
CANprintf("Error erasing flash bank 2 (%i)", HAL_FLASH_GetError());
return false;
}
HAL_FLASH_Lock();
printf("Done.");
return true;
}
This erases the 2nd bank of memory on an STM32L471.
(two bank, and the code starts on bank 1)
I can call this function and erase the flash repeatedly.
However, once I write data to the flash I can no longer erase it.
HAL_FLASHEx_Erase() returns 128, which is 0x080, which is
#define FLASH_SR_PGSERR_Msk (0x1UL << FLASH_SR_PGSERR_Pos) /*!< 0x00000080 */
#define FLASH_SR_PGSERR FLASH_SR_PGSERR_Msk
#define HAL_FLASH_ERROR_PGS FLASH_FLAG_PGSERR
#define FLASH_FLAG_PGSERR FLASH_SR_PGSERR /*!< FLASH Programming sequence error flag */
If I reboot the MCPU, erasing works again.
2022-04-21 12:29 PM
Check FLASH_SR prior to the HAL_FLASHEx_Erase call. Likely, PGSERR is set from a previous operation.
2022-04-21 12:46 PM
If I trace the code into HAL_FLASHEx_Erase(), There is a status variable called here:
status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
(A few lines into the function) this functions returns HAL_OK
Then, moving down the code this block of code runs:
if (pEraseInit->TypeErase == FLASH_TYPEERASE_MASSERASE)
{
/* Mass erase to be done */
FLASH_MassErase(pEraseInit->Banks);
/* Wait for last operation to be completed */
status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
This call of FLASH_WaitForLastOperation returns the error.
If I trace that function it occurs here:
error = (FLASH->SR & FLASH_FLAG_SR_ERRORS);
Although, just to be certain, I checked for the flag right before calling HAL_FLASHEx_Erase() and it is indeed 0.