2025-12-02 11:53 PM
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