cancel
Showing results for 
Search instead for 
Did you mean: 

STM32 FLASH Write Protection Error

Jouls
Associate II

Hi there!
I was trying to emulate eeprom using flash memory. I am using Nucleo-F030R8 board. I was able to program flash 2 times (0xF055 was the test value):

Jouls_1-1692196000827.png

however I cannot reproduce it anymore and whilst trying to program I get PGERR.
Uploading my code below

main.c
//while() loop - event triggered on the button press

uint8_t data[2] = {0x02 , 0x55};
if(ee_write(0, 1, (uint8_t*)data) == true)
//success
else
//fail

 I'm using flash page 60, starting from address 0x0800F000 (_EE_ADDR_INUSE )

bool ee_write(uint32_t startVirtualAddress, uint32_t len, uint8_t *data) {
  if ((startVirtualAddress + len) > _EE_SIZE)
    return false;
  if (data == NULL)
    return false;

  HAL_FLASH_Unlock();

  if(*(__IO uint16_t*)_EE_ADDR_INUSE != 0xFFFF){
    FLASH_PageErase(startVirtualAddress + _EE_ADDR_INUSE);
  FLASH->CR &= ~FLASH_CR_PER;
  }

#ifdef FLASH_TYPEPROGRAM_HALFWORD
  for (uint32_t i = 0; i < len ; i+=2) {
    if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, ((i + startVirtualAddress)) + _EE_ADDR_INUSE, (uint64_t)(data[i] | (data[i+1] << 8))) != HAL_OK)
    {
      HAL_FLASH_Lock();
      return false;
    }
  }
#endif
  HAL_FLASH_Lock();
  return true;
}

 And the error occurs while trying to execute last line of code in that function

static void FLASH_Program_HalfWord(uint32_t Address, uint16_t Data)
{
/* Clean the error context */
pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;

/* Proceed to program the new data */
SET_BIT(FLASH->CR, FLASH_CR_PG);

/* Write data in the address */
*(__IO uint16_t*)Address = Data;
}

 What am I missing?

1 ACCEPTED SOLUTION

Accepted Solutions
Florian LR
ST Employee

Hi @Jouls, and welcome to the STCommunity !
You are trying to write again at the same address, and @Bob S is right about the fact you can't overwrite an existing value in the flash.

You can fin the explanation in the Reference Manual :
The flash memory interface preliminarily reads the value at the addressed main flash
memory location and checks that it has been erased. If not, the program operation is
skipped and a warning is issued by the PGERR bit in FLASH_SR register.

You can either write to a new location, or erase the current sector of the flash using the HAL function : 

FLASH_PageErase(PageAddress) (you can find this function in the file stm32f0xx_hal_flash_ex.c).

I hope this will help you !

 

BR, 

Florian LR

View solution in original post

3 REPLIES 3
Bob S
Principal

I've never used the F0 series, but in general you can't write to any FLASH location more than once without erasing the entire sector of FLASH in between writes.

Florian LR
ST Employee

Hi @Jouls, and welcome to the STCommunity !
You are trying to write again at the same address, and @Bob S is right about the fact you can't overwrite an existing value in the flash.

You can fin the explanation in the Reference Manual :
The flash memory interface preliminarily reads the value at the addressed main flash
memory location and checks that it has been erased. If not, the program operation is
skipped and a warning is issued by the PGERR bit in FLASH_SR register.

You can either write to a new location, or erase the current sector of the flash using the HAL function : 

FLASH_PageErase(PageAddress) (you can find this function in the file stm32f0xx_hal_flash_ex.c).

I hope this will help you !

 

BR, 

Florian LR

Jouls
Associate II

You were right! Thank you all for help.
I edited the post so that one can use is in the future.