# STM32F0 internal EEPROM read and write limit for a variable

I use st eeprom emulation library to save my variables. I want to increase the variable when I push the button and save it to eeprom. It works good until 256 but after 256, microcontroller stop working. It seems it works 256 times and I can write 256 times in a page, but I want to read and write more than that. Where is the problem? This is .h library

/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __EEPROM_H
#define __EEPROM_H

/* Includes -----------------------------------------------------------------
-*/ #include "stm32f0xx.h"

/* Exported constants -----------------------------------------------------
---*/

/* Base address of the Flash sectors */
#define ADDR_FLASH_PAGE_0     ((uint32_t)0x08000800) /* Base @ of Page 0, 1
Kbytes *///0x08000000
#define ADDR_FLASH_PAGE_1     ((uint32_t)0x08001000) /* Base @ of Page 1, 1
Kbytes *///0x08000400
#define ADDR_FLASH_PAGE_2     ((uint32_t)0x08001800) /* Base @ of Page 2, 1
Kbytes *///0x08000800
#define ADDR_FLASH_PAGE_3     ((uint32_t)0x08002000) /* Base @ of Page 3, 1
Kbytes *///0x08000C00
#define ADDR_FLASH_PAGE_4     ((uint32_t)0x08002800) /* Base @ of Page 4, 1
Kbytes *///0x08001000
#define ADDR_FLASH_PAGE_5     ((uint32_t)0x08003000) /* Base @ of Page 5, 1
Kbytes *///0x08001400
#define ADDR_FLASH_PAGE_6     ((uint32_t)0x08003800) /* Base @ of Page 6, 1
Kbytes *///0x08001800
#define ADDR_FLASH_PAGE_7     ((uint32_t)0x08004000) /* Base @ of Page 7, 1
Kbytes *///0x08001C00
#define ADDR_FLASH_PAGE_8     ((uint32_t)0x08004800) /* Base @ of Page 8, 1
Kbytes *///0x08002000
#define ADDR_FLASH_PAGE_9     ((uint32_t)0x08005000) /* Base @ of Page 9, 1
Kbytes *///0x08002400
#define ADDR_FLASH_PAGE_10    ((uint32_t)0x08005800) /* Base @ of Page 10, 1
Kbytes *///0x08002800
#define ADDR_FLASH_PAGE_11    ((uint32_t)0x08006000) /* Base @ of Page 11, 1
Kbytes *///0x08002C00
#define ADDR_FLASH_PAGE_12    ((uint32_t)0x08006800) /* Base @ of Page 12, 1
Kbytes *///0x08003000
#define ADDR_FLASH_PAGE_13    ((uint32_t)0x08007000) /* Base @ of Page 13, 1
Kbytes *///0x08003400
#define ADDR_FLASH_PAGE_14    ((uint32_t)0x08007800) /* Base @ of Page 14, 1
Kbytes *///0x08003800
#define ADDR_FLASH_PAGE_15    ((uint32_t)0x08008000) /* Base @ of Page 15, 1
Kbytes *///0x08003C00
#define ADDR_FLASH_PAGE_16    ((uint32_t)0x08008800) /* Base @ of Page 16, 1
Kbytes *///0x08004000
#define ADDR_FLASH_PAGE_17    ((uint32_t)0x08009000) /* Base @ of Page 17, 1
Kbytes *///0x08004400
#define ADDR_FLASH_PAGE_18    ((uint32_t)0x08009800) /* Base @ of Page 18, 1
Kbytes *///0x08004800
#define ADDR_FLASH_PAGE_19    ((uint32_t)0x0800A000) /* Base @ of Page 19, 1
Kbytes *///0x08004C00
#define ADDR_FLASH_PAGE_20    ((uint32_t)0x0800A800) /* Base @ of Page 20, 1
Kbytes *///0x08005000
#define ADDR_FLASH_PAGE_21    ((uint32_t)0x0800B000) /* Base @ of Page 21, 1
Kbytes *///0x08005400
#define ADDR_FLASH_PAGE_22    ((uint32_t)0x0800B800) /* Base @ of Page 22, 1

