simple test EEPROM emulation (STM algorithm described in the application notes: AN4061, AN3969, AN2594, AN3390, AN4056) for STM32F091
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