Electronic – Emulated EEPROM using STM32F030K6T6

eepromstm32f0

I've got a project I'm working that is using an STM32F030K6T6. I've followed STM's example of emulated eeprom for the STM32F0xx microcontrollers, but am hitting a Hard Fault when the EEPROM_Init function calls this line:

/* Get Page0 status */
pagestatus0 = (*(__IO uint16_t*)PAGE0_BASE_ADDRESS);

Here's the PDF document for the STM32 help code: https://www.st.com/content/ccc/resource/technical/document/application_note/2e/d4/65/6b/87/dd/40/25/DM00049914.pdf/files/DM00049914.pdf/jcr:content/translations/en.DM00049914.pdf

and here is a link to the eeprom code itself: https://www.st.com/en/embedded-software/stsw-stm32117.html

I left the example as it was in the STM32 code exmaple, so I assume that the addresses should be okay for a medium density STM32.

Here are the definitions related to the emulated EEPROM

#define ADDR_FLASH_PAGE_16    ((uint32_t)0x08008000) /* Base @ of Page 16, 2 Kbytes */

#define ADDR_FLASH_PAGE_48    ((uint32_t)0x08018000) /* Base @ of Page 48, 2 Kbytes */

/* Define the size of the sectors to be used */
#define PAGE_SIZE               (uint32_t)FLASH_PAGE_SIZE  /* Page size */

/* EEPROM start address in Flash */
#define EEPROM_START_ADDRESS  ((uint32_t)ADDR_FLASH_PAGE_16) /* EEPROM emulation start address */

/* Pages 0 and 1 base and end addresses */
#define PAGE0_BASE_ADDRESS    ((uint32_t)(EEPROM_START_ADDRESS + 0x0000))
#define PAGE0_END_ADDRESS     ((uint32_t)(EEPROM_START_ADDRESS + (PAGE_SIZE - 1)))

#define PAGE1_BASE_ADDRESS    ((uint32_t)(ADDR_FLASH_PAGE_48))
#define PAGE1_END_ADDRESS     ((uint32_t)(ADDR_FLASH_PAGE_48 + PAGE_SIZE - 1))

I usually use Microchip parts, but we are switching over to STM32's for a lot of our future products. In other words, I'm a little out of my natural environment.

I am using Atollic and the STM32CubeMX plugin.

Best Answer

You are using code written for a different STM32 chip which is attempting to access an address where no memory exists on your particular chip, so a fault is triggered.

The STM32F030K6T6 has 32K of flash, normally mapped at addresses 0x800000 to 0x807fff.

The net result of your defines:

#define ADDR_FLASH_PAGE_16    ((uint32_t)0x08008000) /* Base @ of Page 16, 2 Kbytes */

#define EEPROM_START_ADDRESS  ((uint32_t)ADDR_FLASH_PAGE_16) /* EEPROM emulation start address */

#define PAGE0_BASE_ADDRESS    ((uint32_t)(EEPROM_START_ADDRESS + 0x0000))

Is that you are trying to access an address right off the end of those physically present. To use this chip, you'll have to move the EEPROM_START_ADDRESS to a different place in memory, and then adjust your linker script to make sure not to overlap that page with code. Probably you would use the last flash erase page actually present - you'll have to consult the flash documentation for your particular chip to make sure you have the right page size and address.

Some STM32 parts famously seem to have more memory than they officially have - for example some of the 16K F0's seem to actually have 32K, and some 64K F1 parts seem to actually have 128K - but your chip does not appear to benefit from such an unofficial capability.