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_Emulation/src/eeprom.c 00004 * @author MCD Application Team 00005 * @version V1.6.0 00006 * @date 27-May-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, needed in Mbed online compiler to avoid conflict with linker (N.S.) */ 00051 const uint8_t Eeprom_area0[PAGE_SIZE] __attribute__((at(PAGE0_BASE_ADDRESS),used))={ [0 ... (PAGE_SIZE-1)] = 0xFF }; 00052 const uint8_t Eeprom_area1[PAGE_SIZE] __attribute__((at(PAGE1_BASE_ADDRESS),used))={ [0 ... (PAGE_SIZE-1)] = 0xFF }; 00053 00054 00055 /* Global variable used to store variable value in read sequence */ 00056 uint16_t DataVar = 0; 00057 00058 /* Virtual address defined by the user: 0xFFFF value is prohibited */ 00059 extern uint16_t VirtAddVarTab[NB_OF_VAR]; 00060 00061 /* Private function prototypes -----------------------------------------------*/ 00062 /* Private functions ---------------------------------------------------------*/ 00063 static HAL_StatusTypeDef EE_Format(void); 00064 static uint16_t EE_FindValidPage(uint8_t Operation); 00065 static uint16_t EE_VerifyPageFullWriteVariable(uint16_t VirtAddress, uint16_t Data); 00066 static uint16_t EE_PageTransfer(uint16_t VirtAddress, uint16_t Data); 00067 static uint16_t EE_VerifyPageFullyErased(uint32_t Address); 00068 00069 /** 00070 * @brief Restore the pages to a known good state in case of page's status 00071 * corruption after a power loss. 00072 * @param None. 00073 * @retval - Flash error code: on write Flash error 00074 * - FLASH_COMPLETE: on success 00075 */ 00076 uint16_t EE_Init(void) 00077 { 00078 uint16_t pagestatus0 = 6, pagestatus1 = 6; 00079 uint16_t varidx = 0; 00080 uint16_t eepromstatus = 0, readstatus = 0; 00081 int16_t x = -1; 00082 HAL_StatusTypeDef flashstatus; 00083 uint32_t page_error = 0; 00084 FLASH_EraseInitTypeDef s_eraseinit; 00085 00086 00087 /* Get Page0 status */ 00088 pagestatus0 = (*(__IO uint16_t*)PAGE0_BASE_ADDRESS); 00089 /* Get Page1 status */ 00090 pagestatus1 = (*(__IO uint16_t*)PAGE1_BASE_ADDRESS); 00091 00092 /* Fill EraseInit structure*/ 00093 s_eraseinit.TypeErase = FLASH_TYPEERASE_PAGES; 00094 s_eraseinit.PageAddress = PAGE0_BASE_ADDRESS; 00095 s_eraseinit.NbPages = PAGE_NB_PVP; 00096 00097 /* Check for invalid header states and repair if necessary */ 00098 switch (pagestatus0) 00099 { 00100 case ERASED: 00101 if (pagestatus1 == VALID_PAGE) /* Page0 erased, Page1 valid */ 00102 { 00103 /* Erase Page0 */ 00104 if(!EE_VerifyPageFullyErased(PAGE0_BASE_ADDRESS)) 00105 { 00106 flashstatus = HAL_FLASHEx_Erase(&s_eraseinit, &page_error); 00107 /* If erase operation was failed, a Flash error code is returned */ 00108 if (flashstatus != HAL_OK) 00109 { 00110 return flashstatus; 00111 } 00112 } 00113 } 00114 else if (pagestatus1 == RECEIVE_DATA) /* Page0 erased, Page1 receive */ 00115 { 00116 /* Erase Page0 */ 00117 if(!EE_VerifyPageFullyErased(PAGE0_BASE_ADDRESS)) 00118 { 00119 flashstatus = HAL_FLASHEx_Erase(&s_eraseinit, &page_error); 00120 /* If erase operation was failed, a Flash error code is returned */ 00121 if (flashstatus != HAL_OK) 00122 { 00123 return flashstatus; 00124 } 00125 } 00126 /* Mark Page1 as valid */ 00127 flashstatus = HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, PAGE1_BASE_ADDRESS, VALID_PAGE); 00128 /* If program operation was failed, a Flash error code is returned */ 00129 if (flashstatus != HAL_OK) 00130 { 00131 return flashstatus; 00132 } 00133 } 00134 else /* First EEPROM access (Page0&1 are erased) or invalid state -> format EEPROM */ 00135 { 00136 /* Erase both Page0 and Page1 and set Page0 as valid page */ 00137 flashstatus = EE_Format(); 00138 /* If erase/program operation was failed, a Flash error code is returned */ 00139 if (flashstatus != HAL_OK) 00140 { 00141 return flashstatus; 00142 } 00143 } 00144 break; 00145 00146 case RECEIVE_DATA: 00147 if (pagestatus1 == VALID_PAGE) /* Page0 receive, Page1 valid */ 00148 { 00149 /* Transfer data from Page1 to Page0 */ 00150 for (varidx = 0; varidx < NB_OF_VAR; varidx++) 00151 { 00152 if (( *(__IO uint16_t*)(PAGE0_BASE_ADDRESS + 6)) == VirtAddVarTab[varidx]) 00153 { 00154 x = varidx; 00155 } 00156 if (varidx != x) 00157 { 00158 /* Read the last variables' updates */ 00159 readstatus = EE_ReadVariable(VirtAddVarTab[varidx], &DataVar); 00160 /* In case variable corresponding to the virtual address was found */ 00161 if (readstatus != 0x1) 00162 { 00163 /* Transfer the variable to the Page0 */ 00164 eepromstatus = EE_VerifyPageFullWriteVariable(VirtAddVarTab[varidx], DataVar); 00165 /* If program operation was failed, a Flash error code is returned */ 00166 if (eepromstatus != HAL_OK) 00167 { 00168 return eepromstatus; 00169 } 00170 } 00171 } 00172 } 00173 /* Mark Page0 as valid */ 00174 flashstatus = HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, PAGE0_BASE_ADDRESS, VALID_PAGE); 00175 /* If program operation was failed, a Flash error code is returned */ 00176 if (flashstatus != HAL_OK) 00177 { 00178 return flashstatus; 00179 } 00180 s_eraseinit.TypeErase = FLASH_TYPEERASE_PAGES; 00181 s_eraseinit.PageAddress = PAGE1_BASE_ADDRESS; 00182 s_eraseinit.NbPages = PAGE_NB_PVP; 00183 /* Erase Page1 */ 00184 if(!EE_VerifyPageFullyErased(PAGE1_BASE_ADDRESS)) 00185 { 00186 flashstatus = HAL_FLASHEx_Erase(&s_eraseinit, &page_error); 00187 /* If erase operation was failed, a Flash error code is returned */ 00188 if (flashstatus != HAL_OK) 00189 { 00190 return flashstatus; 00191 } 00192 } 00193 } 00194 else if (pagestatus1 == ERASED) /* Page0 receive, Page1 erased */ 00195 { 00196 s_eraseinit.TypeErase = FLASH_TYPEERASE_PAGES; 00197 s_eraseinit.PageAddress = PAGE1_BASE_ADDRESS; 00198 s_eraseinit.NbPages = PAGE_NB_PVP; 00199 /* Erase Page1 */ 00200 if(!EE_VerifyPageFullyErased(PAGE1_BASE_ADDRESS)) 00201 { 00202 flashstatus = HAL_FLASHEx_Erase(&s_eraseinit, &page_error); 00203 /* If erase operation was failed, a Flash error code is returned */ 00204 if (flashstatus != HAL_OK) 00205 { 00206 return flashstatus; 00207 } 00208 } 00209 /* Mark Page0 as valid */ 00210 flashstatus = HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, PAGE0_BASE_ADDRESS, VALID_PAGE); 00211 /* If program operation was failed, a Flash error code is returned */ 00212 if (flashstatus != HAL_OK) 00213 { 00214 return flashstatus; 00215 } 00216 } 00217 else /* Invalid state -> format eeprom */ 00218 { 00219 /* Erase both Page0 and Page1 and set Page0 as valid page */ 00220 flashstatus = EE_Format(); 00221 /* If erase/program operation was failed, a Flash error code is returned */ 00222 if (flashstatus != HAL_OK) 00223 { 00224 return flashstatus; 00225 } 00226 } 00227 break; 00228 00229 case VALID_PAGE: 00230 if (pagestatus1 == VALID_PAGE) /* Invalid state -> format eeprom */ 00231 { 00232 /* Erase both Page0 and Page1 and set Page0 as valid page */ 00233 flashstatus = EE_Format(); 00234 /* If erase/program operation was failed, a Flash error code is returned */ 00235 if (flashstatus != HAL_OK) 00236 { 00237 return flashstatus; 00238 } 00239 } 00240 else if (pagestatus1 == ERASED) /* Page0 valid, Page1 erased */ 00241 { 00242 s_eraseinit.TypeErase = FLASH_TYPEERASE_PAGES; 00243 s_eraseinit.PageAddress = PAGE1_BASE_ADDRESS; 00244 s_eraseinit.NbPages = PAGE_NB_PVP; 00245 /* Erase Page1 */ 00246 if(!EE_VerifyPageFullyErased(PAGE1_BASE_ADDRESS)) 00247 { 00248 flashstatus = HAL_FLASHEx_Erase(&s_eraseinit, &page_error); 00249 /* If erase operation was failed, a Flash error code is returned */ 00250 if (flashstatus != HAL_OK) 00251 { 00252 return flashstatus; 00253 } 00254 } 00255 } 00256 else /* Page0 valid, Page1 receive */ 00257 { 00258 /* Transfer data from Page0 to Page1 */ 00259 for (varidx = 0; varidx < NB_OF_VAR; varidx++) 00260 { 00261 if ((*(__IO uint16_t*)(PAGE1_BASE_ADDRESS + 6)) == VirtAddVarTab[varidx]) 00262 { 00263 x = varidx; 00264 } 00265 if (varidx != x) 00266 { 00267 /* Read the last variables' updates */ 00268 readstatus = EE_ReadVariable(VirtAddVarTab[varidx], &DataVar); 00269 /* In case variable corresponding to the virtual address was found */ 00270 if (readstatus != 0x1) 00271 { 00272 /* Transfer the variable to the Page1 */ 00273 eepromstatus = EE_VerifyPageFullWriteVariable(VirtAddVarTab[varidx], DataVar); 00274 /* If program operation was failed, a Flash error code is returned */ 00275 if (eepromstatus != HAL_OK) 00276 { 00277 return eepromstatus; 00278 } 00279 } 00280 } 00281 } 00282 /* Mark Page1 as valid */ 00283 flashstatus = HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, PAGE1_BASE_ADDRESS, VALID_PAGE); 00284 /* If program operation was failed, a Flash error code is returned */ 00285 if (flashstatus != HAL_OK) 00286 { 00287 return flashstatus; 00288 } 00289 s_eraseinit.TypeErase = FLASH_TYPEERASE_PAGES; 00290 s_eraseinit.PageAddress = PAGE0_BASE_ADDRESS; 00291 s_eraseinit.NbPages = PAGE_NB_PVP; 00292 /* Erase Page0 */ 00293 if(!EE_VerifyPageFullyErased(PAGE0_BASE_ADDRESS)) 00294 { 00295 flashstatus = HAL_FLASHEx_Erase(&s_eraseinit, &page_error); 00296 /* If erase operation was failed, a Flash error code is returned */ 00297 if (flashstatus != HAL_OK) 00298 { 00299 return flashstatus; 00300 } 00301 } 00302 } 00303 break; 00304 00305 default: /* Any other state -> format eeprom */ 00306 /* Erase both Page0 and Page1 and set Page0 as valid page */ 00307 flashstatus = EE_Format(); 00308 /* If erase/program operation was failed, a Flash error code is returned */ 00309 if (flashstatus != HAL_OK) 00310 { 00311 return flashstatus; 00312 } 00313 break; 00314 } 00315 00316 return HAL_OK; 00317 } 00318 00319 /** 00320 * @brief Verify if specified page is fully erased. 00321 * @param Address: page address 00322 * This parameter can be one of the following values: 00323 * @arg PAGE0_BASE_ADDRESS: Page0 base address 00324 * @arg PAGE1_BASE_ADDRESS: Page1 base address 00325 * @retval page fully erased status: 00326 * - 0: if Page not erased 00327 * - 1: if Page erased 00328 */ 00329 uint16_t EE_VerifyPageFullyErased(uint32_t Address) 00330 { 00331 uint32_t readstatus = 1; 00332 uint16_t addressvalue = 0x5555; 00333 uint32_t end_address; 00334 00335 if (PAGE0_BASE_ADDRESS==Address) 00336 { 00337 end_address = PAGE0_END_ADDRESS; 00338 } 00339 else 00340 { 00341 end_address = PAGE1_END_ADDRESS; 00342 }; 00343 00344 00345 /* Check each active page address starting from end */ 00346 while (Address <= end_address) 00347 { 00348 /* Get the current location content to be compared with virtual address */ 00349 addressvalue = (*(__IO uint16_t*)Address); 00350 00351 /* Compare the read address with the virtual address */ 00352 if (addressvalue != ERASED) 00353 { 00354 00355 /* In case variable value is read, reset readstatus flag */ 00356 readstatus = 0; 00357 00358 break; 00359 } 00360 /* Next address location */ 00361 Address = Address + 4; 00362 } 00363 00364 /* Return readstatus value: (0: Page not erased, 1: Page erased) */ 00365 return readstatus; 00366 } 00367 00368 /** 00369 * @brief Returns the last stored variable data, if found, which correspond to 00370 * the passed virtual address 00371 * @param VirtAddress: Variable virtual address 00372 * @param Data: Global variable contains the read variable value 00373 * @retval Success or error status: 00374 * - 0: if variable was found 00375 * - 1: if the variable was not found 00376 * - NO_VALID_PAGE: if no valid page was found. 00377 */ 00378 uint16_t EE_ReadVariable(uint16_t VirtAddress, uint16_t* Data) 00379 { 00380 uint16_t validpage = PAGE0; 00381 uint16_t addressvalue = 0x5555, readstatus = 1; 00382 uint32_t address = EEPROM_START_ADDRESS, PageStartAddress = EEPROM_START_ADDRESS; 00383 00384 /* Get active Page for read operation */ 00385 validpage = EE_FindValidPage(READ_FROM_VALID_PAGE); 00386 00387 /* Check if there is no valid page */ 00388 if (validpage == NO_VALID_PAGE) 00389 { 00390 return NO_VALID_PAGE; 00391 } 00392 00393 /* Get the valid Page start Address */ 00394 PageStartAddress = (uint32_t)(EEPROM_START_ADDRESS + (uint32_t)(validpage * PAGE_SIZE)); 00395 00396 /* Get the valid Page end Address */ 00397 address = (uint32_t)((EEPROM_START_ADDRESS - 2) + (uint32_t)((1 + validpage) * PAGE_SIZE)); 00398 00399 /* Check each active page address starting from end */ 00400 while (address > (PageStartAddress + 2)) 00401 { 00402 /* Get the current location content to be compared with virtual address */ 00403 addressvalue = (*(__IO uint16_t*)address); 00404 00405 /* Compare the read address with the virtual address */ 00406 if (addressvalue == VirtAddress) 00407 { 00408 /* Get content of Address-2 which is variable value */ 00409 *Data = (*(__IO uint16_t*)(address - 2)); 00410 00411 /* In case variable value is read, reset readstatus flag */ 00412 readstatus = 0; 00413 00414 break; 00415 } 00416 else 00417 { 00418 /* Next address location */ 00419 address = address - 4; 00420 } 00421 } 00422 00423 /* Return readstatus value: (0: variable exist, 1: variable doesn't exist) */ 00424 return readstatus; 00425 } 00426 00427 /** 00428 * @brief Writes/upadtes variable data in EEPROM. 00429 * @param VirtAddress: Variable virtual address 00430 * @param Data: 16 bit data to be written 00431 * @retval Success or error status: 00432 * - FLASH_COMPLETE: on success 00433 * - PAGE_FULL: if valid page is full 00434 * - NO_VALID_PAGE: if no valid page was found 00435 * - Flash error code: on write Flash error 00436 */ 00437 uint16_t EE_WriteVariable(uint16_t VirtAddress, uint16_t Data) 00438 { 00439 uint16_t Status = 0; 00440 00441 /* Write the variable virtual address and value in the EEPROM */ 00442 Status = EE_VerifyPageFullWriteVariable(VirtAddress, Data); 00443 00444 /* In case the EEPROM active page is full */ 00445 if (Status == PAGE_FULL) 00446 { 00447 /* Perform Page transfer */ 00448 Status = EE_PageTransfer(VirtAddress, Data); 00449 } 00450 00451 /* Return last operation status */ 00452 return Status; 00453 } 00454 00455 /** 00456 * @brief Erases PAGE and PAGE1 and writes VALID_PAGE header to PAGE 00457 * @param None 00458 * @retval Status of the last operation (Flash write or erase) done during 00459 * EEPROM formating 00460 */ 00461 static HAL_StatusTypeDef EE_Format(void) 00462 { 00463 HAL_StatusTypeDef flashstatus = HAL_OK; 00464 uint32_t page_error = 0; 00465 FLASH_EraseInitTypeDef s_eraseinit; 00466 00467 s_eraseinit.TypeErase = FLASH_TYPEERASE_PAGES; 00468 s_eraseinit.PageAddress = PAGE0_BASE_ADDRESS; 00469 s_eraseinit.NbPages = PAGE_NB_PVP; 00470 /* Erase Page0 */ 00471 if(!EE_VerifyPageFullyErased(PAGE0_BASE_ADDRESS)) 00472 { 00473 flashstatus = HAL_FLASHEx_Erase(&s_eraseinit, &page_error); 00474 /* If erase operation was failed, a Flash error code is returned */ 00475 if (flashstatus != HAL_OK) 00476 { 00477 return flashstatus; 00478 } 00479 } 00480 /* Set Page0 as valid page: Write VALID_PAGE at Page0 base address */ 00481 flashstatus = HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, PAGE0_BASE_ADDRESS, VALID_PAGE); 00482 /* If program operation was failed, a Flash error code is returned */ 00483 if (flashstatus != HAL_OK) 00484 { 00485 return flashstatus; 00486 } 00487 00488 s_eraseinit.PageAddress = PAGE1_BASE_ADDRESS; 00489 /* Erase Page1 */ 00490 if(!EE_VerifyPageFullyErased(PAGE1_BASE_ADDRESS)) 00491 { 00492 flashstatus = HAL_FLASHEx_Erase(&s_eraseinit, &page_error); 00493 /* If erase operation was failed, a Flash error code is returned */ 00494 if (flashstatus != HAL_OK) 00495 { 00496 return flashstatus; 00497 } 00498 } 00499 00500 return HAL_OK; 00501 } 00502 00503 /** 00504 * @brief Find valid Page for write or read operation 00505 * @param Operation: operation to achieve on the valid page. 00506 * This parameter can be one of the following values: 00507 * @arg READ_FROM_VALID_PAGE: read operation from valid page 00508 * @arg WRITE_IN_VALID_PAGE: write operation from valid page 00509 * @retval Valid page number (PAGE or PAGE1) or NO_VALID_PAGE in case 00510 * of no valid page was found 00511 */ 00512 static uint16_t EE_FindValidPage(uint8_t Operation) 00513 { 00514 uint16_t pagestatus0 = 6, pagestatus1 = 6; 00515 00516 /* Get Page0 actual status */ 00517 pagestatus0 = (*(__IO uint16_t*)PAGE0_BASE_ADDRESS); 00518 00519 /* Get Page1 actual status */ 00520 pagestatus1 = (*(__IO uint16_t*)PAGE1_BASE_ADDRESS); 00521 00522 /* Write or read operation */ 00523 switch (Operation) 00524 { 00525 case WRITE_IN_VALID_PAGE: /* ---- Write operation ---- */ 00526 if (pagestatus1 == VALID_PAGE) 00527 { 00528 /* Page0 receiving data */ 00529 if (pagestatus0 == RECEIVE_DATA) 00530 { 00531 return PAGE0; /* Page0 valid */ 00532 } 00533 else 00534 { 00535 return PAGE1; /* Page1 valid */ 00536 } 00537 } 00538 else if (pagestatus0 == VALID_PAGE) 00539 { 00540 /* Page1 receiving data */ 00541 if (pagestatus1 == RECEIVE_DATA) 00542 { 00543 return PAGE1; /* Page1 valid */ 00544 } 00545 else 00546 { 00547 return PAGE0; /* Page0 valid */ 00548 } 00549 } 00550 else 00551 { 00552 return NO_VALID_PAGE; /* No valid Page */ 00553 } 00554 00555 case READ_FROM_VALID_PAGE: /* ---- Read operation ---- */ 00556 if (pagestatus0 == VALID_PAGE) 00557 { 00558 return PAGE0; /* Page0 valid */ 00559 } 00560 else if (pagestatus1 == VALID_PAGE) 00561 { 00562 return PAGE1; /* Page1 valid */ 00563 } 00564 else 00565 { 00566 return NO_VALID_PAGE ; /* No valid Page */ 00567 } 00568 00569 default: 00570 return PAGE0; /* Page0 valid */ 00571 } 00572 } 00573 00574 /** 00575 * @brief Verify if active page is full and Writes variable in EEPROM. 00576 * @param VirtAddress: 16 bit virtual address of the variable 00577 * @param Data: 16 bit data to be written as variable value 00578 * @retval Success or error status: 00579 * - FLASH_COMPLETE: on success 00580 * - PAGE_FULL: if valid page is full 00581 * - NO_VALID_PAGE: if no valid page was found 00582 * - Flash error code: on write Flash error 00583 */ 00584 static uint16_t EE_VerifyPageFullWriteVariable(uint16_t VirtAddress, uint16_t Data) 00585 { 00586 HAL_StatusTypeDef flashstatus = HAL_OK; 00587 uint16_t validpage = PAGE0; 00588 uint32_t address = EEPROM_START_ADDRESS, pageendaddress = EEPROM_START_ADDRESS+PAGE_SIZE; 00589 00590 /* Get valid Page for write operation */ 00591 validpage = EE_FindValidPage(WRITE_IN_VALID_PAGE); 00592 00593 /* Check if there is no valid page */ 00594 if (validpage == NO_VALID_PAGE) 00595 { 00596 return NO_VALID_PAGE; 00597 } 00598 00599 /* Get the valid Page start address */ 00600 address = (uint32_t)(EEPROM_START_ADDRESS + (uint32_t)(validpage * PAGE_SIZE)); 00601 00602 /* Get the valid Page end address */ 00603 pageendaddress = (uint32_t)((EEPROM_START_ADDRESS - 1) + (uint32_t)((validpage + 1) * PAGE_SIZE)); 00604 00605 /* Check each active page address starting from begining */ 00606 while (address < pageendaddress) 00607 { 00608 /* Verify if address and address+2 contents are 0xFFFFFFFF */ 00609 if ((*(__IO uint32_t*)address) == 0xFFFFFFFF) 00610 { 00611 /* Set variable data */ 00612 flashstatus = HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, address, Data); 00613 /* If program operation was failed, a Flash error code is returned */ 00614 if (flashstatus != HAL_OK) 00615 { 00616 return flashstatus; 00617 } 00618 /* Set variable virtual address */ 00619 flashstatus = HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, address + 2, VirtAddress); 00620 /* Return program operation status */ 00621 return flashstatus; 00622 } 00623 else 00624 { 00625 /* Next address location */ 00626 address = address + 4; 00627 } 00628 } 00629 00630 /* Return PAGE_FULL in case the valid page is full */ 00631 return PAGE_FULL; 00632 } 00633 00634 /** 00635 * @brief Transfers last updated variables data from the full Page to 00636 * an empty one. 00637 * @param VirtAddress: 16 bit virtual address of the variable 00638 * @param Data: 16 bit data to be written as variable value 00639 * @retval Success or error status: 00640 * - FLASH_COMPLETE: on success 00641 * - PAGE_FULL: if valid page is full 00642 * - NO_VALID_PAGE: if no valid page was found 00643 * - Flash error code: on write Flash error 00644 */ 00645 static uint16_t EE_PageTransfer(uint16_t VirtAddress, uint16_t Data) 00646 { 00647 HAL_StatusTypeDef flashstatus = HAL_OK; 00648 uint32_t newpageaddress = EEPROM_START_ADDRESS; 00649 uint32_t oldpageid = 0; 00650 uint16_t validpage = PAGE0, varidx = 0; 00651 uint16_t eepromstatus = 0, readstatus = 0; 00652 uint32_t page_error = 0; 00653 FLASH_EraseInitTypeDef s_eraseinit; 00654 00655 /* Get active Page for read operation */ 00656 validpage = EE_FindValidPage(READ_FROM_VALID_PAGE); 00657 00658 if (validpage == PAGE1) /* Page1 valid */ 00659 { 00660 /* New page address where variable will be moved to */ 00661 newpageaddress = PAGE0_BASE_ADDRESS; 00662 00663 /* Old page ID where variable will be taken from */ 00664 oldpageid = PAGE1_BASE_ADDRESS; 00665 } 00666 else if (validpage == PAGE0) /* Page0 valid */ 00667 { 00668 /* New page address where variable will be moved to */ 00669 newpageaddress = PAGE1_BASE_ADDRESS; 00670 00671 /* Old page ID where variable will be taken from */ 00672 oldpageid = PAGE0_BASE_ADDRESS; 00673 } 00674 else 00675 { 00676 return NO_VALID_PAGE; /* No valid Page */ 00677 } 00678 00679 /* Set the new Page status to RECEIVE_DATA status */ 00680 flashstatus = HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, newpageaddress, RECEIVE_DATA); 00681 /* If program operation was failed, a Flash error code is returned */ 00682 if (flashstatus != HAL_OK) 00683 { 00684 return flashstatus; 00685 } 00686 00687 /* Write the variable passed as parameter in the new active page */ 00688 eepromstatus = EE_VerifyPageFullWriteVariable(VirtAddress, Data); 00689 /* If program operation was failed, a Flash error code is returned */ 00690 if (eepromstatus != HAL_OK) 00691 { 00692 return eepromstatus; 00693 } 00694 00695 /* Transfer process: transfer variables from old to the new active page */ 00696 for (varidx = 0; varidx < NB_OF_VAR; varidx++) 00697 { 00698 if (VirtAddVarTab[varidx] != VirtAddress) /* Check each variable except the one passed as parameter */ 00699 { 00700 /* Read the other last variable updates */ 00701 readstatus = EE_ReadVariable(VirtAddVarTab[varidx], &DataVar); 00702 /* In case variable corresponding to the virtual address was found */ 00703 if (readstatus != 0x1) 00704 { 00705 /* Transfer the variable to the new active page */ 00706 eepromstatus = EE_VerifyPageFullWriteVariable(VirtAddVarTab[varidx], DataVar); 00707 /* If program operation was failed, a Flash error code is returned */ 00708 if (eepromstatus != HAL_OK) 00709 { 00710 return eepromstatus; 00711 } 00712 } 00713 } 00714 } 00715 00716 s_eraseinit.TypeErase = FLASH_TYPEERASE_PAGES; 00717 s_eraseinit.PageAddress = oldpageid; 00718 s_eraseinit.NbPages = PAGE_NB_PVP; 00719 00720 /* Erase the old Page: Set old Page status to ERASED status */ 00721 flashstatus = HAL_FLASHEx_Erase(&s_eraseinit, &page_error); 00722 /* If erase operation was failed, a Flash error code is returned */ 00723 if (flashstatus != HAL_OK) 00724 { 00725 return flashstatus; 00726 } 00727 00728 /* Set new Page status to VALID_PAGE status */ 00729 flashstatus = HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, newpageaddress, VALID_PAGE); 00730 /* If program operation was failed, a Flash error code is returned */ 00731 if (flashstatus != HAL_OK) 00732 { 00733 return flashstatus; 00734 } 00735 00736 00737 00738 /* Return last operation flash status */ 00739 return flashstatus; 00740 } 00741 00742 /** 00743 * @} 00744 */ 00745 00746 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
Generated on Fri Jul 22 2022 14:32:51 by
1.7.2