cancel
Showing results for 
Search instead for 
Did you mean: 

Can't erase flash after writing to it.

jgauthier
Senior

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.

2 REPLIES 2
TDK
Guru

Check FLASH_SR prior to the HAL_FLASHEx_Erase call. Likely, PGSERR is set from a previous operation.

If you feel a post has answered your question, please click "Accept as Solution".
jgauthier
Senior

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.