cancel
Showing results for 
Search instead for 
Did you mean: 

Can not erase flash memory page using HAL Drivers

Radoslav Mar
Associate II
Posted on June 18, 2018 at 12:23

Hello All.

MCU: STM32F031G6U6

IDE: System Workbench

API: STM32F0 HAL and low-layer drivers

I am trying to erase page in the flash memory at address: 0x8002000.

Here is the code:

https://community.st.com/tags♯/?tags=code

‌

FLASH_EraseInitTypeDef EraseInitStruct;

uint32_t SECTORError = 0;;

bool result = true;

/* Unlock the Flash to enable the flash control register access *************/

HAL_FLASH_Unlock();

//addr = 0x08007800 just for testing

/* Erase the user Flash area

(area defined by FLASH_USER_START_ADDR and FLASH_USER_END_ADDR) ***********/

/* Fill EraseInit structure*/

EraseInitStruct.TypeErase = FLASH_TYPEERASE_PAGES;

EraseInitStruct.PageAddress = Address; // start address

EraseInitStruct.NbPages = 1;

if (HAL_FLASHEx_Erase(&EraseInitStruct, &SECTORError) != HAL_OK)

{

/*

Error occurred while sector erase.

User can add here some code to deal with this error.

SECTORError will contain the faulty sector and then to know the code error on this sector,

user can call function 'HAL_FLASH_GetError()'

*/

/* Infinite loop */

while (1)

{

;// error, BALAGAN!!!

}

}

The program crashes at this line 

if (HAL_FLASHEx_Erase(&EraseInitStruct, &SECTORError) != HAL_OK)

Nothing after this function call is executed.

Any Ideas?

#code #code::blocks
10 REPLIES 10
areify
Associate II

Sorry for refloating but I have the same issue.

While debugging this problem I saw that, inside this function (HAL_FLASHEx_Erase) is the following block:

/* 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 = 0xFFFFFFFFU;
        
        /* 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;
          }
        }
      }

Here, all the process of erasing starts only if FLASH_WaitForLastOperation (...) returns HAL_OK (which is defined as zero). But if we dive into this function we can see in the comments:

  * @retval FLASH Status: The returned value can be: FLASH_ERROR_PG,
  *         FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
  */

An overview of this function prove that this is actually true. And those enum values are defined as:

typedef enum
{ 
  FLASH_BUSY = 1,
  FLASH_ERROR_PG,
  FLASH_ERROR_WRP,
  FLASH_COMPLETE,
  FLASH_TIMEOUT
}FLASH_Status;

As you can see, any of that values is equal to zero, so... how is expected to work this function? Is this a bug or am I misusing this library?

Thank you and excuse my english.