Skip to main content
Fabsch
Associate II
June 6, 2019
Solved

Why error = FLASH->SR is set and block erasing flash memory?

  • June 6, 2019
  • 7 replies
  • 6193 views

In my code i try to delete a flash mem page using

 if(HAL_FLASHEx_Erase(&FlashErase,&PageError) != HAL_OK)

but always got an HAL_ERROR because in this function (which is called in HAL_FLASHEx_Erase...)

HAL_StatusTypeDef FLASH_WaitForLastOperation(uint32_t Timeout)
{
 uint32_t error;
 uint32_t tickstart = HAL_GetTick();
 
 /* Wait for the FLASH operation to complete by polling on BUSY flag to be reset.
 Even if the FLASH operation fails, the BUSY flag will be reset and an error
 flag will be set */
 while (__HAL_FLASH_GET_FLAG(FLASH_FLAG_BSY))
 {
 if ((HAL_GetTick() - tickstart) >= Timeout)
 {
 return HAL_TIMEOUT;
 }
 }
 
 /* check flash errors. Only ECC correction can be checeked here as ECCD
 generates NMI */
 error = FLASH->SR;
 
 /* Check FLASH End of Operation flag */
 if ((error & FLASH_FLAG_EOP) != 0U)
 {
 /* Clear FLASH End of Operation pending bit */
 __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP);
 }
 
 /* Now update error variable to only error value */
 error &= FLASH_FLAG_SR_ERROR;
 
 /* Update error with ECC error value */
 error |= (FLASH->ECCR & FLASH_FLAG_ECCC);
 
 /* clear error flags */
 __HAL_FLASH_CLEAR_FLAG(error);
 
 if (error != 0U)
 {
 /*Save the error code*/
 pFlash.ErrorCode = error;
 
 return HAL_ERROR;
 }
 
 /* Wait for control register to be written */
 while (__HAL_FLASH_GET_FLAG(FLASH_FLAG_CFGBSY))
 {
 if ((HAL_GetTick() - tickstart) >= Timeout)
 {
 return HAL_TIMEOUT;
 }
 }

error = FLASH->SR sets error to 0x8000.

In the datasheet this part is marked as reserved so why FLASH-SR sets this error bit and blocks the erase process?

Thank you all for your comments!

This topic has been closed for replies.
Best answer by Le Corre Pierre

With those details, i can reproduce your issue with the exact same board only P-NUCLEO-WB55 / EPNWB55$CU4. This cannot be observed on the official P-NUCLEO-WB55 kit.

Those EPNWB55$CU4 are not supported inside the STM32CubeFWWB. Especially, you cannot change the BLE stack at all with the one provided. For this reason, i cannot plan any change iniside the HAL FLASH driver to handle this situation.

You can use this workaround to erase your flash with this specific board:

 /* USER CODE BEGIN 1 */
 /* + Workaround: Engineering samples with FLASH_SR_OPTVERR bit set for P-NUCLEO-WB55 / EPNWB55$CU4 */
 /* /!\ This can be apply ONLY to those Engineering samples /!\ */
 /* Reset FLASH_SR_OPTVERR bit by software at each startup */
 __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_OPTVERR);
 /* - Workaround: Engineering samples with FLASH_SR_OPTVERR bit set for P-NUCLEO-WB55 / EPNWB55$CU4 */
 /* USER CODE END 1 */

With this workaround, your above code behave as expected.

Pierre.

7 replies

Le Corre Pierre
ST Employee
June 7, 2019

Hi Fabsch,

The error you mention is related to FLASH SR: Bit 15 OPTVERR: Option and Engineering bits loading validity error.

Can you describe your setup and boards (value of the sticker at the bottom of the board)?

Did you change the option bytes using STM32CubeProgrammer (associated version?) or any other method?

Did you make any action which can change the option bytes?

BR.

Fabsch
FabschAuthor
Associate II
June 7, 2019

Hi Pierre,

Thank you for your answer. I am using a P-NUCLEO-WB55 / EPNWB55$CU4.

With the used software:

CubeIDE

Version: 1.0.0

Build: 2872_20190423-2022 (UTC)

STM32CubeMX - STM32 Device Configuration Tool

Version: 5.2.0

Build: 20190423-0831 (UTC)

I Created a new projekt with IDE and MX Cube for the preconfigured Board. In the Board selector I choose P-NUCLEO-WB55-Nucleo 

In the generated code i add following lines of coded:

/* USER CODE BEGIN WHILE */
 FLASH_EraseInitTypeDef FlashErase;
 FlashErase.NbPages = 1;
 FlashErase.Page = 254;
 FlashErase.TypeErase = TYPEERASE_PAGES;
 uint32_t PageError = 0;
 
 //------------------working delete procedure
