Skip to main content
declareupdate
Associate III
March 9, 2021
Question

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

  • March 9, 2021
  • 3 replies
  • 1125 views

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.

This topic has been closed for replies.

3 replies

Tesla DeLorean
Guru
March 9, 2021

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 VenmoUp vote any posts that you find helpful, it shows what's working..
declareupdate
Associate III
March 9, 2021

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
March 9, 2021
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.