/** * @brief Writes/upadtes variable data in EEPROM. * @param VirtAddress: Variable virtual address * @param Data: 16 bit data to be written * @retval Success or error status: * - FLASH_COMPLETE: on success * - PAGE_FULL: if valid page is full * - NO_VALID_PAGE: if no valid page was found * - Flash error code: on write Flash error */ uint16_t EE_WriteVariable(uint16_t VirtAddress, uint16_t Data) { uint16_t Status = 0; /* Write the variable virtual address and value in the EEPROM */ Status = EE_VerifyPageFullWriteVariable(VirtAddress, Data); /* In case the EEPROM active page is full */ if(Status == PAGE_FULL) { /* Perform Page transfer */ Status = EE_PageTransfer(VirtAddress, Data); } /* Return last operation status */ return Status; }
uint16 EEPROMClass::init(void) { uint16 status0, status1; FLASH_Status FlashStatus; FLASH_Unlock(); Status = EEPROM_NO_VALID_PAGE; status0 = (*(__io uint16 *)PageBase0); status1 = (*(__io uint16 *)PageBase1); switch (status0) { /* Page0 Page1 ----- ----- EEPROM_ERASED EEPROM_VALID_PAGE Page1 valid, Page0 erased EEPROM_RECEIVE_DATA Page1 need set to valid, Page0 erased EEPROM_ERASED make EE_Format any Error: EEPROM_NO_VALID_PAGE */ case EEPROM_ERASED: if (status1 == EEPROM_VALID_PAGE) // Page0 erased, Page1 valid Status = EE_CheckErasePage(PageBase0, EEPROM_ERASED); else if (status1 == EEPROM_RECEIVE_DATA) // Page0 erased, Page1 receive { FlashStatus = FLASH_ProgramHalfWord(PageBase1, EEPROM_VALID_PAGE); if (FlashStatus != FLASH_COMPLETE) Status = FlashStatus; else Status = EE_CheckErasePage(PageBase0, EEPROM_ERASED); } else if (status1 == EEPROM_ERASED) // Both in erased state so format EEPROM Status = format(); break; /* Page0 Page1 ----- ----- EEPROM_RECEIVE_DATA EEPROM_VALID_PAGE Transfer Page1 to Page0 EEPROM_ERASED Page0 need set to valid, Page1 erased any EEPROM_NO_VALID_PAGE */ case EEPROM_RECEIVE_DATA: if (status1 == EEPROM_VALID_PAGE) // Page0 receive, Page1 valid Status = EE_PageTransfer(PageBase0, PageBase1, 0xFFFF); else if (status1 == EEPROM_ERASED) // Page0 receive, Page1 erased { Status = EE_CheckErasePage(PageBase1, EEPROM_ERASED); if (Status == EEPROM_OK) { FlashStatus = FLASH_ProgramHalfWord(PageBase0, EEPROM_VALID_PAGE); if (FlashStatus != FLASH_COMPLETE) Status = FlashStatus; else Status = EEPROM_OK; } } break; /* Page0 Page1 ----- ----- EEPROM_VALID_PAGE EEPROM_VALID_PAGE Error: EEPROM_NO_VALID_PAGE EEPROM_RECEIVE_DATA Transfer Page0 to Page1 any Page0 valid, Page1 erased */ case EEPROM_VALID_PAGE: if (status1 == EEPROM_VALID_PAGE) // Both pages valid Status = EEPROM_NO_VALID_PAGE; else if (status1 == EEPROM_RECEIVE_DATA) Status = EE_PageTransfer(PageBase1, PageBase0, 0xFFFF); else Status = EE_CheckErasePage(PageBase1, EEPROM_ERASED); break; /* Page0 Page1 ----- ----- any EEPROM_VALID_PAGE Page1 valid, Page0 erased EEPROM_RECEIVE_DATA Page1 valid, Page0 erased any EEPROM_NO_VALID_PAGE */ default: if (status1 == EEPROM_VALID_PAGE) Status = EE_CheckErasePage(PageBase0, EEPROM_ERASED); // Check/Erase Page0 else if (status1 == EEPROM_RECEIVE_DATA) { FlashStatus = FLASH_ProgramHalfWord(PageBase1, EEPROM_VALID_PAGE); if (FlashStatus != FLASH_COMPLETE) Status = FlashStatus; else Status = EE_CheckErasePage(PageBase0, EEPROM_ERASED); } break; } return Status; }
/** * @brief Verify if active page is full and Writes variable in EEPROM. * @param Address: 16 bit virtual address of the variable * @param Data: 16 bit data to be written as variable value * @retval Success or error status: * - FLASH_COMPLETE: on success * - EEPROM_PAGE_FULL: if valid page is full (need page transfer) * - EEPROM_NO_VALID_PAGE: if no valid page was found * - EEPROM_OUT_SIZE: if EEPROM size exceeded * - Flash error code: on write Flash error */ uint16 EEPROMClass::EE_VerifyPageFullWriteVariable(uint16 Address, uint16 Data) { FLASH_Status FlashStatus; uint32 idx, pageBase, pageEnd, newPage; uint16 count; // Get valid Page for write operation pageBase = EE_FindValidPage(); if (pageBase == 0) return EEPROM_NO_VALID_PAGE; // Get the valid Page end Address pageEnd = pageBase + PageSize; // Set end of page for (idx = pageEnd - 2; idx > pageBase; idx -= 4) { if ((*(__io uint16*)idx) == Address) // Find last value for address { count = (*(__io uint16*)(idx - 2)); // Read last data if (count == Data) return EEPROM_OK; if (count == 0xFFFF) { FlashStatus = FLASH_ProgramHalfWord(idx - 2, Data); // Set variable data if (FlashStatus == FLASH_COMPLETE) return EEPROM_OK; } break; } } // Check each active page address starting from begining for (idx = pageBase + 4; idx < pageEnd; idx += 4) if ((*(__io uint32*)idx) == 0xFFFFFFFF) // Verify if element { // contents are 0xFFFFFFFF FlashStatus = FLASH_ProgramHalfWord(idx, Data); // Set variable data if (FlashStatus != FLASH_COMPLETE) return FlashStatus; FlashStatus = FLASH_ProgramHalfWord(idx + 2, Address); // Set variable virtual address if (FlashStatus != FLASH_COMPLETE) return FlashStatus; return EEPROM_OK; } // Empty slot not found, need page transfer // Calculate unique variables in page count = EE_GetVariablesCount(pageBase, Address) + 1; if (count >= (PageSize / 4 - 1)) return EEPROM_OUT_SIZE; if (pageBase == PageBase1) newPage = PageBase0; // New page address where variable will be moved to else newPage = PageBase1; // Set the new Page status to RECEIVE_DATA status FlashStatus = FLASH_ProgramHalfWord(newPage, EEPROM_RECEIVE_DATA); if (FlashStatus != FLASH_COMPLETE) return FlashStatus; // Write the variable passed as parameter in the new active page FlashStatus = FLASH_ProgramHalfWord(newPage + 4, Data); if (FlashStatus != FLASH_COMPLETE) return FlashStatus; FlashStatus = FLASH_ProgramHalfWord(newPage + 6, Address); if (FlashStatus != FLASH_COMPLETE) return FlashStatus; return EE_PageTransfer(newPage, pageBase, Address); }