This commit is contained in:
andrea
2025-12-08 13:48:52 +01:00
parent 792e63b21c
commit 3db6a38a2b
59 changed files with 73522 additions and 48789 deletions

View File

@@ -31,7 +31,6 @@ const uint16_t EE_VirtAddrs[EE_NUM_VIRTUAL_ADDR] =
0x0019, 0x001A, 0x001B, 0x001C,
0x001D, 0x001E, 0x001F, 0x0020
};
/* ========================================================================= */
/* --- Internal helpers ---------------------------------------------------- */
@@ -91,53 +90,63 @@ static uint32_t EE_FindFreeAddress(uint32_t pageBase)
return 0U; /* No space */
}
/* Find latest value of VirtAddress in a specific page */
/* Find latest value of VirtAddress in a specific page (internal, uses EE_Status) */
/* Find latest value of VirtAddress in a specific page (scan forward) */
static EE_Status EE_FindInPage(uint32_t pageBase, uint16_t VirtAddress, uint16_t *Data)
{
uint32_t pageEnd = pageBase + EE_PAGE_SIZE;
uint32_t addr;
uint32_t addr = pageBase + 2U; // skip status halfword
uint32_t pageEnd = pageBase + EE_PAGE_SIZE;
EE_Status result = EE_NOT_FOUND;
uint16_t lastVal = 0;
if (Data == NULL)
return EE_ERROR;
/* Start from last possible record and go backwards */
for (addr = pageEnd - sizeof(EE_Record_t); addr > pageBase + 1U; addr -= sizeof(EE_Record_t))
while (addr <= (pageEnd - sizeof(EE_Record_t)))
{
uint16_t vaddr = *(__IO uint16_t *)addr;
uint16_t value = *(__IO uint16_t *)(addr + 2U);
if (vaddr == 0xFFFFU)
{
/* Empty slot, skip */
continue;
// First empty slot => no more records in this page
break;
}
uint16_t value = *(__IO uint16_t *)(addr + 2U);
if (vaddr == VirtAddress)
{
*Data = value;
return EE_OK;
lastVal = value; // keep most recent
result = EE_OK;
}
addr += sizeof(EE_Record_t); // move 4 bytes forward
}
return EE_NOT_FOUND;
if (result == EE_OK)
*Data = lastVal;
return result;
}
/* Format both pages: erase and set PAGE0 as VALID */
static EE_Status EE_Format(void)
{
if (EE_FlashErasePage(EE_PAGE0_BASE) != HAL_OK)
return EE_ERROR;
return EE_STATUS_ERROR;
if (EE_FlashErasePage(EE_PAGE1_BASE) != HAL_OK)
return EE_ERROR;
return EE_STATUS_ERROR;
if (EE_FlashProgramHalfWord(EE_PAGE0_BASE, EE_PAGE_STATUS_VALID) != HAL_OK)
return EE_ERROR;
return EE_STATUS_ERROR;
/* PAGE1 will remain erased (status = 0xFFFF) */
EE_ActivePageBase = EE_PAGE0_BASE;
return EE_OK;
return EE_STATUS_OK;
}
/* Get the base of the other page */
@@ -157,11 +166,11 @@ static EE_Status EE_PageTransfer(uint16_t VirtAddress, uint16_t Data)
/* Erase new page */
if (EE_FlashErasePage(newBase) != HAL_OK)
return EE_ERROR;
return EE_STATUS_ERROR;
/* Mark new page as RECEIVE */
if (EE_FlashProgramHalfWord(newBase, EE_PAGE_STATUS_RECEIVE) != HAL_OK)
return EE_ERROR;
return EE_STATUS_ERROR;
/* Start writing records just after status */
addr = newBase + 2U;
@@ -180,7 +189,7 @@ static EE_Status EE_PageTransfer(uint16_t VirtAddress, uint16_t Data)
{
/* Read latest value from old active page */
st = EE_FindInPage(oldBase, vaddr, &value);
if (st != EE_OK)
if (st != EE_STATUS_OK)
{
/* Variable never written -> skip */
continue;
@@ -189,27 +198,27 @@ static EE_Status EE_PageTransfer(uint16_t VirtAddress, uint16_t Data)
/* Write record to new page */
if (EE_FlashProgramHalfWord(addr, vaddr) != HAL_OK)
return EE_ERROR;
return EE_STATUS_ERROR;
if (EE_FlashProgramHalfWord(addr + 2U, value) != HAL_OK)
return EE_ERROR;
return EE_STATUS_ERROR;
addr += sizeof(EE_Record_t);
if (addr >= (newBase + EE_PAGE_SIZE))
return EE_NO_SPACE;
return EE_STATUS_NO_SPACE;
}
/* Erase old page */
if (EE_FlashErasePage(oldBase) != HAL_OK)
return EE_ERROR;
return EE_STATUS_ERROR;
/* Mark new page as VALID */
if (EE_FlashProgramHalfWord(newBase, EE_PAGE_STATUS_VALID) != HAL_OK)
return EE_ERROR;
return EE_STATUS_ERROR;
/* Update active page */
EE_ActivePageBase = newBase;
return EE_OK;
return EE_STATUS_OK;
}
/* --- Public API ----------------------------------------------------------- */
@@ -218,8 +227,9 @@ static EE_Status EE_PageTransfer(uint16_t VirtAddress, uint16_t Data)
* Initialize the EEPROM emulation.
* - Checks page statuses and chooses the active page.
* - If inconsistent or blank, formats pages.
* PUBLIC RETURN TYPE: uint16_t (EE_OK / EE_ERROR / ...)
*/
EE_Status EE_Init(void)
uint16_t EE_Init(void)
{
uint16_t status0 = EE_GetPageStatus(EE_PAGE0_BASE);
uint16_t status1 = EE_GetPageStatus(EE_PAGE1_BASE);
@@ -227,7 +237,7 @@ EE_Status EE_Init(void)
if ((status0 == EE_PAGE_STATUS_ERASED) && (status1 == EE_PAGE_STATUS_ERASED))
{
/* Fresh device -> format */
return EE_Format();
return (uint16_t)EE_Format();
}
else if ((status0 == EE_PAGE_STATUS_VALID) && (status1 == EE_PAGE_STATUS_ERASED))
{
@@ -242,27 +252,32 @@ EE_Status EE_Init(void)
else
{
/* Any weird or inconsistent state -> reformat */
return EE_Format();
return (uint16_t)EE_Format();
}
}
/*
* Read a 16-bit variable by its virtual address.
* PUBLIC RETURN: EE_OK / EE_NOT_FOUND / EE_ERROR (as uint16_t)
*/
EE_Status EE_ReadVariable(uint16_t VirtAddress, uint16_t *Data)
uint16_t EE_ReadVariable(uint16_t VirtAddress, uint16_t *Data)
{
EE_Status st;
if (Data == NULL)
return EE_ERROR;
return EE_FindInPage(EE_ActivePageBase, VirtAddress, Data);
st = EE_FindInPage(EE_ActivePageBase, VirtAddress, Data);
return (uint16_t)st;
}
/*
* Write (append) a 16-bit variable.
* - Writes a new record in the active page.
* - If the page is full, triggers a page transfer (GC).
* PUBLIC RETURN: EE_OK / EE_ERROR / EE_NO_SPACE (as uint16_t)
*/
EE_Status EE_WriteVariable(uint16_t VirtAddress, uint16_t Data)
uint16_t EE_WriteVariable(uint16_t VirtAddress, uint16_t Data)
{
uint32_t freeAddr;
EE_Status st;
@@ -282,6 +297,5 @@ EE_Status EE_WriteVariable(uint16_t VirtAddress, uint16_t Data)
/* No space -> page transfer */
st = EE_PageTransfer(VirtAddress, Data);
return st;
return (uint16_t)st;
}