cancel
Showing results for 
Search instead for 
Did you mean: 

STM32u535 Struggling with FLASH_WaitForLastOperation

knights-of-ni
Associate II

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

8 REPLIES 8
TDK
Super User

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".
knights-of-ni
Associate II

It fails at the first attempted write.

knights-of-ni
Associate II

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

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

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".

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?

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...

knights-of-ni
Associate II

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