I am trying to write on the flash memory of an STM32L476RG with the HAL_FLASH_Program function but it always returns an error.
static FLASH_EraseInitTypeDef EraseInitStruct;
uint32_t PAGEError;
uint32_t Address = 0x080FFF10;
uint64_t data = 5;
/* Unlock the Flash to enable the flash control register access *************/
HAL_FLASH_Unlock();
/* Erase the user Flash area*/
/* Fill EraseInit structure*/
EraseInitStruct.TypeErase = FLASH_TYPEERASE_PAGES;
EraseInitStruct.Page = Address;
EraseInitStruct.NbPages = 1;
if (HAL_FLASHEx_Erase(&EraseInitStruct, &PAGEError) != HAL_OK)
{
/*Error occurred while page erase.*/
HAL_FLASH_GetError ();
}
/*Write into flash*/
HAL_StatusTypeDef status = HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, 0x1FFF7000, data);
if (status== HAL_OK)
{
printf("it works\n\r");
}
else
{
/* Error occurred while writing data in Flash memory*/
HAL_FLASH_GetError();
}
HAL_FLASH_Lock();
I tried to find wthe flash error code with the HAL_FLASH_GetError() function. The error code I get is "168" (0xa8 in Hex) and I have no idea to what it corresponds.
My questions :
The problem is how the fields in EraseInitStruct
are being set. The HAL driver for some STM32 parts expects an address. However, the HAL library for the STM32L476 expects a page number.
typedef struct
{
uint32_t TypeErase; /*!< Mass erase or page erase.
This parameter can be a value of @ref FLASH_Type_Erase */
uint32_t Banks; /*!< Select bank to erase.
This parameter must be a value of @ref FLASH_Banks
(FLASH_BANK_BOTH should be used only for mass erase) */
uint32_t Page; /*!< Initial Flash page to erase when page erase is disabled
This parameter must be a value between 0 and (max number of pages in the bank - 1)
(eg : 255 for 1MB dual bank) */
uint32_t NbPages; /*!< Number of pages to be erased.
This parameter must be a value between 1 and (max number of pages in the bank - value of initial page)*/
} FLASH_EraseInitTypeDef;
So you need to set the page number correctly, and also specify which flash bank you are trying to erase:
EraseInitStruct.Banks = FLASH_BANK_2;
EraseInitStruct.Page = 255u;
It is good practice to check the result of all HAL function calls, and abort the operation if there is an error.
@Lundin brought up a good point about possibly being unable to erase / program the flash bank that you are running code from. This is an issue for some devices, but the reference manual for the STM32L476 (in section 3.3.5) says this is ok:
... during a program/erase operation to the Flash memory, any attempt to read the same Flash memory bank will stall the bus. The read operation will proceed correctly once the program/erase operation has completed.