Skip to main content
Visitor II
December 3, 2025
Question

EEPROM Emulation brings EE_ERROR_NOACTIVE_PAGE on STM32U599

  • December 3, 2025
  • 1 reply
  • 80 views

Hi

Initial situation
MCU = STM32U599VJTxQ
STM32CubeIDE = v1.19.0
TouchGFX = v4.26.0
EEPROM Emulator = x-cube-eeprom-v8-0-0 (downloaded direct from STM website)

I use the eeprom emulator to save an array of 251 bytes permant on the flash. To save the data into the flash I use the EE_WriteVariable32bits function

This are my function to init the EEPROM emulator, write data to EEPROM and read data from EEPROM

void Datastore::EEPROM_Init()
{
 HAL_FLASH_Unlock(); // 1. Flash freigeben

 // 2. Sicherstellen, dass Flash idle ist
 uint32_t timeout = 1000000;
 while(__HAL_FLASH_GET_FLAG(FLASH_FLAG_BSY))
 {
 if(timeout-- == 0)
 {
 HAL_FLASH_Lock();
 this->m_errorHdl_p->Add(ERR_ID_EEPROM_INIT_FAILURE);
 return;
 }
 }

 // 3. Critical Section / Interrupts kurz maskieren
 __disable_irq();

 // 4. EEPROM Init mit Retry
 EE_Status status = EE_WRITE_ERROR;
 const uint8_t max_retries = 3;
 uint8_t attempt = 0;

 while(((status != EE_OK) && (status != EE_PAGE_FULL)) && (attempt < max_retries))
 {
 status = EE_Init(EE_FORCED_ERASE);
 attempt++;
 }

 // 5. Interrupts wieder freigeben
 __enable_irq();

 HAL_FLASH_Lock(); // 6. Flash wieder sperren

 // 6. Fehlerbehandlung
 if((status != EE_OK) && (status != EE_PAGE_FULL))
 {
 this->m_errorHdl_p->Add(ERR_ID_EEPROM_INIT_FAILURE);
 }
}


#define EEPROM_WRITE_MAX_RETRIES 5
#define EEPROM_TRANSFER_WAIT_US 10
void Datastore::EEPROM_WriteData()
{
 if (!this->m_isInitDone) return;

 HAL_GPIO_WritePin(RUNLED_GPIO_Port, RUNLED_Pin, GPIO_PIN_SET);
 HAL_FLASH_Unlock();

 // Sicherstellen, dass Flash idle ist
 uint32_t timeout = 1000000;
 while(__HAL_FLASH_GET_FLAG(FLASH_FLAG_BSY))
 {
 if(timeout-- == 0)
 {
 HAL_FLASH_Lock();
 this->m_errorHdl_p->Add(ERR_ID_EEPROM_WRITE_FAILURE);
 HAL_GPIO_WritePin(RUNLED_GPIO_Port, RUNLED_Pin, GPIO_PIN_RESET);
 return;
 }
 }

 __disable_irq(); // IRQs maskieren

 EE_Status status;
 const uint32_t numVars = NB_OF_VARIABLES;

 for (uint32_t varIndex = 0; varIndex < numVars; varIndex++)
 {
 uint8_t attempt = 0;

 do
 {
 status = EE_WriteVariable32bits(varIndex + 1, this->m_parameter.param32[varIndex]);
 attempt++;

 // Wenn Page-Transfer aktiv oder sporadischer Schreibfehler
 if(status == EE_ERROR_NOACTIVE_PAGE || status == EE_WRITE_ERROR)
 {
 // Kurzes Delay, damit Flash Page-Transfer abgeschlossen wird
 for(volatile uint32_t i = 0; i < 10000; i++);
 }

 } while((status == EE_ERROR_NOACTIVE_PAGE || status == EE_WRITE_ERROR) && (attempt < EEPROM_WRITE_MAX_RETRIES));

 if(status != EE_OK)
 {
 // Persistenter Fehler -> abbrechen
 this->m_errorHdl_p->Add(ERR_ID_EEPROM_WRITE_FAILURE);
 break;
 }
 }

 __enable_irq(); // IRQs wieder freigeben
 HAL_FLASH_Lock();
 HAL_GPIO_WritePin(RUNLED_GPIO_Port, RUNLED_Pin, GPIO_PIN_RESET);
}


