Search code examples
cembeddedstm32stm32-hal

STM32L476 flash Page erase has no effect


I have an issue where I try to write a value to a flash page (page 256 @ 0x08080000) in the STM32L476. However, I get a PROGERR error set in the flash Status Register. This means that a non-zero value was attempted to be written into a flash location not erased to 0xFFFFFFFF.

I do erase the flash like this:

uint32_t page = 256;
HAL_FLASH_Unlock();
FLASH_PageErase(page, FLASH_BANK_BOTH);
FLASH_WaitForLastOperation((uint32_t) FLASH_TIMEOUT_VALUE);
CLEAR_BIT(FLASH->CR, (FLASH_CR_PER | FLASH_CR_PNB));
HAL_FLASH_Lock();

However, when I check the flash contents after the erase, it did not change from the old, unerased values.

I tried to change it to

uint32_t page = 256;
HAL_FLASH_Unlock();
SET_BIT(FLASH->SR, (FLASH_FLAG_ALL_ERRORS));
FLASH_WaitForLastOperation((uint32_t) FLASH_TIMEOUT_VALUE);
FLASH_PageErase(page, FLASH_BANK_BOTH);
FLASH_WaitForLastOperation((uint32_t) FLASH_TIMEOUT_VALUE);
CLEAR_BIT(FLASH->CR, (FLASH_CR_PER | FLASH_CR_PNB));
HAL_FLASH_Lock();

but to no avail.

Am I missing something obvious?


Solution

  • Found the issue. It has to do with the dual-bank flash on the STM32L476. Erasing page 256 erases page 0 in bank 1 instead.

    Correctly checking for that and erasing the correct page would look like this:

    uint32_t page = 256;
    HAL_FLASH_Unlock();
    FLASH_PageErase(page & 0xFF, (page & 0x100) == 0 ? FLASH_BANK_1 : FLASH_BANK_2);
    FLASH_WaitForLastOperation((uint32_t) FLASH_TIMEOUT_VALUE);
    CLEAR_BIT(FLASH->CR, (FLASH_CR_PER | FLASH_CR_PNB));
    HAL_FLASH_Lock();