// HAL_FLASH_Unlock();
// __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR | FLASH_FLAG_PGSERR | FLASH_FLAG_PGAERR);
// /* Process Locked */
// __HAL_LOCK(&pFlash);
// FLASH_PageErase(255);
// /* Process Unlocked */
// __HAL_UNLOCK(&pFlash);
 //------------------delete end
 
 //Not working because of error = 0x8000 
 HAL_FLASH_Unlock();
 __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR | FLASH_FLAG_PGSERR | FLASH_FLAG_PGAERR);
 if(HAL_FLASHEx_Erase(&FlashErase,&PageError) != HAL_OK){
	 HAL_GPIO_WritePin(GPIOB, LD3_Pin, GPIO_PIN_SET);	// indicator for erasing fails
 }

LED indicates that the error occurred and in the memory viewer that the flash memory is not erased.

With this part the flash memory can erased without problems:

//------------------working delete procedure
// HAL_FLASH_Unlock();
// __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR | FLASH_FLAG_PGSERR | FLASH_FLAG_PGAERR);
// /* Process Locked */
// __HAL_LOCK(&pFlash);
// FLASH_PageErase(255);
// /* Process Unlocked */
// __HAL_UNLOCK(&pFlash);
 //------------------delete end

Thank you!

Le Corre Pierre
ST Employee
June 7, 2019

Ok, Those are engineering sample (ES).

Can you tell us the workshop date and location where you get this sample. This is an important information to know the software compatibilities with those ES.

(also your previous response has been truncated)

STM32CubeFW version used?

Did you change the BLE stack or the FUS?

Fabsch
FabschAuthor
Associate II
June 7, 2019

Got this sample at ST workshop in Hamburg at the 29.01.2019.

Fabsch
FabschAuthor
Associate II
June 7, 2019

With the used software:

CubeIDE

Version: 1.0.0

Build: 2872_20190423-2022 (UTC)

STM32CubeMX - STM32 Device Configuration Tool

Version: 5.2.0

Build: 20190423-0831 (UTC)

I Created a new projekt with IDE and MX Cube for the preconfigured Board. In the Board selector I choose P-NUCLEO-WB55-Nucleo 

In the generated code i add following lines of coded:

/* USER CODE BEGIN WHILE */
 FLASH_EraseInitTypeDef FlashErase;
 FlashErase.NbPages = 1;
 FlashErase.Page = 254;
 FlashErase.TypeErase = TYPEERASE_PAGES;
 uint32_t PageError = 0;
 
 //------------------working delete procedure
// HAL_FLASH_Unlock();
// __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR | FLASH_FLAG_PGSERR | FLASH_FLAG_PGAERR);
// /* Process Locked */
// __HAL_LOCK(&pFlash);
// FLASH_PageErase(255);
// /* Process Unlocked */
// __HAL_UNLOCK(&pFlash);
 //------------------delete end
 
 //Not working because of error = 0x8000
 HAL_FLASH_Unlock();
 __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR | FLASH_FLAG_PGSERR | FLASH_FLAG_PGAERR);
 if(HAL_FLASHEx_Erase(&FlashErase,&PageError) != HAL_OK){
	 HAL_GPIO_WritePin(GPIOB, LD3_Pin, GPIO_PIN_SET);	// indicator for erasing fails
 }

I only added these lines of code no changes done after MX Cube created the code. (Used standard configuration after installation of MxCubeIDE and MxCubeCodeconfigurator)

Le Corre Pierre
ST Employee
June 7, 2019

With those details, i can reproduce your issue with the exact same board only P-NUCLEO-WB55 / EPNWB55$CU4. This cannot be observed on the official P-NUCLEO-WB55 kit.

Those EPNWB55$CU4 are not supported inside the STM32CubeFWWB. Especially, you cannot change the BLE stack at all with the one provided. For this reason, i cannot plan any change iniside the HAL FLASH driver to handle this situation.

You can use this workaround to erase your flash with this specific board:

 /* USER CODE BEGIN 1 */
 /* + Workaround: Engineering samples with FLASH_SR_OPTVERR bit set for P-NUCLEO-WB55 / EPNWB55$CU4 */
 /* /!\ This can be apply ONLY to those Engineering samples /!\ */
 /* Reset FLASH_SR_OPTVERR bit by software at each startup */
 __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_OPTVERR);
 /* - Workaround: Engineering samples with FLASH_SR_OPTVERR bit set for P-NUCLEO-WB55 / EPNWB55$CU4 */
 /* USER CODE END 1 */

With this workaround, your above code behave as expected.

Pierre.

Fabsch
FabschAuthor
Associate II
June 7, 2019

Works for me. Thank you!

juergen23
Associate II
September 24, 2020

Hi,

i found this old thread and i have a question.

I'm using a STM32L151 now for several months for measurement of some data to calculate a flow value.

I use the EEPROM to save some settings and load them when i restart the system.

All works fine, but then the OPTVERRUSR-Flag was set and i couldn't accesss the eeprom any more.

After resetting the flag all works fine.

When is this flag set by the hardware?

The reference manual says "If option have not loaded properly...", but which options are meant?

So i can reset the flag every time at startup when it is set, but i wan't to understand when and why this flag is set.

Thanks in advance

Juergen