cancel
Showing results for 
Search instead for 
Did you mean: 

can't write to STM32G051G6U6 's flash: PGSERR

ak
Associate II

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?

1 ACCEPTED SOLUTION

Accepted Solutions

The flash needs unlocked before you can write to it.

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

 

If you feel a post has answered your question, please click "Accept as Solution".

View solution in original post

4 REPLIES 4
TDK
Guru

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

If you feel a post has answered your question, please click "Accept as Solution".
ak
Associate II

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.

The flash needs unlocked before you can write to it.

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

 

If you feel a post has answered your question, please click "Accept as Solution".
ak
Associate II

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!