Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
eeprom.cpp
00001 /** 00002 ****************************************************************************** 00003 * @file EEPROM/EEPROM_Emulation/src/eeprom.c 00004 * @author MCD Application Team 00005 * @version V1.0.1 00006 * @date 29-January-2016 00007 * @brief This file provides all the EEPROM emulation firmware functions. 00008 ****************************************************************************** 00009 * @attention 00010 * 00011 * <h2><center>© COPYRIGHT(c) 2016 STMicroelectronics</center></h2> 00012 * 00013 * Redistribution and use in source and binary forms, with or without modification, 00014 * are permitted provided that the following conditions are met: 00015 * 1. Redistributions of source code must retain the above copyright notice, 00016 * this list of conditions and the following disclaimer. 00017 * 2. Redistributions in binary form must reproduce the above copyright notice, 00018 * this list of conditions and the following disclaimer in the documentation 00019 * and/or other materials provided with the distribution. 00020 * 3. Neither the name of STMicroelectronics nor the names of its contributors 00021 * may be used to endorse or promote products derived from this software 00022 * without specific prior written permission. 00023 * 00024 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00025 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00026 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 00027 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 00028 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00029 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 00030 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 00031 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 00032 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 00033 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00034 * 00035 ****************************************************************************** 00036 */ 00037 00038 /** @addtogroup EEPROM_Emulation 00039 * @{ 00040 */ 00041 00042 /* Includes ------------------------------------------------------------------*/ 00043 #include "eeprom.h" 00044 00045 /* Private typedef -----------------------------------------------------------*/ 00046 /* Private define ------------------------------------------------------------*/ 00047 /* Private macro -------------------------------------------------------------*/ 00048 /* Private variables ---------------------------------------------------------*/ 00049 00050 /* Dummy variables to protect eeprom pages if code size is bigger than 32kb (F401) 00051 needed in Mbed online compiler to avoid conflict with linker (N.S.) */ 00052 const uint8_t Eeprom_area0[PAGE_SIZE] __attribute__((at(PAGE0_BASE_ADDRESS),used))={ [0 ... (PAGE_SIZE-1)] = 0xFF }; 00053 const uint8_t Eeprom_area1[PAGE_SIZE] __attribute__((at(PAGE1_BASE_ADDRESS),used))={ [0 ... (PAGE_SIZE-1)] = 0xFF }; 00054 00055 00056 /* Global variable used to store variable value in read sequence */ 00057 uint16_t DataVar = 0; 00058 00059 /* Virtual address defined by the user: 0xFFFF value is prohibited */ 00060 extern uint16_t VirtAddVarTab[NB_OF_VAR]; 00061 00062 /* Private function prototypes -----------------------------------------------*/ 00063 /* Private functions ---------------------------------------------------------*/ 00064 static HAL_StatusTypeDef EE_Format(void); 00065 static uint16_t EE_FindValidPage(uint8_t Operation); 00066 static uint16_t EE_VerifyPageFullWriteVariable(uint16_t VirtAddress, uint16_t Data); 00067 static uint16_t EE_PageTransfer(uint16_t VirtAddress, uint16_t Data); 00068 static uint16_t EE_VerifyPageFullyErased(uint32_t Address); 00069 00070 /** 00071 * @brief Restore the pages to a known good state in case of page's status 00072 * corruption after a power loss. 00073 * @param None. 00074 * @retval - Flash error code: on write Flash error 00075 * - FLASH_COMPLETE: on success 00076 */ 00077 uint16_t EE_Init(void) 00078 { 00079 uint16_t PageStatus0 = 6, PageStatus1 = 6; 00080 uint16_t VarIdx = 0; 00081 uint16_t EepromStatus = 0, ReadStatus = 0; 00082 int16_t x = -1; 00083 HAL_StatusTypeDef FlashStatus; 00084 uint32_t SectorError = 0; 00085 FLASH_EraseInitTypeDef pEraseInit; 00086 00087 00088 /* Get Page0 status */ 00089 PageStatus0 = (*(__IO uint16_t*)PAGE0_BASE_ADDRESS); 00090 /* Get Page1 status */ 00091 PageStatus1 = (*(__IO uint16_t*)PAGE1_BASE_ADDRESS); 00092 00093 pEraseInit.TypeErase = TYPEERASE_SECTORS; 00094 pEraseInit.Sector = PAGE0_ID; 00095 pEraseInit.NbSectors = 1; 00096 pEraseInit.VoltageRange = VOLTAGE_RANGE; 00097 00098 /* Check for invalid header states and repair if necessary */ 00099 switch (PageStatus0) 00100 { 00101 case ERASED: 00102 if (PageStatus1 == VALID_PAGE) /* Page0 erased, Page1 valid */ 00103 { 00104 /* Erase Page0 */ 00105 if(!EE_VerifyPageFullyErased(PAGE0_BASE_ADDRESS)) 00106 { 00107 FlashStatus = HAL_FLASHEx_Erase(&pEraseInit, &SectorError); 00108 /* If erase operation was failed, a Flash error code is returned */ 00109 if (FlashStatus != HAL_OK) 00110 { 00111 return FlashStatus; 00112 } 00113 } 00114 } 00115 else if (PageStatus1 == RECEIVE_DATA) /* Page0 erased, Page1 receive */ 00116 { 00117 /* Erase Page0 */ 00118 if(!EE_VerifyPageFullyErased(PAGE0_BASE_ADDRESS)) 00119 { 00120 FlashStatus = HAL_FLASHEx_Erase(&pEraseInit, &SectorError); 00121 /* If erase operation was failed, a Flash error code is returned */ 00122 if (FlashStatus != HAL_OK) 00123 { 00124 return FlashStatus; 00125 } 00126 } 00127 /* Mark Page1 as valid */ 00128 FlashStatus = HAL_FLASH_Program(TYPEPROGRAM_HALFWORD, PAGE1_BASE_ADDRESS, VALID_PAGE); 00129 /* If program operation was failed, a Flash error code is returned */ 00130 if (FlashStatus != HAL_OK) 00131 { 00132 return FlashStatus; 00133 } 00134 } 00135 else /* First EEPROM access (Page0&1 are erased) or invalid state -> format EEPROM */ 00136 { 00137 /* Erase both Page0 and Page1 and set Page0 as valid page */ 00138 FlashStatus = EE_Format(); 00139 /* If erase/program operation was failed, a Flash error code is returned */ 00140 if (FlashStatus != HAL_OK) 00141 { 00142 return FlashStatus; 00143 } 00144 } 00145 break; 00146 00147 case RECEIVE_DATA: 00148 if (PageStatus1 == VALID_PAGE) /* Page0 receive, Page1 valid */ 00149 { 00150 /* Transfer data from Page1 to Page0 */ 00151 for (VarIdx = 0; VarIdx < NB_OF_VAR; VarIdx++) 00152 { 00153 if (( *(__IO uint16_t*)(PAGE0_BASE_ADDRESS + 6)) == VirtAddVarTab[VarIdx]) 00154 { 00155 x = VarIdx; 00156 } 00157 if (VarIdx != x) 00158 { 00159 /* Read the last variables' updates */ 00160 ReadStatus = EE_ReadVariable(VirtAddVarTab[VarIdx], &DataVar); 00161 /* In case variable corresponding to the virtual address was found */ 00162 if (ReadStatus != 0x1) 00163 { 00164 /* Transfer the variable to the Page0 */ 00165 EepromStatus = EE_VerifyPageFullWriteVariable(VirtAddVarTab[VarIdx], DataVar); 00166 /* If program operation was failed, a Flash error code is returned */ 00167 if (EepromStatus != HAL_OK) 00168 { 00169 return EepromStatus; 00170 } 00171 } 00172 } 00173 } 00174 /* Mark Page0 as valid */ 00175 FlashStatus = HAL_FLASH_Program(TYPEPROGRAM_HALFWORD, PAGE0_BASE_ADDRESS, VALID_PAGE); 00176 /* If program operation was failed, a Flash error code is returned */ 00177 if (FlashStatus != HAL_OK) 00178 { 00179 return FlashStatus; 00180 } 00181 pEraseInit.Sector = PAGE1_ID; 00182 pEraseInit.NbSectors = 1; 00183 pEraseInit.VoltageRange = VOLTAGE_RANGE; 00184 /* Erase Page1 */ 00185 if(!EE_VerifyPageFullyErased(PAGE1_BASE_ADDRESS)) 00186 { 00187 FlashStatus = HAL_FLASHEx_Erase(&pEraseInit, &SectorError); 00188 /* If erase operation was failed, a Flash error code is returned */ 00189 if (FlashStatus != HAL_OK) 00190 { 00191 return FlashStatus; 00192 } 00193 } 00194 } 00195 else if (PageStatus1 == ERASED) /* Page0 receive, Page1 erased */ 00196 { 00197 pEraseInit.Sector = PAGE1_ID; 00198 pEraseInit.NbSectors = 1; 00199 pEraseInit.VoltageRange = VOLTAGE_RANGE; 00200 /* Erase Page1 */ 00201 if(!EE_VerifyPageFullyErased(PAGE1_BASE_ADDRESS)) 00202 { 00203 FlashStatus = HAL_FLASHEx_Erase(&pEraseInit, &SectorError); 00204 /* If erase operation was failed, a Flash error code is returned */ 00205 if (FlashStatus != HAL_OK) 00206 { 00207 return FlashStatus; 00208 } 00209 } 00210 /* Mark Page0 as valid */ 00211 FlashStatus = HAL_FLASH_Program(TYPEPROGRAM_HALFWORD, PAGE0_BASE_ADDRESS, VALID_PAGE); 00212 /* If program operation was failed, a Flash error code is returned */ 00213 if (FlashStatus != HAL_OK) 00214 { 00215 return FlashStatus; 00216 } 00217 } 00218 else /* Invalid state -> format eeprom */ 00219 { 00220 /* Erase both Page0 and Page1 and set Page0 as valid page */ 00221 FlashStatus = EE_Format(); 00222 /* If erase/program operation was failed, a Flash error code is returned */ 00223 if (FlashStatus != HAL_OK) 00224 { 00225 return FlashStatus; 00226 } 00227 } 00228 break; 00229 00230 case VALID_PAGE: 00231 if (PageStatus1 == VALID_PAGE) /* Invalid state -> format eeprom */ 00232 { 00233 /* Erase both Page0 and Page1 and set Page0 as valid page */ 00234 FlashStatus = EE_Format(); 00235 /* If erase/program operation was failed, a Flash error code is returned */ 00236 if (FlashStatus != HAL_OK) 00237 { 00238 return FlashStatus; 00239 } 00240 } 00241 else if (PageStatus1 == ERASED) /* Page0 valid, Page1 erased */ 00242 { 00243 pEraseInit.Sector = PAGE1_ID; 00244 pEraseInit.NbSectors = 1; 00245 pEraseInit.VoltageRange = VOLTAGE_RANGE; 00246 /* Erase Page1 */ 00247 if(!EE_VerifyPageFullyErased(PAGE1_BASE_ADDRESS)) 00248 { 00249 FlashStatus = HAL_FLASHEx_Erase(&pEraseInit, &SectorError); 00250 /* If erase operation was failed, a Flash error code is returned */ 00251 if (FlashStatus != HAL_OK) 00252 { 00253 return FlashStatus; 00254 } 00255 } 00256 } 00257 else /* Page0 valid, Page1 receive */ 00258 { 00259 /* Transfer data from Page0 to Page1 */ 00260 for (VarIdx = 0; VarIdx < NB_OF_VAR; VarIdx++) 00261 { 00262 if ((*(__IO uint16_t*)(PAGE1_BASE_ADDRESS + 6)) == VirtAddVarTab[VarIdx]) 00263 { 00264 x = VarIdx; 00265 } 00266 if (VarIdx != x) 00267 { 00268 /* Read the last variables' updates */ 00269 ReadStatus = EE_ReadVariable(VirtAddVarTab[VarIdx], &DataVar); 00270 /* In case variable corresponding to the virtual address was found */ 00271 if (ReadStatus != 0x1) 00272 { 00273 /* Transfer the variable to the Page1 */ 00274 EepromStatus = EE_VerifyPageFullWriteVariable(VirtAddVarTab[VarIdx], DataVar); 00275 /* If program operation was failed, a Flash error code is returned */ 00276 if (EepromStatus != HAL_OK) 00277 { 00278 return EepromStatus; 00279 } 00280 } 00281 } 00282 } 00283 /* Mark Page1 as valid */ 00284 FlashStatus = HAL_FLASH_Program(TYPEPROGRAM_HALFWORD, PAGE1_BASE_ADDRESS, VALID_PAGE); 00285 /* If program operation was failed, a Flash error code is returned */ 00286 if (FlashStatus != HAL_OK) 00287 { 00288 return FlashStatus; 00289 } 00290 pEraseInit.Sector = PAGE0_ID; 00291 pEraseInit.NbSectors = 1; 00292 pEraseInit.VoltageRange = VOLTAGE_RANGE; 00293 /* Erase Page0 */ 00294 if(!EE_VerifyPageFullyErased(PAGE0_BASE_ADDRESS)) 00295 { 00296 FlashStatus = HAL_FLASHEx_Erase(&pEraseInit, &SectorError); 00297 /* If erase operation was failed, a Flash error code is returned */ 00298 if (FlashStatus != HAL_OK) 00299 { 00300 return FlashStatus; 00301 } 00302 } 00303 } 00304 break; 00305 00306 default: /* Any other state -> format eeprom */ 00307 /* Erase both Page0 and Page1 and set Page0 as valid page */ 00308 FlashStatus = EE_Format(); 00309 /* If erase/program operation was failed, a Flash error code is returned */ 00310 if (FlashStatus != HAL_OK) 00311 { 00312 return FlashStatus; 00313 } 00314 break; 00315 } 00316 00317 return HAL_OK; 00318 } 00319 00320 /** 00321 * @brief Verify if specified page is fully erased. 00322 * @param Address: page address 00323 * This parameter can be one of the following values: 00324 * @arg PAGE0_BASE_ADDRESS: Page0 base address 00325 * @arg PAGE1_BASE_ADDRESS: Page1 base address 00326 * @retval page fully erased status: 00327 * - 0: if Page not erased 00328 * - 1: if Page erased 00329 */ 00330 uint16_t EE_VerifyPageFullyErased(uint32_t Address) 00331 { 00332 uint32_t readstatus = 1; 00333 uint16_t addressvalue = 0x5555; 00334 uint32_t end_address; 00335 00336 if (PAGE0_BASE_ADDRESS==Address) 00337 { 00338 end_address = PAGE0_END_ADDRESS; 00339 } 00340 else 00341 { 00342 end_address = PAGE1_END_ADDRESS; 00343 }; 00344 00345 00346 /* Check each active page address starting from end */ 00347 while (Address <= end_address) 00348 { 00349 /* Get the current location content to be compared with virtual address */ 00350 addressvalue = (*(__IO uint16_t*)Address); 00351 00352 /* Compare the read address with the virtual address */ 00353 if (addressvalue != ERASED) 00354 { 00355 00356 /* In case variable value is read, reset readstatus flag */ 00357 readstatus = 0; 00358 00359 break; 00360 } 00361 /* Next address location */ 00362 Address = Address + 4; 00363 } 00364 00365 /* Return readstatus value: (0: Page not erased, 1: Page erased) */ 00366 return readstatus; 00367 } 00368 00369 /** 00370 * @brief Returns the last stored variable data, if found, which correspond to 00371 * the passed virtual address 00372 * @param VirtAddress: Variable virtual address 00373 * @param Data: Global variable contains the read variable value 00374 * @retval Success or error status: 00375 * - 0: if variable was found 00376 * - 1: if the variable was not found 00377 * - NO_VALID_PAGE: if no valid page was found. 00378 */ 00379 uint16_t EE_ReadVariable(uint16_t VirtAddress, uint16_t* Data) 00380 { 00381 uint16_t ValidPage = PAGE0; 00382 uint16_t AddressValue = 0x5555, ReadStatus = 1; 00383 uint32_t Address = EEPROM_START_ADDRESS, PageStartAddress = EEPROM_START_ADDRESS; 00384 00385 /* Get active Page for read operation */ 00386 ValidPage = EE_FindValidPage(READ_FROM_VALID_PAGE); 00387 00388 /* Check if there is no valid page */ 00389 if (ValidPage == NO_VALID_PAGE) 00390 { 00391 return NO_VALID_PAGE; 00392 } 00393 00394 /* Get the valid Page start Address */ 00395 PageStartAddress = (uint32_t)(EEPROM_START_ADDRESS + (uint32_t)(ValidPage * PAGE_SIZE)); 00396 00397 /* Get the valid Page end Address */ 00398 Address = (uint32_t)((EEPROM_START_ADDRESS - 2) + (uint32_t)((1 + ValidPage) * PAGE_SIZE)); 00399 00400 /* Check each active page address starting from end */ 00401 while (Address > (PageStartAddress + 2)) 00402 { 00403 /* Get the current location content to be compared with virtual address */ 00404 AddressValue = (*(__IO uint16_t*)Address); 00405 00406 /* Compare the read address with the virtual address */ 00407 if (AddressValue == VirtAddress) 00408 { 00409 /* Get content of Address-2 which is variable value */ 00410 *Data = (*(__IO uint16_t*)(Address - 2)); 00411 00412 /* In case variable value is read, reset ReadStatus flag */ 00413 ReadStatus = 0; 00414 00415 break; 00416 } 00417 else 00418 { 00419 /* Next address location */ 00420 Address = Address - 4; 00421 } 00422 } 00423 00424 /* Return ReadStatus value: (0: variable exist, 1: variable doesn't exist) */ 00425 return ReadStatus; 00426 } 00427 00428 /** 00429 * @brief Writes/upadtes variable data in EEPROM. 00430 * @param VirtAddress: Variable virtual address 00431 * @param Data: 16 bit data to be written 00432 * @retval Success or error status: 00433 * - FLASH_COMPLETE: on success 00434 * - PAGE_FULL: if valid page is full 00435 * - NO_VALID_PAGE: if no valid page was found 00436 * - Flash error code: on write Flash error 00437 */ 00438 uint16_t EE_WriteVariable(uint16_t VirtAddress, uint16_t Data) 00439 { 00440 uint16_t Status = 0; 00441 00442 /* Write the variable virtual address and value in the EEPROM */ 00443 Status = EE_VerifyPageFullWriteVariable(VirtAddress, Data); 00444 00445 /* In case the EEPROM active page is full */ 00446 if (Status == PAGE_FULL) 00447 { 00448 /* Perform Page transfer */ 00449 Status = EE_PageTransfer(VirtAddress, Data); 00450 } 00451 00452 /* Return last operation status */ 00453 return Status; 00454 } 00455 00456 /** 00457 * @brief Erases PAGE and PAGE1 and writes VALID_PAGE header to PAGE 00458 * @param None 00459 * @retval Status of the last operation (Flash write or erase) done during 00460 * EEPROM formating 00461 */ 00462 static HAL_StatusTypeDef EE_Format(void) 00463 { 00464 HAL_StatusTypeDef FlashStatus = HAL_OK; 00465 uint32_t SectorError = 0; 00466 FLASH_EraseInitTypeDef pEraseInit; 00467 00468 pEraseInit.TypeErase = FLASH_TYPEERASE_SECTORS; 00469 pEraseInit.Sector = PAGE0_ID; 00470 pEraseInit.NbSectors = 1; 00471 pEraseInit.VoltageRange = VOLTAGE_RANGE; 00472 /* Erase Page0 */ 00473 if(!EE_VerifyPageFullyErased(PAGE0_BASE_ADDRESS)) 00474 { 00475 FlashStatus = HAL_FLASHEx_Erase(&pEraseInit, &SectorError); 00476 /* If erase operation was failed, a Flash error code is returned */ 00477 if (FlashStatus != HAL_OK) 00478 { 00479 return FlashStatus; 00480 } 00481 } 00482 /* Set Page0 as valid page: Write VALID_PAGE at Page0 base address */ 00483 FlashStatus = HAL_FLASH_Program(TYPEPROGRAM_HALFWORD, PAGE0_BASE_ADDRESS, VALID_PAGE); 00484 /* If program operation was failed, a Flash error code is returned */ 00485 if (FlashStatus != HAL_OK) 00486 { 00487 return FlashStatus; 00488 } 00489 00490 pEraseInit.Sector = PAGE1_ID; 00491 /* Erase Page1 */ 00492 if(!EE_VerifyPageFullyErased(PAGE1_BASE_ADDRESS)) 00493 { 00494 FlashStatus = HAL_FLASHEx_Erase(&pEraseInit, &SectorError); 00495 /* If erase operation was failed, a Flash error code is returned */ 00496 if (FlashStatus != HAL_OK) 00497 { 00498 return FlashStatus; 00499 } 00500 } 00501 00502 return HAL_OK; 00503 } 00504 00505 /** 00506 * @brief Find valid Page for write or read operation 00507 * @param Operation: operation to achieve on the valid page. 00508 * This parameter can be one of the following values: 00509 * @arg READ_FROM_VALID_PAGE: read operation from valid page 00510 * @arg WRITE_IN_VALID_PAGE: write operation from valid page 00511 * @retval Valid page number (PAGE or PAGE1) or NO_VALID_PAGE in case 00512 * of no valid page was found 00513 */ 00514 static uint16_t EE_FindValidPage(uint8_t Operation) 00515 { 00516 uint16_t PageStatus0 = 6, PageStatus1 = 6; 00517 00518 /* Get Page0 actual status */ 00519 PageStatus0 = (*(__IO uint16_t*)PAGE0_BASE_ADDRESS); 00520 00521 /* Get Page1 actual status */ 00522 PageStatus1 = (*(__IO uint16_t*)PAGE1_BASE_ADDRESS); 00523 00524 /* Write or read operation */ 00525 switch (Operation) 00526 { 00527 case WRITE_IN_VALID_PAGE: /* ---- Write operation ---- */ 00528 if (PageStatus1 == VALID_PAGE) 00529 { 00530 /* Page0 receiving data */ 00531 if (PageStatus0 == RECEIVE_DATA) 00532 { 00533 return PAGE0; /* Page0 valid */ 00534 } 00535 else 00536 { 00537 return PAGE1; /* Page1 valid */ 00538 } 00539 } 00540 else if (PageStatus0 == VALID_PAGE) 00541 { 00542 /* Page1 receiving data */ 00543 if (PageStatus1 == RECEIVE_DATA) 00544 { 00545 return PAGE1; /* Page1 valid */ 00546 } 00547 else 00548 { 00549 return PAGE0; /* Page0 valid */ 00550 } 00551 } 00552 else 00553 { 00554 return NO_VALID_PAGE; /* No valid Page */ 00555 } 00556 00557 case READ_FROM_VALID_PAGE: /* ---- Read operation ---- */ 00558 if (PageStatus0 == VALID_PAGE) 00559 { 00560 return PAGE0; /* Page0 valid */ 00561 } 00562 else if (PageStatus1 == VALID_PAGE) 00563 { 00564 return PAGE1; /* Page1 valid */ 00565 } 00566 else 00567 { 00568 return NO_VALID_PAGE ; /* No valid Page */ 00569 } 00570 00571 default: 00572 return PAGE0; /* Page0 valid */ 00573 } 00574 } 00575 00576 /** 00577 * @brief Verify if active page is full and Writes variable in EEPROM. 00578 * @param VirtAddress: 16 bit virtual address of the variable 00579 * @param Data: 16 bit data to be written as variable value 00580 * @retval Success or error status: 00581 * - FLASH_COMPLETE: on success 00582 * - PAGE_FULL: if valid page is full 00583 * - NO_VALID_PAGE: if no valid page was found 00584 * - Flash error code: on write Flash error 00585 */ 00586 static uint16_t EE_VerifyPageFullWriteVariable(uint16_t VirtAddress, uint16_t Data) 00587 { 00588 HAL_StatusTypeDef FlashStatus = HAL_OK; 00589 uint16_t ValidPage = PAGE0; 00590 uint32_t Address = EEPROM_START_ADDRESS, PageEndAddress = EEPROM_START_ADDRESS+PAGE_SIZE; 00591 00592 /* Get valid Page for write operation */ 00593 ValidPage = EE_FindValidPage(WRITE_IN_VALID_PAGE); 00594 00595 /* Check if there is no valid page */ 00596 if (ValidPage == NO_VALID_PAGE) 00597 { 00598 return NO_VALID_PAGE; 00599 } 00600 00601 /* Get the valid Page start Address */ 00602 Address = (uint32_t)(EEPROM_START_ADDRESS + (uint32_t)(ValidPage * PAGE_SIZE)); 00603 00604 /* Get the valid Page end Address */ 00605 PageEndAddress = (uint32_t)((EEPROM_START_ADDRESS - 1) + (uint32_t)((ValidPage + 1) * PAGE_SIZE)); 00606 00607 /* Check each active page address starting from begining */ 00608 while (Address < PageEndAddress) 00609 { 00610 /* Verify if Address and Address+2 contents are 0xFFFFFFFF */ 00611 if ((*(__IO uint32_t*)Address) == 0xFFFFFFFF) 00612 { 00613 /* Set variable data */ 00614 FlashStatus = HAL_FLASH_Program(TYPEPROGRAM_HALFWORD, Address, Data); 00615 /* If program operation was failed, a Flash error code is returned */ 00616 if (FlashStatus != HAL_OK) 00617 { 00618 return FlashStatus; 00619 } 00620 /* Set variable virtual address */ 00621 FlashStatus = HAL_FLASH_Program(TYPEPROGRAM_HALFWORD, Address + 2, VirtAddress); 00622 /* Return program operation status */ 00623 return FlashStatus; 00624 } 00625 else 00626 { 00627 /* Next address location */ 00628 Address = Address + 4; 00629 } 00630 } 00631 00632 /* Return PAGE_FULL in case the valid page is full */ 00633 return PAGE_FULL; 00634 } 00635 00636 /** 00637 * @brief Transfers last updated variables data from the full Page to 00638 * an empty one. 00639 * @param VirtAddress: 16 bit virtual address of the variable 00640 * @param Data: 16 bit data to be written as variable value 00641 * @retval Success or error status: 00642 * - FLASH_COMPLETE: on success 00643 * - PAGE_FULL: if valid page is full 00644 * - NO_VALID_PAGE: if no valid page was found 00645 * - Flash error code: on write Flash error 00646 */ 00647 static uint16_t EE_PageTransfer(uint16_t VirtAddress, uint16_t Data) 00648 { 00649 HAL_StatusTypeDef FlashStatus = HAL_OK; 00650 uint32_t NewPageAddress = EEPROM_START_ADDRESS; 00651 uint16_t OldPageId=0; 00652 uint16_t ValidPage = PAGE0, VarIdx = 0; 00653 uint16_t EepromStatus = 0, ReadStatus = 0; 00654 uint32_t SectorError = 0; 00655 FLASH_EraseInitTypeDef pEraseInit; 00656 00657 /* Get active Page for read operation */ 00658 ValidPage = EE_FindValidPage(READ_FROM_VALID_PAGE); 00659 00660 if (ValidPage == PAGE1) /* Page1 valid */ 00661 { 00662 /* New page address where variable will be moved to */ 00663 NewPageAddress = PAGE0_BASE_ADDRESS; 00664 00665 /* Old page ID where variable will be taken from */ 00666 OldPageId = PAGE1_ID; 00667 } 00668 else if (ValidPage == PAGE0) /* Page0 valid */ 00669 { 00670 /* New page address where variable will be moved to */ 00671 NewPageAddress = PAGE1_BASE_ADDRESS; 00672 00673 /* Old page ID where variable will be taken from */ 00674 OldPageId = PAGE0_ID; 00675 } 00676 else 00677 { 00678 return NO_VALID_PAGE; /* No valid Page */ 00679 } 00680 00681 /* Set the new Page status to RECEIVE_DATA status */ 00682 FlashStatus = HAL_FLASH_Program(TYPEPROGRAM_HALFWORD, NewPageAddress, RECEIVE_DATA); 00683 /* If program operation was failed, a Flash error code is returned */ 00684 if (FlashStatus != HAL_OK) 00685 { 00686 return FlashStatus; 00687 } 00688 00689 /* Write the variable passed as parameter in the new active page */ 00690 EepromStatus = EE_VerifyPageFullWriteVariable(VirtAddress, Data); 00691 /* If program operation was failed, a Flash error code is returned */ 00692 if (EepromStatus != HAL_OK) 00693 { 00694 return EepromStatus; 00695 } 00696 00697 /* Transfer process: transfer variables from old to the new active page */ 00698 for (VarIdx = 0; VarIdx < NB_OF_VAR; VarIdx++) 00699 { 00700 if (VirtAddVarTab[VarIdx] != VirtAddress) /* Check each variable except the one passed as parameter */ 00701 { 00702 /* Read the other last variable updates */ 00703 ReadStatus = EE_ReadVariable(VirtAddVarTab[VarIdx], &DataVar); 00704 /* In case variable corresponding to the virtual address was found */ 00705 if (ReadStatus != 0x1) 00706 { 00707 /* Transfer the variable to the new active page */ 00708 EepromStatus = EE_VerifyPageFullWriteVariable(VirtAddVarTab[VarIdx], DataVar); 00709 /* If program operation was failed, a Flash error code is returned */ 00710 if (EepromStatus != HAL_OK) 00711 { 00712 return EepromStatus; 00713 } 00714 } 00715 } 00716 } 00717 00718 pEraseInit.TypeErase = TYPEERASE_SECTORS; 00719 pEraseInit.Sector = OldPageId; 00720 pEraseInit.NbSectors = 1; 00721 pEraseInit.VoltageRange = VOLTAGE_RANGE; 00722 00723 /* Erase the old Page: Set old Page status to ERASED status */ 00724 FlashStatus = HAL_FLASHEx_Erase(&pEraseInit, &SectorError); 00725 /* If erase operation was failed, a Flash error code is returned */ 00726 if (FlashStatus != HAL_OK) 00727 { 00728 return FlashStatus; 00729 } 00730 00731 /* Set new Page status to VALID_PAGE status */ 00732 FlashStatus = HAL_FLASH_Program(TYPEPROGRAM_HALFWORD, NewPageAddress, VALID_PAGE); 00733 /* If program operation was failed, a Flash error code is returned */ 00734 if (FlashStatus != HAL_OK) 00735 { 00736 return FlashStatus; 00737 } 00738 00739 /* Return last operation flash status */ 00740 return FlashStatus; 00741 } 00742 00743 /** 00744 * @} 00745 */ 00746 00747 /******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
Generated on Wed Jul 13 2022 11:37:02 by
