2020-04-29 12:13 PM
Hi all,
I am using HAL_FLASH_Program() to program an uuid into a specific address. I can verify it write successfully by reading from the address. However, if I power cycle the MCU, the memory at that address returns to the original value. If I write it directly through ST-Link then it stays permanently. Does anyone know why is that? Do I need to erase the memory location before write to it using HAL_FLASH_Program()? I am using STM32F745.
Thank you
Solved! Go to Solution.
2020-04-30 11:40 AM
Fixed it:
FLASH->CR |= 0x1; //Set PG bit
__DMB();
*(volatile uint16_t*) 0x080BFFFA = uuid;
__DMB();
while(FLASH->SR & 0x0100)
P.S. And of course the HAL code is broken in this regard...
2020-04-29 12:56 PM
> Do I need to erase the memory location before write to it using HAL_FLASH_Program()?
Yes, you must erase flash before writing to it. You can't treat is as RAM.
2020-04-29 01:20 PM
Can I erase a byte in flash? What actually happen when I modify a flash byte using ST-Link?
2020-04-29 01:25 PM
2020-04-29 02:01 PM
I have tried to use the erase sector option in ST-Link but no success.
My procedure is below:
What do you think I did wrong?
2020-04-29 02:27 PM
Reading can be "faked" by D-cache, if it's turned on. Try not turning it on and most likely you'll see that you are actually not writing anything. As for why... Here is a wild guess - you haven't read the reference manual and are trying to write double word values. ;)
2020-04-29 02:43 PM
> What do you think I did wrong?
I don't think it's a useful exercise for me to guess what mistakes you're making. There's plenty of examples on how to write flash.
2020-04-30 02:11 AM
> What do you think I did wrong?
You trusted a barely documented library function that it does what you think it should do.
Follow the instructions in these sections of the reference manual, set the registers exactly as advised.
Examine FLASH->SR after each step for possible problems.
2020-04-30 10:39 AM
I have set the PSIZE bits in FLASH->CR register to 01 (x16) and write uint16_t data into the address but it gives me PGPERR. I'm really confused.
2020-04-30 10:44 AM
Thank you. I have ditched the HAL library and writing directly to registers as follow:
void FA_program_uuid( uint16_t uuid)
{
HAL_FLASH_Unlock();
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_ALL_ERRORS);
FLASH->CR &= CR_PSIZE_MASK; //Clear all the PSIZE bits
FLASH->CR |= FLASH_PSIZE_HALF_WORD; //Set PSIZE bits to 01: x16
while((FLASH->SR & 0x0100) > 0)
{
//Wait for BSY bit is cleared
}
FLASH->CR |= 0x2; //Set SER bit
FLASH->CR |= 0x30; //Select the sector by setting SNB bits
FLASH->CR |= 0x100; //Set the STRT bit
while((FLASH->SR & 0x0100) > 0)
{
//Wait for BSY bit is cleared
}
FLASH->CR |= 0x1; //Set PG bit
*(uint16_t*) 0x080BFFFB = uuid;
while((FLASH->SR & 0x0100) > 0)
{
//Wait for BSY bit is cleared
}
FLASH->CR &= 0xffffffe; //Clear PG bit
HAL_FLASH_Lock();
}
And I got PGPERR flag in FLASH->SR even though I have set PSIZE to 01 for x16 programming.