Topic : Problem performing IAP EEPROM programming on STM8

Forum : ST7/STM8

Original Post
Post Information Post
July 22, 2011 - 12:21pm


I have a problem trying to write data to the internal EEPROM of a STM8S103 microcontroller. If I understood the corresponding documentation correctly, the sequence to programm EEPROM from within a running application is the following:

  1. unlock EEPROM[/*]
  2. activate word programming by writing the correct bits to FLASH_CR2 and FLASH_NCR2[/*]
  3. write the 4 bytes that are to be stored in EEPROM[/*]
  4. poll the EOP bit in FLASH_IAPSR register until it signals the end of the programming process[/*]

My problem already starts with the first step, unlocking the EEPROM. For this I wrote a little function writing the expected MASS keys to the DUKR register of the microcontroller. After doing that it checks whether EEPROM is unlocked by checking the DUL bit of the IAPSR register and returns OK if unlock was successful and ERROR otherwise. The function looks like this:

STATUS eeprom_write_enable()
  STATUS retVal = ERROR;
  FLASH_t *flashPeriph = FLASH;

  flashPeriph->DUKR = FLASH_PUKR_PUK;
  flashPeriph->DUKR = FLASH_DUKR_DUK;
  if ((flashPeriph->IAPSR & FLASH_IAPSR_DUL) == FLASH_IAPSR_DUL)
    retVal = OK;
} /* end of eeprom_write_enable */

The typedef for FLASH_t and the values used in the function are defined in a description header I made and look like this:

/* FLASH program and data memory (FLASH) */
typedef struct FLASH_Struct
  volatile UCHAR8 CR1;             /* Flash control register 1 */
  volatile UCHAR8 CR2;             /* Flash control register 2 */
  volatile UCHAR8 NCR2;           /* Flash complementary control register 2 */
  volatile UCHAR8 FPR;              /* Flash protection register */
  volatile UCHAR8 NFPR;            /* Flash complementary protection register */
  volatile UCHAR8 IAPSR;           /* Flash in-application programming status register */
  volatile UCHAR8 RESERVED1;  /* Reserved byte */
  volatile UCHAR8 RESERVED2;  /* Reserved byte */
  volatile UCHAR8 PUKR;            /* Flash program memory unprotection register */
  volatile UCHAR8 RESERVED3;  /* Reserved byte */
  volatile UCHAR8 DUKR;            /* Data EEPROM unprotection register */
} FLASH_t;

/*FLASH_Registers_Reset_Value */
#define FLASH_CR1_RESET_VALUE   ((UCHAR8)0x00)
#define FLASH_CR2_RESET_VALUE   ((UCHAR8)0x00)
/* end of FLASH_Registers_Reset_Value */

/* FLASH_Registers_Bits_Definition */
#define FLASH_CR1_IE          ((UCHAR8)0x02)   /* Flash Interrupt enable */
#define FLASH_CR1_FIX         ((UCHAR8)0x01)  /* Fixed Byte programming time */

#define FLASH_CR2_OPT         ((UCHAR8)0x80)    /* Write option bytes */
#define FLASH_CR2_WP          ((UCHAR8)0x40)    /* Word programming */
#define FLASH_CR2_ERASE       ((UCHAR8)0x20)  /* Block erasing */
#define FLASH_CR2_PRG         ((UCHAR8)0x01)    /* Standard block programming */

#define FLASH_NCR2_NOPT       ~((UCHAR8)0x80)   /* Write option bytes (negated) */
#define FLASH_NCR2_NWP        ~((UCHAR8)0x40)   /* Word programming (negated) */
#define FLASH_NCR2_NERASE     ~((UCHAR8)0x20) /* Block erasing (negated) */
#define FLASH_NCR2_NPRG       ~((UCHAR8)0x01)   /* Standard block programming (negated) */

#define FLASH_IAPSR_HVOFF     ((UCHAR8)0x40)       /* End of high voltage flag */
#define FLASH_IAPSR_DUL       ((UCHAR8)0x08)         /* Data EEPROM area unlocked flag */
#define FLASH_IAPSR_EOP       ((UCHAR8)0x04)         /* End of programming flag */
#define FLASH_IAPSR_PUL       ((UCHAR8)0x02)         /* Flash Program memory unlocked flag */
#define FLASH_IAPSR_WR_PG_DIS ((UCHAR8)0x01)  /* Write attempted to protected page */

#define FLASH_PUKR_PUK        ((UCHAR8)0xAE)  /* Flash program MASS key 2, data EEPROM MASS key 1 */
#define FLASH_DUKR_DUK        ((UCHAR8)0x56)  /* Data EEPROM MASS key 2, flash program MASS key 1 */
/* end of FLASH_Registers_Bits_Definition */

/* FLASH base address */
#define FLASH_BASE_ADDRESS       0x505A

Now my understanding of the MASS unlock sequence is, that if I perform a write of the correct key sequence to the DUKR register, EEPROM write access should be unlocked and this should be signaled in the DUL bit of the IAPSR register. This never happens for me. After writing to the DUKR register, IAPSR remains at the default value of 0x00 and subsequently no write access to EEPROM can be performed.

I tested the code in the simulator and on our real hardware and both showed the same behaviour.

I am using Ride7 version nad RKit-STM8 for Ride7 version

Am I missing something that has to be done in order to be able to unlock EEPROM for write access or can you help me find out why I am not able to unlock EEPROM?

Thanks in advance for your help.

Post Information Post
July 25, 2011 - 9:25am
Raisonance Support Team

Hi Stephan,

Your idea looks correct. However I do not see why you rewrite the functions already available from the ST firmware libraries.
You may want to experiment first with the "FLASH_WriteWordOperation" example to validate that it works.

Also, please note that our simulator is a CORE simulator. The peripherals are not simulated, hence the memory is always in read-write mode, and IAPSR will never change by itself.

I hope this helps.
Best Regards,

August 16, 2011 - 4:02pm


for our project, I only need a small part of the functionality the ST firmware library has to offer for EEPROM access (basically I only need a function to write words and to read an EEPROM block).

Since no unused code may remain in the project, due to certification issues, I would need to at least strip down the library supplied by Raisonance. Therefore I decided to rather rewrite it in order to have code that complies to our coding and style guides.

But I followed your advice and played around a bit with the library in order to perform some tests. The write enable is working correctly now.

Tanks for your help and regards,