Internal flash storage issue on STM32G0B1
Good day,
I am writing firmware for a custom board using the STM32G0B1KET6 and am experiencing issues related to writing a serial number to the internal flash.
As far as I can tell, this MCU has 512 KB of flash split into 2 banks of 128 pages (each page is 2 KB). I am attempting to write to the last page of the first bank (Page 127 @ 0x803F800).
I have modified the linker file to reduce the flash area used by my application code like so:
MEMORY
{
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 144K
FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 64K
}Here is my flash writing function.
uint8_t Flash_Write(uint32_t startAddress, uint64_t data)
{
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_OPTVERR);
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_BSY1);
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_BSY2);
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_PGSERR);
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_PGAERR);
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_CFGBSY);
if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_CFGBSY) == 1)
{
return 0;
}
HAL_StatusTypeDef status;
uint32_t err;
status = HAL_FLASH_Unlock();
if (status != HAL_OK)
{
// Handle error
printf("Failed to unlock flash.\r\n");
return 0;
}
// Erase page first
FLASH_EraseInitTypeDef EraseInitStruct;
uint32_t PageError = 0;
EraseInitStruct.TypeErase = FLASH_TYPEERASE_PAGES;
EraseInitStruct.Page = (startAddress - FLASH_BASE) / FLASH_PAGE_SIZE;
EraseInitStruct.NbPages = 1;
EraseInitStruct.Banks = FLASH_BANK_1;
status = HAL_FLASHEx_Erase(&EraseInitStruct, &PageError);
if (status != HAL_OK)
{
err = HAL_FLASH_GetError();
printf("Failed to erase flash. Err: %lu\r\n",err);
HAL_FLASH_Lock();
return 0;
}
// Write data
if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, startAddress, data) != HAL_OK)
{
// Handle error
err = HAL_FLASH_GetError();
printf("Flash programming error. Err: %lu\r\n",err);
HAL_FLASH_Lock();
return 0;
}
HAL_FLASH_Lock();
return 1;
}
void cmSetUID(void)
{
uint64_t UID;
uint8_t retry = 0;
UID = atoi((char*)&DebugRxBuf[DebugRxPtr]);
while(Flash_Write(0x0803F800,UID) == 0)
{
if(retry > 10)
{
printf("UID Set: FAILED\r\n");
return;
}
else
{
//HAL_Delay(10);
retry++;
}
}
printf("UID Set: %lu\r\n",(uint32_t)UID);
}
void cmReadUID(void)
{
uint64_t UID;
UID = Flash_Read(0x0803F800);
printf("UID Read: %lu\r\n",(uint32_t)UID);
}For some reason the PGSERR and PGAERR flags are always set when the board is programmed or this function is entered, which is why I am manually clearing them to prevent failure at the HAL_FLASHEx_Erase function.
The issue that I am having relates to the CFGBSY flag, which is sometimes set on boot or after a successful write (but not always), and I cannot clear the flag as it is set/cleared by hardware. For some reason the CFGBSY flag will eventually go low after successive calls to the Flash_Write function even though the function returns if the flag is set.


If anyone has any ideas on why my flags are acting up I would greatly appreciate it.
Regards,
Shaun