/* Define the size of the sectors to be used */
//#define PAGE_SIZE               (uint32_t)FLASH_PAGE_SIZE  /* Page size */
#define PAGE_SIZE             ((uint32_t)0x0800)
/* EEPROM start address in Flash */
/* Change this if you need more EEPROM space and require less programming
space */

/* Pages 0 and 1 base and end addresses */
- 1)))

- 1))

/* Used Flash pages for EEPROM emulation */
#define PAGE1                 ((uint16_t)1) /* Page nb between

/* No valid page define */
#define NO_VALID_PAGE         ((uint16_t)0x00AB)

/* Page status definitions */
#define ERASED                ((uint16_t)0xFFFF)     /* Page is empty */
#define RECEIVE_DATA          ((uint16_t)0xEEEE)     /* Page is marked to
#define VALID_PAGE            ((uint16_t)0x0000)     /* Page containing
valid data */

/* Valid pages in read and write defines */
#define WRITE_IN_VALID_PAGE   ((uint8_t)0x01)

/* Page full define */
#define PAGE_FULL             ((uint8_t)0x80)

/* Variables' number */
#define NB_OF_VAR             ((uint8_t)0x04)

/* Exported types ------------------------------------------------------------*/
/* Exported macro ------------------------------------------------------------*/
/* Exported functions ------------------------------------------------------- */
uint16_t EE_Init(void);

#endif /* __EEPROM_H */


I write two functions for read and write memory.

FLASH_Unlock();

EE_Init();

FLASH_Lock();


and

FLASH_Unlock();

EE_Init();

EE_WriteVariable( ++i , alarm_counter );

FLASH_Lock();


I changed my code like this:

uint16_t VirtAddVarTab[10] = {0,1,2,3,4,5,6,7,8,9};

uint16_t VirtdataTab[10] = {0,0,0,0,0,0,0,0,0,0};

uint16_t alarm_counter = 0;

......

FLASH_Unlock();

EE_Init();

alarm_counter = VirtdataTab[0] + 1;

FLASH_Lock();


Do I have to use address like 0x0100 or it is correct to use like this in my code?

• I have never used that library but I have read its docs. Normally, it should switch to another page and erase the old one. There may be short delays due to page migration process, but it should allow continuous writes after the migration. Maybe you have errors in your configuration. Please share your code. – Tagli Apr 17 at 9:59
• @Tagli : I updated the post and insert the code – Hamed P Apr 17 at 10:16
• In your new code, I don't understand the purpose of VirtdataTab. What is it for? Why an array? – Codo Apr 18 at 12:28

I looks as if you misunderstood the EEPROM API (probably due to its poor documentation). Your code modifies the key instead of the value and once the page is full, it will not migrate the correct values to the new page as it only works for a fixed set of keys.

Assuming that alarm_counter is in fact the values that you want to increase when the button is pressed, your code should look like this:

#define NB_OF_VAR 1

...

#define EE_KEY_ALARM_COUNTER 0x0100

uint16_t VirtAddVarTab[NB_OF_VAR] = { EE_KEY_ALARM_COUNTER };

uint16_t alarm_counter;

...

FLASH_Unlock();
EE_Init();

alarm_counter++;

EE_WriteVariable(EE_KEY_ALARM_COUNTER, alarm_counter);
FLASH_Lock();

• I add my modified code below. But I can just write 256 times – Hamed P Apr 18 at 4:30
• In your new code, I don't understand the purpose of VirtdataTab. What is it for? Why an array? Note that NB_OF_VAR  and VirtAddVarTab aren't just a random names. They must be declared like this for the EEPROM emulation library to work. – Codo Apr 18 at 9:00

I want to increase the variable when I push the button and save it to eeprom.

What you're doing is incrementing the address (i), so you're writing the value of alarm_counter across a whole page of Flash.

• How can I fix it? How many variables I can save in one page? – Hamed P Apr 17 at 10:34
• Stop incrementing i and increment alarm_counter instead maybe? – pjc50 Apr 17 at 10:36
• EE_WriteVariable( i , alarm_counter++ ); like this? – Hamed P Apr 17 at 10:37

I found the problem. There is a define in eeprom.h file for page size. It was:

#define PAGE_SIZE ((uint32_t)0x0800)

I changed it to :

#define PAGE_SIZE             0x400U


And everything works without problem