cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F031G8, getting a hard fault in any attempt at eeprom emulation, specifically on page erase.

declareupdate
Associate III

Howdy,

I'm ending up in the hard fault handler on any attempt at page erase. Using the function from stm32g0xx_hal_flash_ex.c

void FLASH_PageErase(uint32_t Banks, uint32_t Page)
{
  volatile uint32_t tmp;
 
  /* Check the parameters */
  assert_param(IS_FLASH_BANK(Banks));
  assert_param(IS_FLASH_PAGE(Page));
 
  /* Get configuration register, then clear page number */
  tmp = (FLASH->CR & ~FLASH_CR_PNB);
 
#if defined(FLASH_DBANK_SUPPORT)
  /* Check if page has to be erased in bank 1 or 2 */
  if(Banks != FLASH_BANK_1)
  {
    tmp |= FLASH_CR_BKER;
  }
  else
  {
    tmp &= ~FLASH_CR_BKER;
  }
#endif
 
  /* Set page number, Page Erase bit & Start bit */
  FLASH->CR = (tmp | (FLASH_CR_STRT | (Page <<  FLASH_CR_PNB_Pos) | FLASH_CR_PER));
}

There on line 25, I crash when writing to FLASH->CR; I've confirmed that just setting the FLASH_CR_PER bit causes the hard fault.

I tried using ST's provided eeprom emulation firmware as well, with the same result in the same function. Any ideas what is going on here? Or maybe some simple verified code to store and retrieve a value from flash?

Thanks in advance.

3 REPLIES 3

Might be useful to know the parameters it is called with, and the registers reported at the fault. Posted several examples of this.

Most likely the page number is wrong, too large, or you're erasing pages containing executing code.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
declareupdate
Associate III

Great, thank you! I will post back with this info. Which examples are you referring to? I hadn't realized I can view the registers reported at the fault.

declareupdate
Associate III
HAL_StatusTypeDef flash_page_erase(uint32_t page) {
 
	HAL_StatusTypeDef test = HAL_FLASH_Unlock();
 
	test = FLASH_WaitForLastOperation(1000); //1s timeout
	__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR);
	FLASH_PageErase(FLASH_BANK_1, page);
	test = FLASH_WaitForLastOperation(1000);
	CLEAR_BIT(FLASH->CR, FLASH_CR_PER);
 
	HAL_FLASH_Lock();
	return test;
}
 
void flash_write_test() {
	for (uint16_t i = 0; i < 1024; ++i) {
		EE_Array[i] = i * 33;
        }
	write_EEdata2Flash();
	for (uint16_t i = 0; i < 1024; ++i) {
		if (FEE_ReadDataWord(i) != i * 33) {
			i--; // breakpoint here
                }
        }
}
 
void write_EEdata2Flash() {
	uint32_t i;
	uint64_t data;
 
	flash_page_erase(31); //Page clear
 
	flashAdr = FEE_PAGE_BASE_ADDRESS; // = 0x800F800, 64k - 2k, attempting to write to the last page. 
 
	for (i = 0; i < FEE_PAGE_SIZE / 2; i++) //pack up array values into double words 
			{
		data = EE_Array[i++];
		data |= (uint64_t) EE_Array[i++] << 16;
		data |= (uint64_t) EE_Array[i++] << 32;
		data |= (uint64_t) EE_Array[i++] << 48;
		flash_write(flashAdr, data);
		flashAdr += 8;
	}
}
 
void flash_write(uint32_t address, uint64_t data) {
	HAL_FLASH_Unlock();
	HAL_FLASH_Program(TYPEPROGRAM_DOUBLEWORD, address, data);
	HAL_FLASH_Lock();
}

I'm calling flash_write_test(), which attempts to fill up an array, pack up the array values into double words, write those to flash and read them back.