Electronic – STM32F0 internal EEPROM read and write limit for a variable

eepromstm32

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 */
 #define EEPROM_START_ADDRESS  ((uint32_t)ADDR_FLASH_PAGE_30) /* 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)(EEPROM_START_ADDRESS + 0x400))
  #define PAGE1_END_ADDRESS     ((uint32_t)(EEPROM_START_ADDRESS + PAGE_SIZE 
  - 1))

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

     /* 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 
    receive data */
    #define VALID_PAGE            ((uint16_t)0x0000)     /* Page containing 
    valid data */

    /* Valid pages in read and write defines */
    #define READ_FROM_VALID_PAGE  ((uint8_t)0x00)
    #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);
      uint16_t EE_ReadVariable(uint16_t VirtAddress, uint16_t* Data);
      uint16_t EE_WriteVariable(uint16_t VirtAddress, uint16_t Data);


      #endif /* __EEPROM_H */

I write two functions for read and write memory.

FLASH_Unlock();

EE_Init();

EE_ReadVariable( ++i , &alarm_counter );

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();

 EE_ReadVariable(VirtAddVarTab[0], &VirtdataTab[0]);

 alarm_counter = VirtdataTab[0] + 1;

 EE_WriteVariable( VirtAddVarTab[0] , alarm_counter ); 

 FLASH_Lock();  

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

Does 0x0100 is this address in .h file?
#define ADDR_FLASH_PAGE_0 ((uint32_t)0x08000800)

Best Answer

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();
EE_ReadVariable(EE_KEY_ALARM_COUNTER, &alarm_counter);

alarm_counter++;

EE_WriteVariable(EE_KEY_ALARM_COUNTER, alarm_counter); 
FLASH_Lock();