Skip to main content
Explorer
March 14, 2025
Solved

can't write to STM32G051G6U6 's flash: PGSERR

  • March 14, 2025
  • 2 replies
  • 704 views

Hi community,

here my minimal code example:

 int main(void) {
 HAL_Init();
 SystemClock_Config();
 FLASH_EraseInitTypeDef s_eraseinit = {0};
 uint32_t pe = 0;
 s_eraseinit.TypeErase = FLASH_TYPEERASE_PAGES;
 s_eraseinit.NbPages = 1;
 s_eraseinit.Page = 1;
 s_eraseinit.Banks = FLASH_BANK_1;
 HAL_StatusTypeDef status = HAL_FLASHEx_Erase(&s_eraseinit, &pe);
 PRINT_INFO("HAL_FLASHEx_Erase status: %d, PageError: 0x%08X\n", status, pe);

 status = HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, 0x8000808, 0xAAAAAAAAAAAAAAAAU);

 uint64_t flash_content = (*(__IO uint64_t *)0x8000808);
 PRINT_INFO("Flash content: 0x%08X, flash status: %d\n", (uint32_t)flash_content, status);
 if (flash_content == 0xAAAAAAAAAAAAAAAAU) {
 HAL_GPIO_WritePin(LED_GREEN_GPIO_Port, LED_GREEN_Pin, GPIO_PIN_SET);
 } else {
 HAL_GPIO_WritePin(LED_RED_GPIO_Port, LED_RED_Pin, GPIO_PIN_SET);
 }
 while (1) {
 }
}

Later on I want to use EEPROM emulation for storing some data to flash. But unfortunately it never really worked. So now I am trying to write into flash using the minimal example above but also this is failing. I am left quite clueless and lacking of ideas what to try next.

My output:

HAL_FLASHEx_Erase status: 0, ErrorCode: 0
HAL_FLASHEx_Erase status: 0, PageError: 0xFFFFFFFF
HAL_FLASH_Program status: 1, ErrorCode: 128
Flash content: 0xFFFFFFFF, flash status: 1

I already understood that writing to flash fails with FLASH_SR_PGSERR. But since I am purely using the HAL library I don't think I really made a mistake with the programming sequence.

The errata does not contain anything like this neither.

Do you have any experience with that fault on that MCU?

    This topic has been closed for replies.
    Best answer by TDK

    The flash needs unlocked before you can write to it.

    HAL_FLASH_Unlock();
    HAL_FLASH_Program(...);
    HAL_FLASH_Lock();

     

    2 replies

    Super User
    March 14, 2025

    Check for and clear any flash error flags before the first HAL_FLASH_Program statement.

    akAuthor
    Explorer
    March 14, 2025

    Current code with error check:

    int main(void) {
    
     HAL_Init();
     /* Configure the system clock */
     SystemClock_Config();
    
    #if 1
     FLASH_EraseInitTypeDef s_eraseinit = {0};
     uint32_t pe = 0;
     s_eraseinit.TypeErase = FLASH_TYPEERASE_PAGES;
     s_eraseinit.NbPages = 1;
     s_eraseinit.Page = 1;
     s_eraseinit.Banks = FLASH_BANK_1;
     HAL_StatusTypeDef status = HAL_FLASHEx_Erase(&s_eraseinit, &pe);
     PRINT_INFO("HAL_FLASHEx_Erase status: %d, PageError: 0x%08X\n", status, pe);
    
     /* check flash errors */
     uint32_t error = (FLASH->SR & FLASH_SR_ERRORS);
    
     /* Clear SR register */
     FLASH->SR = FLASH_SR_CLEAR;
    
     PRINT_INFO("FLASH->SR after erase 0x%08X\n", error);
    
     status = HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, 0x8000808, 0xAAAAAAAAAAAAAAAAU);
    
     uint64_t flash_content = (*(__IO uint64_t *)0x8000808);
     PRINT_INFO("Flash content: 0x%08X, flash status: %d\n", (uint32_t)flash_content, status);
     if (flash_content == 0xAAAAAAAAAAAAAAAAU) {
     HAL_GPIO_WritePin(LED_GREEN_GPIO_Port, LED_GREEN_Pin, GPIO_PIN_SET);
     } else {
     HAL_GPIO_WritePin(LED_RED_GPIO_Port, LED_RED_Pin, GPIO_PIN_SET);
     }
     while (1) {
     }
    }

     

    Debug print:

    HAL_FLASHEx_Erase status: 0, ErrorCode: 0
    HAL_FLASHEx_Erase status: 0, PageError: 0xFFFFFFFF
    FLASH->SR after erase 0x00000000
    HAL_FLASH_Program status: 1, ErrorCode: 128
    Flash content: 0xFFFFFFFF, flash status: 1

    It seems that the flash_erase() function finished without any error. (FLASH->SR after erase 0x00000000)

    unfortunately the fault still persists.

    TDKAnswer
    Super User
    March 14, 2025

    The flash needs unlocked before you can write to it.

    HAL_FLASH_Unlock();
    HAL_FLASH_Program(...);
    HAL_FLASH_Lock();

     

    akAuthor
    Explorer
    March 14, 2025

    I should have had a look at the en.x-cube-eeprom's example where they do exactly this before calling the eeprom emulation code. I thought that the locking mechanism was already implemented in the drivers. Thank you, for pointing that out!