/** * @brief Returns the last stored variable data, if found, * which correspond to the passed virtual address * @param Address: Variable virtual address * @param Data: Pointer to data variable * @retval Success or error status: * - EEPROM_OK: if variable was found * - EEPROM_BAD_ADDRESS: if the variable was not found * - EEPROM_NO_VALID_PAGE: if no valid page was found. */ uint16 EEPROMClass::read(uint16 Address, uint16 *Data) { uint32 pageBase, pageEnd; // Set default data (empty EEPROM) *Data = EEPROM_DEFAULT_DATA; if (Status == EEPROM_NOT_INIT) if (init() != EEPROM_OK) return Status; // Get active Page for read operation pageBase = EE_FindValidPage(); if (pageBase == 0) return EEPROM_NO_VALID_PAGE; // Get the valid Page end Address pageEnd = pageBase + ((uint32)(PageSize - 2)); // Check each active page address starting from end for (pageBase += 6; pageEnd >= pageBase; pageEnd -= 4) if ((*(__io uint16*)pageEnd) == Address) // Compare the read address with the virtual address { *Data = (*(__io uint16*)(pageEnd - 2)); // Get content of Address-2 which is variable value return EEPROM_OK; } // Return ReadStatus value: (0: variable exist, 1: variable doesn't exist) return EEPROM_BAD_ADDRESS; }
/******************************************************************************* * Function Name : EE_VerifyPageFullWriteVariable * Description : Verify if active page is full and Writes variable in EEPROM. * Input : - VirtAddress: 16 bit virtual address of the variable * - Data: 16 bit data to be written as variable value * Output : None * Return : - 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 *******************************************************************************/ u16 EE_VerifyPageFullWriteVariable(u16 VirtAddress, u16 Data) { FLASH_Status FlashStatus = FLASH_COMPLETE; u16 ValidPage = PAGE0; u32 Address = 0x08010000, PageEndAddress = 0x080107FF; /* Get valid Page for write operation */ ValidPage = EE_FindValidPage(WRITE_IN_VALID_PAGE); /* Check if there is no valid page */ if (ValidPage == NO_VALID_PAGE) { return NO_VALID_PAGE; } /* Get the valid Page start Address */ Address = (u32)(EEPROM_START_ADDRESS + (u32)(ValidPage * PAGE_SIZE)); /* Get the valid Page end Address */ PageEndAddress = (u32)((EEPROM_START_ADDRESS - 2) + (u32)((1 + ValidPage) * PAGE_SIZE)); /* Check each active page address starting from beginning */ while (Address < PageEndAddress) { /* Verify each time if Address and Address+2 contents are equal to Data and VirtAddress respectively */ if (((*(vu16*)Address) == Data) && ((*(vu16*)(Address + 2)) == VirtAddress)) { return FLASH_COMPLETE; } /* Verify if Address and Address+2 contents are 0xFFFFFFFF */ if ((*(vu32*)Address) == 0xFFFFFFFF) { /* Set variable data */ FlashStatus = FLASH_ProgramHalfWord(Address, Data); /* If program operation was failed, a Flash error code is returned */ if (FlashStatus != FLASH_COMPLETE) { return FlashStatus; } /* Set variable virtual address */ FlashStatus = FLASH_ProgramHalfWord(Address + 2, VirtAddress); /* Return program operation status */ return FlashStatus; } else { /* Next address location */ Address = Address + 4; } } /* Return PAGE_FULL in case the valid page is full */ return PAGE_FULL; }
/** * @brief Verify if active page is full and Writes variable in EEPROM. * @param VirtAddress: 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 * - PAGE_FULL: if valid page is full * - NO_VALID_PAGE: if no valid page was found * - Flash error code: on write Flash error */ static uint16_t EE_VerifyPageFullWriteVariable(uint16_t VirtAddress, uint16_t Data) { FLASH_Status FlashStatus = FLASH_COMPLETE; uint16_t ValidPage = PAGE0; uint32_t Address = EEPROM_START_ADDRESS, PageEndAddress = EEPROM_START_ADDRESS+PAGE_SIZE-1; /* Get valid Page for write operation */ ValidPage = EE_FindValidPage(WRITE_IN_VALID_PAGE); /* Check if there is no valid page */ if (ValidPage == NO_VALID_PAGE) { return NO_VALID_PAGE; } //FLASH_Unlock(); /* Get the valid Page start Address */ Address = (uint32_t)(EEPROM_START_ADDRESS + (uint32_t)(ValidPage * PAGE_SIZE)); /* Get the valid Page end Address */ PageEndAddress = (uint32_t)((EEPROM_START_ADDRESS - 2) + (uint32_t)((1 + ValidPage) * PAGE_SIZE)); /* Check each active page address starting from begining */ while (Address < PageEndAddress) { /* Verify if Address and Address+2 contents are 0xFFFFFFFF */ if ((*(__IO uint32_t*)Address) == 0xFFFFFFFF) { /* Set variable data */ FlashStatus = FLASH_ProgramHalfWord(Address, Data); /* If program operation was failed, a Flash error code is returned */ if (FlashStatus != FLASH_COMPLETE) { //FLASH_Lock(); return FlashStatus; } /* Set variable virtual address */ FlashStatus = FLASH_ProgramHalfWord(Address + 2, VirtAddress); /* Return program operation status */ //FLASH_Lock(); return FlashStatus; } else { /* Next address location */ Address = Address + 4; } } //FLASH_Lock(); /* Return PAGE_FULL in case the valid page is full */ return PAGE_FULL; }
/** * @brief Return number of variable * @retval Number of variables */ uint16 EEPROMClass::count(uint16 *Count) { if (Status == EEPROM_NOT_INIT) if (init() != EEPROM_OK) return Status; // Get valid Page for write operation uint32 pageBase = EE_FindValidPage(); if (pageBase == 0) return EEPROM_NO_VALID_PAGE; // No valid page, return max. numbers *Count = EE_GetVariablesCount(pageBase, 0xFFFF); return EEPROM_OK; }
/** * @brief Returns the last stored variable data, if found, which correspond to * the passed virtual address * @param VirtAddress: Variable virtual address * @param Data: Global variable contains the read variable value * @retval Success or error status: * - 0: if variable was found * - 1: if the variable was not found * - NO_VALID_PAGE: if no valid page was found. */ uint16_t EE_ReadVariable(uint16_t VirtAddress, uint16_t* Data) { uint16_t ValidPage = PAGE0; uint16_t AddressValue = 0x5555, ReadStatus = 1; uint32_t Address = 0x08010000, PageStartAddress = 0x08010000; /* Get active Page for read operation */ ValidPage = EE_FindValidPage(READ_FROM_VALID_PAGE); /* Check if there is no valid page */ if (ValidPage == NO_VALID_PAGE) { return NO_VALID_PAGE; } /* Get the valid Page start Address */ PageStartAddress = (uint32_t)(EEPROM_START_ADDRESS + (uint32_t)(ValidPage * PAGE_SIZE)); /* Get the valid Page end Address */ //Address = (uint32_t)((EEPROM_START_ADDRESS - 2) + (uint32_t)((1 + ValidPage) * PAGE_SIZE)); Address=CurWrAddress-2; /* Check each active page address starting from end */ while (Address > (PageStartAddress + 2)) { /* Get the current location content to be compared with virtual address */ AddressValue = (*(__IO uint16_t*)Address); /* Compare the read address with the virtual address */ if (AddressValue == VirtAddress) { /* Get content of Address-2 which is variable value */ *Data = (*(__IO uint16_t*)(Address - 2)); /* In case variable value is read, reset ReadStatus flag */ ReadStatus = 0; break; } else { /* Next address location */ Address = Address - 4; } } /* Return ReadStatus value: (0: variable exist, 1: variable doesn't exist) */ return ReadStatus; }
/** * @brief Verify if active page is full and Writes variable in EEPROM. * @param VirtAddress: 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 * - PAGE_FULL: if valid page is full * - NO_VALID_PAGE: if no valid page was found * - Flash error code: on write Flash error */ static uint16_t EE_VerifyPageFullWriteVariable(uint16_t VirtAddress, uint16_t Data) { HAL_StatusTypeDef flashstatus = HAL_OK; uint16_t validpage = PAGE0; uint32_t address = EEPROM_START_ADDRESS, pageendaddress = EEPROM_START_ADDRESS+PAGE_SIZE; /* Get valid Page for write operation */ validpage = EE_FindValidPage(WRITE_IN_VALID_PAGE); /* Check if there is no valid page */ if (validpage == NO_VALID_PAGE) { return NO_VALID_PAGE; } /* Get the valid Page start address */ address = (uint32_t)(EEPROM_START_ADDRESS + (uint32_t)(validpage * PAGE_SIZE)); /* Get the valid Page end address */ pageendaddress = (uint32_t)((EEPROM_START_ADDRESS - 1) + (uint32_t)((validpage + 1) * PAGE_SIZE)); /* Check each active page address starting from begining */ while (address < pageendaddress) { /* Verify if address and address+2 contents are 0xFFFFFFFF */ if ((*(__IO uint32_t*)address) == 0xFFFFFFFF) { /* Set variable data */ flashstatus = HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, address, Data); /* If program operation was failed, a Flash error code is returned */ if (flashstatus != HAL_OK) { return flashstatus; } /* Set variable virtual address */ flashstatus = HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, address + 2, VirtAddress); /* Return program operation status */ return flashstatus; } else { /* Next address location */ address = address + 4; } } /* Return PAGE_FULL in case the valid page is full */ return PAGE_FULL; }
/** * @brief Returns the erase counter for current page * @param Data: Global variable contains the read variable value * @retval Success or error status: * - EEPROM_OK: if erases counter return. * - EEPROM_NO_VALID_PAGE: if no valid page was found. */ uint16 EEPROMClass::erases(uint16 *Erases) { uint32 pageBase; if (Status != EEPROM_OK) if (init() != EEPROM_OK) return Status; // Get active Page for read operation pageBase = EE_FindValidPage(); if (pageBase == 0) return EEPROM_NO_VALID_PAGE; *Erases = (*(__io uint16*)pageBase+2); return EEPROM_OK; }
//初始化写地址,减少每次读写时查询时间 uint16_t InitCurrWrAddress(void) { FLASH_Status FlashStatus = FLASH_COMPLETE; uint16_t ValidPage = PAGE0; //uint32_t Address; uint32_t PageEndAddress; /* Get valid Page for write operation */ ValidPage = EE_FindValidPage(WRITE_IN_VALID_PAGE); /* Check if there is no valid page */ if (ValidPage == NO_VALID_PAGE) { CurWrAddress = (uint32_t)(EEPROM_START_ADDRESS + (uint32_t)(ValidPage * PAGE_SIZE)); return NO_VALID_PAGE; } /* Get the valid Page start Address */ //Address = (uint32_t)(EEPROM_START_ADDRESS + (uint32_t)(ValidPage * PAGE_SIZE)); CurWrAddress = (uint32_t)(EEPROM_START_ADDRESS + (uint32_t)(ValidPage * PAGE_SIZE)); /* Get the valid Page end Address */ PageEndAddress = (uint32_t)((EEPROM_START_ADDRESS - 2) + (uint32_t)((1 + ValidPage) * PAGE_SIZE)); /* Check each active page address starting from begining */ while (CurWrAddress < PageEndAddress) { /* Verify if Address and Address+2 contents are 0xFFFFFFFF */ if ((*(__IO uint32_t*)CurWrAddress) == 0xFFFFFFFF) { /* Set variable virtual address */ FlashStatus = FLASH_COMPLETE; /* Return program operation status */ return FlashStatus; } else { /* Next address location */ CurWrAddress = CurWrAddress + 4; } } /* Return PAGE_FULL in case the valid page is full */ return PAGE_FULL; }
/** * @brief Transfers last updated variables data from the full Page to * an empty one. * @param VirtAddress: 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 * - PAGE_FULL: if valid page is full * - NO_VALID_PAGE: if no valid page was found * - Flash error code: on write Flash error */ static uint16_t EE_PageTransfer(uint16_t VirtAddress, uint16_t Data) { FLASH_Status FlashStatus = FLASH_COMPLETE; uint32_t NewPageAddress = 0x00000000, OldPageAddress = 0x00000000; uint16_t ValidPage = PAGE0, VarIdx = 0; uint16_t EepromStatus = 0, ReadStatus = 0; /* Get active Page for read operation */ ValidPage = EE_FindValidPage(READ_FROM_VALID_PAGE); if(ValidPage == PAGE1) { /* Page1 valid */ /* New page address where variable will be moved to */ NewPageAddress = PAGE0_BASE_ADDRESS; /* Old page address where variable will be taken from */ OldPageAddress = PAGE1_BASE_ADDRESS; } else if(ValidPage == PAGE0) { /* Page0 valid */ /* New page address where variable will be moved to */ NewPageAddress = PAGE1_BASE_ADDRESS; /* Old page address where variable will be taken from */ OldPageAddress = PAGE0_BASE_ADDRESS; } else { return NO_VALID_PAGE; /* No valid Page */ } /* Set the new Page status to RECEIVE_DATA status */ FlashStatus = FLASH_ProgramHalfWord(NewPageAddress, RECEIVE_DATA); /* If program operation was failed, a Flash error code is returned */ if(FlashStatus != FLASH_COMPLETE) { return FlashStatus; } /* Write the variable passed as parameter in the new active page */ EepromStatus = EE_VerifyPageFullWriteVariable(VirtAddress, Data); /* If program operation was failed, a Flash error code is returned */ if(EepromStatus != FLASH_COMPLETE) { return EepromStatus; } /* Transfer process: transfer variables from old to the new active page */ for(VarIdx = 0; VarIdx < NumbOfVar; VarIdx++) { if(VirtAddVarTab[VarIdx] != VirtAddress) { /* Check each variable except the one passed as parameter */ /* Read the other last variable updates */ ReadStatus = EE_ReadVariable(VirtAddVarTab[VarIdx], &DataVar); /* In case variable corresponding to the virtual address was found */ if(ReadStatus != 0x1) { /* Transfer the variable to the new active page */ EepromStatus = EE_VerifyPageFullWriteVariable(VirtAddVarTab[VarIdx], DataVar); /* If program operation was failed, a Flash error code is returned */ if(EepromStatus != FLASH_COMPLETE) { return EepromStatus; } } } } /* Erase the old Page: Set old Page status to ERASED status */ FlashStatus = FLASH_ErasePage(OldPageAddress); /* If erase operation was failed, a Flash error code is returned */ if(FlashStatus != FLASH_COMPLETE) { return FlashStatus; } /* Set new Page status to VALID_PAGE status */ FlashStatus = FLASH_ProgramHalfWord(NewPageAddress, VALID_PAGE); /* If program operation was failed, a Flash error code is returned */ if(FlashStatus != FLASH_COMPLETE) { return FlashStatus; } /* Return last operation flash status */ return FlashStatus; }
/** * @brief Transfers last updated variables data from the full Page to * an empty one. * @param VirtAddress: 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 * - PAGE_FULL: if valid page is full * - NO_VALID_PAGE: if no valid page was found * - Flash error code: on write Flash error */ static uint16_t EE_PageTransfer(uint16_t VirtAddress, uint16_t Data) { FLASH_Status FlashStatus = FLASH_COMPLETE; uint32_t NewPageAddress = 0x080103FF, OldPageAddress = 0x08010000; uint16_t ValidPage = PAGE0, VarIdx = 0; uint16_t EepromStatus = 0; /* Get active Page for read operation */ ValidPage = EE_FindValidPage(READ_FROM_VALID_PAGE); if (ValidPage == PAGE1) /* Page1 valid */ { /* New page address where variable will be moved to */ NewPageAddress = PAGE0_BASE_ADDRESS; /* Old page address where variable will be taken from */ OldPageAddress = PAGE1_BASE_ADDRESS; } else if (ValidPage == PAGE0) /* Page0 valid */ { /* New page address where variable will be moved to */ NewPageAddress = PAGE1_BASE_ADDRESS; /* Old page address where variable will be taken from */ OldPageAddress = PAGE0_BASE_ADDRESS; } else { return NO_VALID_PAGE; /* No valid Page */ } /* Set the new Page status to RECEIVE_DATA status */ FlashStatus = FLASH_ProgramHalfWord(NewPageAddress, RECEIVE_DATA); /* If program operation was failed, a Flash error code is returned */ if (FlashStatus != FLASH_COMPLETE) { return FlashStatus; } /* Write the variable passed as parameter in the new active page */ EepromStatus = EE_VerifyPageFullWriteVariable(VirtAddress, Data); /* If program operation was failed, a Flash error code is returned */ if (EepromStatus != FLASH_COMPLETE) { return EepromStatus; } /* First transfer the contiguous region of addresses */ for (VarIdx = 0; VarIdx < EE_MAX_CONTIGUOUS; VarIdx++) { /* Check each variable except the one passed as parameter */ if (VarIdx != VirtAddress) { EepromStatus = EE_TransferVariable(VarIdx, NewPageAddress); if (EepromStatus != FLASH_COMPLETE) return EepromStatus; } } /* Then the individual addresses in the address table */ for (VarIdx = 0; VarIdx < EE_NUM_ADDR; VarIdx++) { if (ee_addr_table[VarIdx] != VirtAddress) { EepromStatus = EE_TransferVariable(ee_addr_table[VarIdx], NewPageAddress); if (EepromStatus != FLASH_COMPLETE) return EepromStatus; } } /* Erase the old Page: Set old Page status to ERASED status */ FlashStatus = FLASH_ErasePage(OldPageAddress); /* If erase operation was failed, a Flash error code is returned */ if (FlashStatus != FLASH_COMPLETE) { return FlashStatus; } /* Set new Page status to VALID_PAGE status */ FlashStatus = FLASH_ProgramHalfWord(NewPageAddress, VALID_PAGE); /* If program operation was failed, a Flash error code is returned */ if (FlashStatus != FLASH_COMPLETE) { return FlashStatus; } /* Return last operation flash status */ return FlashStatus; }
/** * @brief Transfers last updated variables data from the full Page to * an empty one. * @param VirtAddress: 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 * - PAGE_FULL: if valid page is full * - NO_VALID_PAGE: if no valid page was found * - Flash error code: on write Flash error */ static uint16_t EE_PageTransfer(uint16_t VirtAddress, uint16_t Data) { FLASH_Status FlashStatus = FLASH_COMPLETE; uint32_t NewPageAddress = PAGE1_BASE_ADDRESS, OldPageAddress = PAGE0_BASE_ADDRESS; uint16_t ValidPage = PAGE0, VarIdx = 0; uint16_t EepromStatus = 0, ReadStatus = 0; /* Get active Page for read operation */ ValidPage = EE_FindValidPage(READ_FROM_VALID_PAGE); if (ValidPage == PAGE1) /* Page1 valid */ { /* New page address where variable will be moved to */ NewPageAddress = PAGE0_BASE_ADDRESS; /* Old page address where variable will be taken from */ OldPageAddress = PAGE1_BASE_ADDRESS; } else if (ValidPage == PAGE0) /* Page0 valid */ { /* New page address where variable will be moved to */ NewPageAddress = PAGE1_BASE_ADDRESS; /* Old page address where variable will be taken from */ OldPageAddress = PAGE0_BASE_ADDRESS; } else { return NO_VALID_PAGE; /* No valid Page */ } //FLASH_Unlock(); /* Set the new Page status to RECEIVE_DATA status */ FlashStatus = FLASH_ProgramHalfWord(NewPageAddress, RECEIVE_DATA); /* If program operation was failed, a Flash error code is returned */ if (FlashStatus != FLASH_COMPLETE) { //FLASH_Lock(); return FlashStatus; } /* Write the variable passed as parameter in the new active page */ EepromStatus = EE_VerifyPageFullWriteVariable(VirtAddress, Data); /* If program operation was failed, a Flash error code is returned */ if (EepromStatus != FLASH_COMPLETE) { //FLASH_Lock(); return EepromStatus; } /* Transfer process: transfer variables from old to the new active page */ for (VarIdx = 0; VarIdx < NB_OF_VAR; VarIdx++) { if (VirtAddVarTab[VarIdx] != VirtAddress) /* Check each variable except the one passed as parameter */ { /* Read the other last variable updates */ ReadStatus = EE_ReadVariable(VirtAddVarTab[VarIdx], &DataVar); /* In case variable corresponding to the virtual address was found */ if (ReadStatus != 0x1) { /* Transfer the variable to the new active page */ EepromStatus = EE_VerifyPageFullWriteVariable(VirtAddVarTab[VarIdx], DataVar); /* If program operation was failed, a Flash error code is returned */ if (EepromStatus != FLASH_COMPLETE) { //FLASH_Lock(); return EepromStatus; } } } } /* Erase the old Page: Set old Page status to ERASED status */ FlashStatus = eraseHelper(OldPageAddress); /* If erase operation was failed, a Flash error code is returned */ if (FlashStatus != FLASH_COMPLETE) { //FLASH_Lock(); return FlashStatus; } /* Set new Page status to VALID_PAGE status */ FlashStatus = FLASH_ProgramHalfWord(NewPageAddress, VALID_PAGE); /* If program operation was failed, a Flash error code is returned */ if (FlashStatus != FLASH_COMPLETE) { //FLASH_Lock(); return FlashStatus; } // FIX from https://my.st.com/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/Flat.aspx?RootFolder=%2Fpublic%2FSTe2ecommunities%2Fmcu%2FLists%2Fcortex_mx_stm32%2FEEPROM%20emulation%20in%20STM32F4x%20family&FolderCTID=0x01200200770978C69A1141439FE559EB459D7580009C4E14902C3CDE46A77F0FFD06506F5B¤tviews=272 // /* Flush the caches by setting the DCRST and ICRST bits in the FLASH_CR register. Note: The I/D cache should be flushed only when it is disabled (I/DCEN = 0).*/ // FLASH->ACR &= ~(FLASH_ACR_ICEN |FLASH_ACR_DCEN); // FLASH->ACR = (FLASH_ACR_ICRST |FLASH_ACR_DCRST); // /* Now restore ( Enable I/D caches, clear the DCRST and ICRST bits */ // FLASH->ACR = (FLASH_ACR_ICEN |FLASH_ACR_DCEN); // FLASH->ACR = ~(FLASH_ACR_ICRST |FLASH_ACR_DCRST); //FLASH_Lock(); /* Return last operation flash status */ return FlashStatus; }
/** * @brief Transfers last updated variables data from the full Page to * an empty one. * @param VirtAddress: 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 * - PAGE_FULL: if valid page is full * - NO_VALID_PAGE: if no valid page was found * - Flash error code: on write Flash error */ static uint16_t EE_PageTransfer(uint16_t VirtAddress, uint16_t Data) { HAL_StatusTypeDef FlashStatus = HAL_OK; uint32_t NewPageAddress = EEPROM_START_ADDRESS; uint16_t OldPageId=0; uint16_t ValidPage = PAGE0, VarIdx = 0; uint16_t EepromStatus = 0, ReadStatus = 0; uint32_t SectorError = 0; FLASH_EraseInitTypeDef pEraseInit; /* Get active Page for read operation */ ValidPage = EE_FindValidPage(READ_FROM_VALID_PAGE); if (ValidPage == PAGE1) /* Page1 valid */ { /* New page address where variable will be moved to */ NewPageAddress = PAGE0_BASE_ADDRESS; /* Old page ID where variable will be taken from */ OldPageId = PAGE1_ID; } else if (ValidPage == PAGE0) /* Page0 valid */ { /* New page address where variable will be moved to */ NewPageAddress = PAGE1_BASE_ADDRESS; /* Old page ID where variable will be taken from */ OldPageId = PAGE0_ID; } else { return NO_VALID_PAGE; /* No valid Page */ } /* Set the new Page status to RECEIVE_DATA status */ FlashStatus = HAL_FLASH_Program(TYPEPROGRAM_HALFWORD, NewPageAddress, RECEIVE_DATA); /* If program operation was failed, a Flash error code is returned */ if (FlashStatus != HAL_OK) { return FlashStatus; } /* Write the variable passed as parameter in the new active page */ EepromStatus = EE_VerifyPageFullWriteVariable(VirtAddress, Data); /* If program operation was failed, a Flash error code is returned */ if (EepromStatus != HAL_OK) { return EepromStatus; } /* Transfer process: transfer variables from old to the new active page */ for (VarIdx = 0; VarIdx < NB_OF_VAR; VarIdx++) { if (VirtAddVarTab[VarIdx] != VirtAddress) /* Check each variable except the one passed as parameter */ { /* Read the other last variable updates */ ReadStatus = EE_ReadVariable(VirtAddVarTab[VarIdx], &DataVar); /* In case variable corresponding to the virtual address was found */ if (ReadStatus != 0x1) { /* Transfer the variable to the new active page */ EepromStatus = EE_VerifyPageFullWriteVariable(VirtAddVarTab[VarIdx], DataVar); /* If program operation was failed, a Flash error code is returned */ if (EepromStatus != HAL_OK) { return EepromStatus; } } } } pEraseInit.TypeErase = TYPEERASE_SECTORS; pEraseInit.Sector = OldPageId; pEraseInit.NbSectors = 1; pEraseInit.VoltageRange = VOLTAGE_RANGE; /* Erase the old Page: Set old Page status to ERASED status */ FlashStatus = HAL_FLASHEx_Erase(&pEraseInit, &SectorError); /* If erase operation was failed, a Flash error code is returned */ if (FlashStatus != HAL_OK) { return FlashStatus; } /* Set new Page status to VALID_PAGE status */ FlashStatus = HAL_FLASH_Program(TYPEPROGRAM_HALFWORD, NewPageAddress, VALID_PAGE); /* If program operation was failed, a Flash error code is returned */ if (FlashStatus != HAL_OK) { return FlashStatus; } /* Return last operation flash status */ return FlashStatus; }
/** * @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); }
/** * @brief Transfers last updated variables data from the full Page to * an empty one. * @param VirtAddress: 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 * - PAGE_FULL: if valid page is full * - NO_VALID_PAGE: if no valid page was found * - Flash error code: on write Flash error */ static uint16_t EE_PageTransfer(uint16_t VirtAddress, uint16_t Data) { HAL_StatusTypeDef flashstatus = HAL_OK; uint32_t newpageaddress = EEPROM_START_ADDRESS; uint32_t oldpageid = 0; uint16_t validpage = PAGE0, varidx = 0; uint16_t eepromstatus = 0, readstatus = 0; uint32_t page_error = 0; FLASH_EraseInitTypeDef s_eraseinit; /* Get active Page for read operation */ validpage = EE_FindValidPage(READ_FROM_VALID_PAGE); if (validpage == PAGE1) /* Page1 valid */ { /* New page address where variable will be moved to */ newpageaddress = PAGE0_BASE_ADDRESS; /* Old page ID where variable will be taken from */ oldpageid = PAGE1_ID; } else if (validpage == PAGE0) /* Page0 valid */ { /* New page address where variable will be moved to */ newpageaddress = PAGE1_BASE_ADDRESS; /* Old page ID where variable will be taken from */ oldpageid = PAGE0_ID; } else { return NO_VALID_PAGE; /* No valid Page */ } /* Set the new Page status to RECEIVE_DATA status */ flashstatus = HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, newpageaddress, RECEIVE_DATA); /* If program operation was failed, a Flash error code is returned */ if (flashstatus != HAL_OK) { return flashstatus; } /* Write the variable passed as parameter in the new active page */ eepromstatus = EE_VerifyPageFullWriteVariable(VirtAddress, Data); /* If program operation was failed, a Flash error code is returned */ if (eepromstatus != HAL_OK) { return eepromstatus; } /* Transfer process: transfer variables from old to the new active page */ for (varidx = 0; varidx < NB_OF_VAR; varidx++) { if (VirtAddVarTab[varidx] != VirtAddress) /* Check each variable except the one passed as parameter */ { /* Read the other last variable updates */ readstatus = EE_ReadVariable(VirtAddVarTab[varidx], &DataVar); /* In case variable corresponding to the virtual address was found */ if (readstatus != 0x1) { /* Transfer the variable to the new active page */ eepromstatus = EE_VerifyPageFullWriteVariable(VirtAddVarTab[varidx], DataVar); /* If program operation was failed, a Flash error code is returned */ if (eepromstatus != HAL_OK) { return eepromstatus; } } } } s_eraseinit.TypeErase = FLASH_TYPEERASE_PAGES; s_eraseinit.PageAddress = oldpageid; s_eraseinit.NbPages = 1; /* Erase the old Page: Set old Page status to ERASED status */ flashstatus = HAL_FLASHEx_Erase(&s_eraseinit, &page_error); /* If erase operation was failed, a Flash error code is returned */ if (flashstatus != HAL_OK) { return flashstatus; } /* Set new Page status to VALID_PAGE status */ flashstatus = HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, newpageaddress, VALID_PAGE); /* If program operation was failed, a Flash error code is returned */ if (flashstatus != HAL_OK) { return flashstatus; } /* Return last operation flash status */ return flashstatus; }