Skip to main content
Associate II
February 18, 2026
Question

STM32u535 Struggling with FLASH_WaitForLastOperation

  • February 18, 2026
  • 5 replies
  • 277 views

I have flash update operations working fine on an STM32U535 with 512kB flash, but am getting an error on a 256kB device.  Driving into the debugger, I find it coming out of the FLASH_WaitForLastOperation HAL routine, specifically after: reg_sr = IS_FLASH_SECURE_OPERATION() ? &(FLASH->SECSR) : &(FLASH_NS->NSSR) which returns 0b10001000, which winds up being the FLASH_NSSR_PROGERR, and FLASH_NSSR_PGSERR.  I am not sure why.   Code segment enclosed here:

const uint32_t NVRAM = 0x0803E000;

FLASH_EraseInitTypeDef EraseInitStruct = {0};

HAL_StatusTypeDef hfError;



uint32_t PAGEError = 0; // To hold any page error code

uint32_t pageNumber = (NVRAM - 0x08000000) / 0x2000;

uint32_t progAddress = NVRAM;

uint64_t *pSource = (uint64_t)&memory[0x1800]; // 1800

uint32_t quadWordCount = 0xFF / 16;



if (HAL_FLASH_Unlock() != HAL_OK) {

printf("Cannot erase FLASH memory.\n\r"); // Handle error, e.g., print error message

return;

}



// Clear OPTWERR bit set on virgin samples

__HAL_FLASH_CLEAR_FLAG( FLASH_FLAG_EOP | FLASH_FLAG_WRPERR | FLASH_FLAG_PROGERR);



// 2. Erase the data structures in the first bank of Flash memory

EraseInitStruct.TypeErase = FLASH_TYPEERASE_PAGES;

EraseInitStruct.Page = pageNumber; // Set the specific page to erase

EraseInitStruct.Banks = FLASH_BANK_1; // Or the correct bank for your device

EraseInitStruct.NbPages = 1; // Number of 8kByte pages to erase

if (hfError = HAL_FLASHEx_Erase(&EraseInitStruct, &PAGEError) != HAL_FLASH_ERROR_NONE) {

printf("FLASH erase error Bank 1.\n\r");

goto exit_function;

}



if (HAL_FLASH_Unlock() != HAL_OK) {

printf("Cannot erase FLASH memory.\n\r"); // Handle error, e.g., print error message

return;

}



for (uint32_t i = 0; i < quadWordCount; i++)

{

if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_QUADWORD, progAddress, (uint32_t)pSource) != HAL_OK)

{

printf("Error Programming data.\n\r");

goto exit_function;

}

progAddress += 4;

pSource += 2;

}

and, of course the HAL_FLASH_Program call is the one failing. Erasing seems OK. What am I missing

5 replies

TDK
Super User
February 18, 2026

You must write the entire flash page (128 bits, or 4x uint32_t values) at once and you can only write to addresses aligned to a flash page. One HAL_FLASH_Program call writes 128 bits.

Your code writes 128 bits to address NVRAM offset 0, then another 128 bits to offset 4, then 8, then 12. This is not allowed.

Maybe you meant to do "progAddress += 16;".

"If you feel a post has answered your question, please click ""Accept as Solution""."
Associate II
February 19, 2026

It fails at the first attempted write.

Associate II
February 19, 2026

progAddress is uint32_t, so an increment of 1 is 32 bits, an increment of 4 is 128 bits.

TDK
Super User
February 19, 2026

It fails at the first attempted write.

Then you have multiple bugs here.

> progAddress is uint32_t, so an increment of 1 is 32 bits, an increment of 4 is 128 bits.

An increment of 1 to an integer of any size is an increment of 1. You are thinking of a uint32_t*.

"If you feel a post has answered your question, please click ""Accept as Solution""."
TDK
Super User
February 19, 2026

There are multiple issues with this code. I didn't realize it at first, but it's looks to be AI generated, hence the almost-correct nature but subtle errors everywhere you look.

"If you feel a post has answered your question, please click ""Accept as Solution""."
Associate II
February 19, 2026

First TDK - thanks for the feedback.  One must never forget the help that the team is providing.  And freely. 

progAddress should have been a pointer, so you are correct, in that form that should have been +=16.  That was in the old working code, but I was screwing around trying to debug this when I changed it thinking it was a pointer.  Still... the code never gets there.  The first write immediately fails.  

AI code is definitely ***.  Still, it can be helpful in pointing you to the right area with the links provided.  Are there other errors that I am not seeing? 

The fault flags are being generated in the FLASH_Program_Quadword routine and flagged in the FLASH_NS->NSSR register on the first byte write.  The FLASH dest_addr of 0x0803E000 (quad word aligned) gets the first memory word from src_addr (0x20001800), and immediately throws the FLASH_NSSR_PROGERR flag, then the second byte write winds up throwing the FLASH_NSSR_PGSERR flag.  Makes sense, but why the PROGERR?

Associate II
February 19, 2026

Darn it!  Somehow the HAL_FLASHEx_Erase call didn't erase the flash.  Despite coming back w/out an error.  This would throw the FLASH_NSSR_PGSERR error.  So now, it is a question of what is wrong with the erase call...

Associate II
February 19, 2026

Oh hell.  The 256kB STM32U535 is dual-banked as well.  I thought banks were 256k period.  Mischief managed.