void Datastore::EEPROM_ReadData()
{
 EE_Status status;

 for (uint32_t varIndex = 0; varIndex < NB_OF_VARIABLES; varIndex++)
 {
 status = EE_ReadVariable32bits(varIndex + 1, &this->m_parameter.param32[varIndex]);
 if (status != EE_OK)
 {
 if (status != EE_NO_DATA) {
 this->m_errorHdl_p->Add(ERR_ID_EEPROM_READ_FAILURE);
 }

 // Setze die Bytes auf Default 0xFF
 uint32_t bytesToClear = 4;
 if(varIndex == NB_OF_VARIABLES - 1)
 {
 // Letzter Block evtl. weniger als 4 Bytes gültig
 bytesToClear = PARAM_DATASTORE_SIZE - (NB_OF_VARIABLES - 1) * 4;
 }

 for(uint32_t i = 0; i < bytesToClear; i++)
 {
 this->m_parameter.param8[varIndex*4 + i] = 0xFF;
 }
 }
 }
}


Here you can see my eeprom_emul_conf.h 

#define PARAM_DATASTORE_SIZE 251

#define START_PAGE_ADDRESS (FLASH_BASE + FLASH_SIZE - 0x20000) /*!< Start address of the 1st page in flash, for EEPROM emulation */
#define CYCLES_NUMBER 2U /*!< Number of 10Kcycles requested, minimum 1 for 10Kcycles (default),
 for instance 10 to reach 100Kcycles. This factor will increase
 pages number */
#define GUARD_PAGES_NUMBER 2U /*!< Number of guard pages avoiding frequent transfers (must be multiple of 2): 0,2,4.. */

/* Configuration of crc calculation for eeprom emulation in flash */
#define CRC_POLYNOMIAL_LENGTH LL_CRC_POLYLENGTH_16B /* CRC polynomial lenght 16 bits */
#define CRC_POLYNOMIAL_VALUE 0x8005U /* Polynomial to use for CRC calculation */

#define NB_OF_VARIABLES ((PARAM_DATASTORE_SIZE + 3) / 4U) /*!< Number of variables to handle in eeprom */



MEMORY
{
 RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 2496K
 SRAM4 (xrw) : ORIGIN = 0x28000000, LENGTH = 16K
 FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 3968K /* 4096K - 128K */
 EEPROM (rx) : ORIGIN = 0x083E0000, LENGTH = 128K
}


The Problem
After writting 10 times the complete array to the EEPROM, then the EEPROM_WriteData function brings an error: EE_ERROR_NOACTIVE_PAGE
It looks like that the page swap does not work as expected. 
Further the compiler brings a warning: 
Description Resource Path Location Type
suggest parentheses around '&&' within '||' [-Wparentheses] eeprom_emul.c /WarmingDrawer_UI/Middlewares/ST/EEPROM_Emul/Core line 1548 C/C++ Problem


Is there a problem with braces around this if statement, in the file "eeprom_emul.c" on line 1548? Is that the reason, why page swap does not work as expected? 

else if ((addressvalue != EE_PAGESTAT_ERASED) || (addressvalue2 != EE_PAGESTAT_ERASED)&&(addressvalue != 0x0000000000000000U)|| (addressvalue2 != 0x0000000000000000U))


Or what else might be wrong, that the page swap does not work?

Thanks a lot for your help
best regards
Markus

    This topic has been closed for replies.

    1 reply

    mraehleAuthor
    Visitor II
    December 11, 2025

    Hi 

    is there anybody who could help me?

    Thanks and best regards
    Markus