Search code examples
cgccstm32halusb-mass-storage

How can I erase an internal flash Page (not sector!) in my STM32F405RG while using HAL?


I've reached a dead end trying manage the internal flash in the STM32F4 microcontroller. There are many examples but most of them use the SPL API or low-level register operations. I am using the HAL libraries. And I cannot find a function to erase just one page (in stm32f4xx_hal_flash.c and stm32f4xx_hal_flash_ex.c). Suggested functions such as HAL_StatusTypeDef HAL_FLASHEx_Erase(FLASH_EraseInitTypeDef *pEraseInit, uint32_t *SectorError) or void FLASH_Erase_Sector(uint32_t Sector, uint8_t VoltageRange) don't allow you to erase one page only (2048 kByte) but only a whole sector (or sectors). When I try to use something like:

void Internal_Flash_Erase(unsigned int pageAddress) {
while (FLASH->SR & FLASH_SR_BSY);
if (FLASH->SR & FLASH_SR_EOP) {
    FLASH->SR = FLASH_SR_EOP;
}

FLASH->CR |= FLASH_CR_PER;
FLASH->AR = pageAddress;
FLASH->CR |= FLASH_CR_STRT;
while (!(FLASH->SR & FLASH_SR_EOP));
FLASH->SR = FLASH_SR_EOP;
FLASH->CR &= ~FLASH_CR_PER;

}

a compiler error occurs because there is no FLASH->AR (Adress Register) in HAL. I found reading the RM0090 Reference manual that now I need to use FLASH->CR instead AR and set the bits FLASH_CR_SNB [3:6] to choose the sector number.

And now I don't know how to erase only one page. It is necessary for creating a Mass Storage Device in internal flash for the function: int8_t STORAGE_Write_FS (uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len) in usbd_storage_if.c that translates USB-stack calls to internal flash.


Solution

  • You can't. The smallest part you can erase is a sector.

    I quote from the reference manual:

    3.6.3 Erase

    The Flash memory erase operation can be performed at sector level or on the whole Flash> memory (Mass Erase). Mass Erase does not affect the OTP sector or the configuration sector.

    This is why the sectors have different sizes. It's important to lay out your software to use the sectors cleverly, considering when you might need to erase flash data.

    You'er probably going to need to buffer entire sectors in RAM, in order to implement flash-writing with file system-like granularity.