cancel
Showing results for 
Search instead for 
Did you mean: 

FLASH_WaitForLastOperation returns error in STM32G070

rickard2
Associate III

I try to erase a page using this code:

bool EraseFlash()
{
	uint32_t FirstPage = 0, NbOfPages = 0;
	uint32_t PageError = 0;
	int i;
	FLASH_EraseInitTypeDef EraseInitStruct = {0};
 
	HAL_FLASH_Unlock();
	FirstPage = GetPage(FLASH_START);
 
	/* Get the number of pages to erase from 1st page */
	NbOfPages = GetPage(FLASH_END) - FirstPage + 1;
 
	// Testing:
	FirstPage = 30;
	NbOfPages = 1;
	/* Fill EraseInit structure*/
	EraseInitStruct.TypeErase   = FLASH_TYPEERASE_PAGES;
	EraseInitStruct.Page        = FirstPage;
	EraseInitStruct.NbPages     = NbOfPages;
 
	printf("Erasing %d, %d\n\r", (int)FirstPage, (int)NbOfPages);
 
	/* Note: If an erase operation in Flash memory also concerns data in the data or instruction cache,
	 you have to make sure that these data are rewritten before they are accessed during code
	 execution. If this cannot be done safely, it is recommended to flush the caches by setting the
	 DCRST and ICRST bits in the FLASH_CR register. */
	if (HAL_FLASHEx_Erase(&EraseInitStruct, &PageError) != HAL_OK)
	{
	  printf("Error %d\n\r", PageError);
	  return false;
	}
	return true;
}

But it fails every time.

First time FLASH_WaitForLastOperation  returns HAL_ERROR and HAL_FLASH_GetError returns 0xA0 which I interpret as errr flags FLASH_FLAG_PGSERR and FLASH_FLAG_PGAERR.

Next time I try it will always return HAL_TIMEOUT.

I have tried different pages but result is the same.

If I clear the bits above, it wil instead return HAL_TIMEOUT on first try.

Why is it behaving like this? What have I missed?

HAL_Init(), __HAL_RCC_SYSCFG_CLK_ENABLE() and __HAL_RCC_PWR_CLK_ENABLE() is enough to init flash correclty?

9 REPLIES 9
TDK
Guru

I don't see a problem in the code. PGSERR/PGAERR don't seem applicable to what you're trying to do. Are you sure you're not modifying the flash in another part of the program before this?

Note that erasing the entire flash is bound to fail unless your program is running in SRAM.

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

It is a bootloader so it will only erase the code where the application is located.

And I do not modify the flash before the erase.

rickard2
Associate III

I found the issue. It was a call to one non initated timer before the erase which messed up the flash erase. A bit wierd, but it works now.

Would you be able to say which timer it was? I might be having a similar problem here...

Never mind; I get what you mean now.

It turned out that I had a similar problem - I was using a timer for switching a buzzer (the timer was used to run it at its optimal frequency, and turning the timer on and off provided a pattern of beeps), but I'd accidentally inserted a new call to turn the buzzer on before the point in the code where the timer was initialised.

The symptoms were that it always returned a non-`HAL_OK` status when calling `FLASH_WaitForLastOperation()`, in the function used to do a flash page erase, so it looked more like it was a flash problem (especially as I was doing other things with the flash at the time!) than it was anything to do with a timer. But it turns out that it was!

elliotwoods
Associate II

I'm also getting HAL_ERROR returned from FLASH_WaitForLastOperation inside HAL_FLASH_Program function.

There are no timers used in my project, and I've tested calling HAL_FLASH_Program right at the top of main.c (before anything else happens in the program, directly below HAL_Init,SystemClock_Config) and it still fails. Notes on project:

* DMA UART on UART2

* Non-DMA UART on UART1

* STM32G070CBT6

 

elliotwoods
Associate II

I found the solution in my case, the memory needs to be 64bit aligned and I was giving it non-64bit aligned memory.

For future reference, one solution might be to allocate some 64bit ram (e.g. uint64_t data[binarySize/sizeof(uint64_t)]) and memcpy the data into that first. For the time being I'm using a different solution and don't have any more time to spend on this issue.

WBria.1
Associate II

@rickard2 @TDK @elliotwoods @LKett.1 

Hi Guys, i'm stuck with this problem for days... i'm not able to store basic data in the flash memory...

Always the FLASH_WaitForLastOperation return HAL_ERROR (with pFlash.ErrorCode = 0xe0) and i did not found the issue... my INIT_FLASH=0x08007800 to the end FLASH_END_ADDR=0x08007FFF

 

Here are the code:

 

int main(void)
{
	/* USER CODE BEGIN 1 */
	uint32_t FirstPage = 0, NbOfPages = 0;
	uint32_t Address = 0, PageError = 0;
	__IO uint32_t MemoryProgramStatus = 0;
	__IO uint32_t data32 = 0;
	static FLASH_EraseInitTypeDef EraseInitStruct;
	/* USER CODE END 1 */

	/* MCU Configuration--------------------------------------------------------*/

	/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
	HAL_Init();

	/* USER CODE BEGIN Init */

	/* USER CODE END Init */

	/* Configure the system clock */
	SystemClock_Config();

	/* USER CODE BEGIN SysInit */

	/* USER CODE END SysInit */

	/* Initialize all configured peripherals */
	MX_GPIO_Init();
	MX_TIM3_Init();
	MX_ADC1_Init();
	MX_TIM17_Init();
	/* USER CODE BEGIN 2 */

	HAL_FLASH_Unlock();
	/* Get the 1st page to erase */
	FirstPage = GetPage(INIT_FLASH_ADDR);

	/* Get the number of pages to erase from 1st page */
	NbOfPages = GetPage(FLASH_END_ADDR) - FirstPage + 1;

	/* Fill EraseInit structure*/
	EraseInitStruct.TypeErase   = FLASH_TYPEERASE_PAGES;
	EraseInitStruct.Page        = FirstPage;
	EraseInitStruct.NbPages     = NbOfPages;

	//FLASH_PageErase(FLASH_BANK_1, EraseInitStruct.Page);
	if (HAL_FLASHEx_Erase(&EraseInitStruct, &PageError) != HAL_OK)
	{
		while(1)
		{

		}
	}

	HAL_Delay(100);

	Address = INIT_FLASH_ADDR;

#define DATA_64                 ((uint64_t)0x1234567812345678)

	while (Address < FLASH_END_ADDR)
	{
		if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, Address, DATA_64) == HAL_OK)
		{
			Address = Address + 8;  /* increment to next double word*/
			HAL_Delay(100);
		}
		else
		{
			while (1)
			{

			}
		}
	}

	HAL_FLASH_Lock();

	while(1)
	{

	}
}

 

 

Since your issue is different than this one, make a new thread.

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