2026-02-18 2:59 PM - last edited on 2026-02-18 11:07 PM by Imen.D
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
2026-02-18 3:16 PM - edited 2026-02-18 3:24 PM
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;".
2026-02-18 4:19 PM
It fails at the first attempted write.
2026-02-18 4:20 PM
progAddress is uint32_t, so an increment of 1 is 32 bits, an increment of 4 is 128 bits.
2026-02-18 4:33 PM
> 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*.
2026-02-18 4:39 PM
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.
2026-02-18 6:09 PM
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?
2026-02-18 6:55 PM
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...
2026-02-18 7:26 PM
Oh hell. The 256kB STM32U535 is dual-banked as well. I thought banks were 256k period. Mischief managed.