Subversion Repositories DashDisplay

Rev

Rev 16 | Rev 21 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. /**
  2.   ******************************************************************************
  3.   * @file    EEPROM_Emulation/src/eeprom.c
  4.   * @author  MCD Application Team
  5.   * @version V3.1.0
  6.   * @date    07/27/2009
  7.   * @brief   This file provides all the EEPROM emulation firmware functions.
  8.   ******************************************************************************
  9.   * @copy
  10.   *
  11.   * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
  12.   * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
  13.   * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
  14.   * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
  15.   * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
  16.   * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
  17.   *
  18.   * <h2><center>&copy; COPYRIGHT 2009 STMicroelectronics</center></h2>
  19.   */
  20. /** @addtogroup EEPROM_Emulation
  21.   * @{
  22.   */
  23.  
  24. /* Includes ------------------------------------------------------------------*/
  25. #include "eeprom.h"
  26.  
  27. /* Private typedef -----------------------------------------------------------*/
  28. /* Private define ------------------------------------------------------------*/
  29. /* Private macro -------------------------------------------------------------*/
  30. /* Private variables ---------------------------------------------------------*/
  31.  
  32.  
  33.  FlashPage_t __attribute__((section(".EEPROM_Data"))) FlashPage[2];
  34.  
  35.  static FLASH_EraseInitTypeDef EraseInitStruct;
  36.  static uint32_t PAGEError;
  37.  
  38.  
  39. /* Global variable used to store variable value in read sequence */
  40. uint16_t DataVar = 0;
  41.  
  42. /* Virtual address defined by the user: 0xFFFF value is prohibited */
  43. extern uint16_t VirtAddVarTab[NumbOfVar];
  44.  
  45. /* Private function prototypes -----------------------------------------------*/
  46. /* Private functions ---------------------------------------------------------*/
  47. static FLASH_Status EE_Format(void);
  48. static uint16_t EE_FindValidPage(uint8_t Operation);
  49. static uint16_t EE_VerifyPageFullWriteVariable(uint16_t VirtAddress, uint16_t Data);
  50. static uint16_t EE_PageTransfer(uint16_t VirtAddress, uint16_t Data);
  51.  
  52. /**
  53.   * @brief  Restore the pages to a known good state in case of page's status
  54.   *   corruption after a power loss.
  55.   * @param  None.
  56.   * @retval - Flash error code: on write Flash error
  57.   *         - FLASH_COMPLETE: on success
  58.   */
  59. uint16_t EE_Init(void)
  60. {
  61.   uint16_t PageStatus0 = 6, PageStatus1 = 6;
  62.   uint16_t VarIdx = 0;
  63.   uint16_t EepromStatus = 0, ReadStatus = 0;
  64.   int16_t x = -1;
  65.   uint16_t  FlashStatus;
  66.  
  67.   /* Get Page0 status */
  68.   PageStatus0 = (*(__IO uint16_t*)PAGE0_BASE_ADDRESS);
  69.   /* Get Page1 status */
  70.   PageStatus1 = (*(__IO uint16_t*)PAGE1_BASE_ADDRESS);
  71.  
  72.   /* Check for invalid header states and repair if necessary */
  73.   switch (PageStatus0)
  74.   {
  75.     case ERASED:
  76.       if (PageStatus1 == VALID_PAGE) /* Page0 erased, Page1 valid */
  77.       {
  78.         /* Erase Page0 */
  79.           EraseInitStruct.TypeErase   = FLASH_TYPEERASE_PAGES;
  80.           EraseInitStruct.PageAddress = PAGE0_BASE_ADDRESS;
  81.           EraseInitStruct.NbPages     = 1;
  82.           if (HAL_FLASHEx_Erase(&EraseInitStruct, &PAGEError) != HAL_OK)
  83.           {
  84.                   /* If erase operation was failed, a Flash error code is returned */
  85.               FlashStatus = HAL_FLASH_GetError();
  86.               return FlashStatus;
  87.           }
  88.       }
  89.       else if (PageStatus1 == RECEIVE_DATA) /* Page0 erased, Page1 receive */
  90.       {
  91.         /* Erase Page0 */
  92.           EraseInitStruct.TypeErase   = FLASH_TYPEERASE_PAGES;
  93.           EraseInitStruct.PageAddress = PAGE0_BASE_ADDRESS;
  94.           EraseInitStruct.NbPages     = 1;
  95.           if (HAL_FLASHEx_Erase(&EraseInitStruct, &PAGEError) != HAL_OK)
  96.           {
  97.                   /* If erase operation was failed, a Flash error code is returned */
  98.                  FlashStatus = HAL_FLASH_GetError();
  99.                  return FlashStatus;
  100.           }
  101.           /* Mark Page1 as valid */
  102.  
  103.          HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD,PAGE1_BASE_ADDRESS, VALID_PAGE);
  104.         /* If program operation was failed, a Flash error code is returned */
  105.          FlashStatus = HAL_FLASH_GetError();
  106.          if (FlashStatus != HAL_FLASH_ERROR_NONE)
  107.          {
  108.           return FlashStatus;
  109.         }
  110.       }
  111.       else /* First EEPROM access (Page0&1 are erased) or invalid state -> format EEPROM */
  112.       {
  113.         /* Erase both Page0 and Page1 and set Page0 as valid page */
  114.         FlashStatus = EE_Format();
  115.         /* If erase/program operation was failed, a Flash error code is returned */
  116.         if (FlashStatus != HAL_FLASH_ERROR_NONE)
  117.         {
  118.            return FlashStatus;
  119.         }
  120.       }
  121.       break;
  122.  
  123.     case RECEIVE_DATA:
  124.       if (PageStatus1 == VALID_PAGE) /* Page0 receive, Page1 valid */
  125.       {
  126.         /* Transfer data from Page1 to Page0 */
  127.         for (VarIdx = 0; VarIdx < NumbOfVar; VarIdx++)
  128.         {
  129.           if (( *(__IO uint16_t*)(PAGE0_BASE_ADDRESS + 6)) == VirtAddVarTab[VarIdx])
  130.           {
  131.             x = VarIdx;
  132.           }
  133.           if (VarIdx != x)
  134.           {
  135.             /* Read the last variables' updates */
  136.             ReadStatus = EE_ReadVariable(VirtAddVarTab[VarIdx], &DataVar);
  137.             /* In case variable corresponding to the virtual address was found */
  138.             if (ReadStatus != 0x1)
  139.             {
  140.               /* Transfer the variable to the Page0 */
  141.               EepromStatus = EE_VerifyPageFullWriteVariable(VirtAddVarTab[VarIdx], DataVar);
  142.               /* If program operation was failed, a Flash error code is returned */
  143.               if (EepromStatus != HAL_FLASH_ERROR_NONE)
  144.               {
  145.                 return EepromStatus;
  146.               }
  147.             }
  148.           }
  149.         }
  150.         /* Mark Page0 as valid */
  151.         HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD,PAGE0_BASE_ADDRESS, VALID_PAGE);
  152.         /* If program operation was failed, a Flash error code is returned */
  153.         FlashStatus = HAL_FLASH_GetError();
  154.         if (FlashStatus != HAL_FLASH_ERROR_NONE)
  155.         {
  156.           return FlashStatus;
  157.         }
  158.         /* Erase Page1 */
  159.         FLASH_PageErase(PAGE1_BASE_ADDRESS);
  160.         /* If erase operation was failed, a Flash error code is returned */
  161.         FlashStatus = HAL_FLASH_GetError();
  162.         if (FlashStatus != HAL_FLASH_ERROR_NONE)
  163.             {
  164.           return FlashStatus;
  165.         }
  166.       }
  167.       else if (PageStatus1 == ERASED) /* Page0 receive, Page1 erased */
  168.       {
  169.         /* Erase Page1 */
  170.         FLASH_PageErase(PAGE1_BASE_ADDRESS);
  171.         /* If erase operation was failed, a Flash error code is returned */
  172.         FlashStatus = HAL_FLASH_GetError();
  173.         if (FlashStatus != HAL_FLASH_ERROR_NONE)
  174.         {
  175.           return FlashStatus;
  176.         }
  177.         /* Mark Page0 as valid */
  178.         HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD,PAGE0_BASE_ADDRESS, VALID_PAGE);
  179.  
  180.         /* If program operation was failed, a Flash error code is returned */
  181.         FlashStatus = HAL_FLASH_GetError();
  182.         if (FlashStatus != HAL_FLASH_ERROR_NONE)
  183.         {
  184.           return FlashStatus;
  185.         }
  186.       }
  187.       else /* Invalid state -> format eeprom */
  188.       {
  189.         /* Erase both Page0 and Page1 and set Page0 as valid page */
  190.         FlashStatus = EE_Format();
  191.         /* If erase/program operation was failed, a Flash error code is returned */
  192.         if (FlashStatus != HAL_FLASH_ERROR_NONE)
  193.         {
  194.           return FlashStatus;
  195.         }
  196.       }
  197.       break;
  198.  
  199.     case VALID_PAGE:
  200.       if (PageStatus1 == VALID_PAGE) /* Invalid state -> format eeprom */
  201.       {
  202.         /* Erase both Page0 and Page1 and set Page0 as valid page */
  203.         FlashStatus = EE_Format();
  204.         /* If erase/program operation was failed, a Flash error code is returned */
  205.         if (FlashStatus != HAL_FLASH_ERROR_NONE)
  206.         {
  207.           return FlashStatus;
  208.         }
  209.       }
  210.       else if (PageStatus1 == ERASED) /* Page0 valid, Page1 erased */
  211.       {
  212.         /* Erase Page1 */
  213.         FLASH_PageErase(PAGE1_BASE_ADDRESS);
  214.         FlashStatus = HAL_FLASH_GetError();
  215.         /* If erase operation was failed, a Flash error code is returned */
  216.         if (FlashStatus != HAL_FLASH_ERROR_NONE)
  217.         {
  218.           return FlashStatus;
  219.         }
  220.       }
  221.       else /* Page0 valid, Page1 receive */
  222.       {
  223.         /* Transfer data from Page0 to Page1 */
  224.         for (VarIdx = 0; VarIdx < NumbOfVar; VarIdx++)
  225.         {
  226.           if ((*(__IO uint16_t*)(PAGE1_BASE_ADDRESS + 6)) == VirtAddVarTab[VarIdx])
  227.           {
  228.             x = VarIdx;
  229.           }
  230.           if (VarIdx != x)
  231.           {
  232.             /* Read the last variables' updates */
  233.             ReadStatus = EE_ReadVariable(VirtAddVarTab[VarIdx], &DataVar);
  234.             /* In case variable corresponding to the virtual address was found */
  235.             if (ReadStatus != 0x1)
  236.             {
  237.               /* Transfer the variable to the Page1 */
  238.               EepromStatus = EE_VerifyPageFullWriteVariable(VirtAddVarTab[VarIdx], DataVar);
  239.               /* If program operation was failed, a Flash error code is returned */
  240.               if (EepromStatus != HAL_FLASH_ERROR_NONE)
  241.               {
  242.                 return EepromStatus;
  243.               }
  244.             }
  245.           }
  246.         }
  247.         /* Mark Page1 as valid */
  248.  
  249.         HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD,PAGE1_BASE_ADDRESS, VALID_PAGE);
  250.         /* If program operation was failed, a Flash error code is returned */
  251.         FlashStatus = HAL_FLASH_GetError();
  252.         if (FlashStatus != HAL_FLASH_ERROR_NONE)
  253.         {
  254.           return FlashStatus;
  255.         }
  256.         /* Erase Page0 */
  257.         FLASH_PageErase(PAGE0_BASE_ADDRESS);
  258.         /* If erase operation was failed, a Flash error code is returned */
  259.         FlashStatus = HAL_FLASH_GetError();
  260.         if (FlashStatus != HAL_FLASH_ERROR_NONE)
  261.         {
  262.           return FlashStatus;
  263.         }
  264.       }
  265.       break;
  266.  
  267.     default:  /* Any other state -> format eeprom */
  268.       /* Erase both Page0 and Page1 and set Page0 as valid page */
  269.       FlashStatus = EE_Format();
  270.       /* If erase/program operation was failed, a Flash error code is returned */
  271.       if (FlashStatus != HAL_FLASH_ERROR_NONE)
  272.       {
  273.         return FlashStatus;
  274.       }
  275.       break;
  276.   }
  277.  
  278.   return HAL_FLASH_ERROR_NONE;
  279. }
  280.  
  281. /**
  282.   * @brief  Returns the last stored variable data, if found, which correspond to
  283.   *   the passed virtual address
  284.   * @param  VirtAddress: Variable virtual address
  285.   * @param  Data: Global variable contains the read variable value
  286.   * @retval Success or error status:
  287.   *           - 0: if variable was found
  288.   *           - 1: if the variable was not found
  289.   *           - NO_VALID_PAGE: if no valid page was found.
  290.   */
  291. uint16_t EE_ReadVariable(uint16_t VirtAddress, uint16_t* Data)
  292. {
  293.   uint16_t ValidPage = PAGE0;
  294.   uint16_t AddressValue = 0x5555, ReadStatus = 1;
  295.   uint32_t Address = 0x08010000, PageStartAddress = 0x08010000;
  296.  
  297.   /* Get active Page for read operation */
  298.   ValidPage = EE_FindValidPage(READ_FROM_VALID_PAGE);
  299.  
  300.   /* Check if there is no valid page */
  301.   if (ValidPage == NO_VALID_PAGE)
  302.   {
  303.     return  NO_VALID_PAGE;
  304.   }
  305.  
  306.   /* Get the valid Page start Address */
  307.   PageStartAddress = (uint32_t)(PAGE0_BASE_ADDRESS + (uint32_t)(ValidPage * PAGE_SIZE));
  308.  
  309.   /* Get the valid Page end Address */
  310.   Address = (uint32_t)((PAGE0_BASE_ADDRESS - 2) + (uint32_t)((1 + ValidPage) * PAGE_SIZE));
  311.  
  312.   /* Check each active page address starting from end */
  313.   while (Address > (PageStartAddress + 2))
  314.   {
  315.     /* Get the current location content to be compared with virtual address */
  316.     AddressValue = (*(__IO uint16_t*)Address);
  317.  
  318.     /* Compare the read address with the virtual address */
  319.     if (AddressValue == VirtAddress)
  320.     {
  321.       /* Get content of Address-2 which is variable value */
  322.       *Data = (*(__IO uint16_t*)(Address - 2));
  323.  
  324.       /* In case variable value is read, reset ReadStatus flag */
  325.       ReadStatus = 0;
  326.  
  327.       break;
  328.     }
  329.     else
  330.     {
  331.       /* Next address location */
  332.       Address = Address - 4;
  333.     }
  334.   }
  335.  
  336.   /* Return ReadStatus value: (0: variable exist, 1: variable doesn't exist) */
  337.   return ReadStatus;
  338. }
  339.  
  340. /**
  341.   * @brief  Writes/upadtes variable data in EEPROM.
  342.   * @param  VirtAddress: Variable virtual address
  343.   * @param  Data: 16 bit data to be written
  344.   * @retval Success or error status:
  345.   *           - FLASH_COMPLETE: on success
  346.   *           - PAGE_FULL: if valid page is full
  347.   *           - NO_VALID_PAGE: if no valid page was found
  348.   *           - Flash error code: on write Flash error
  349.   */
  350. uint16_t EE_WriteVariable(uint16_t VirtAddress, uint16_t Data)
  351. {
  352.   uint16_t Status = 0;
  353.  
  354.   /* Write the variable virtual address and value in the EEPROM */
  355.   Status = EE_VerifyPageFullWriteVariable(VirtAddress, Data);
  356.  
  357.   /* In case the EEPROM active page is full */
  358.   if (Status == PAGE_FULL)
  359.   {
  360.     /* Perform Page transfer */
  361.     Status = EE_PageTransfer(VirtAddress, Data);
  362.   }
  363.  
  364.   /* Return last operation status */
  365.   return Status;
  366. }
  367.  
  368. /**
  369.   * @brief  Erases PAGE0 and PAGE1 and writes VALID_PAGE header to PAGE0
  370.   * @param  None
  371.   * @retval Status of the last operation (Flash write or erase) done during
  372.   *         EEPROM formating
  373.   */
  374.  
  375. static FLASH_Status EE_Format(void)
  376. {
  377.   FLASH_Status FlashStatus = HAL_FLASH_ERROR_NONE;
  378.  
  379.   /* Erase Page0 and Page1  */
  380.   /* Fill EraseInit structure*/
  381.    EraseInitStruct.TypeErase   = FLASH_TYPEERASE_PAGES;
  382.    EraseInitStruct.PageAddress = PAGE0_BASE_ADDRESS;
  383.    EraseInitStruct.NbPages     = 2;
  384.  
  385.    if(HAL_FLASHEx_Erase(&EraseInitStruct, &PAGEError) != HAL_OK)
  386.    /* If erase operation was failed, a Flash error code is returned */
  387.   {
  388.           FlashStatus = HAL_FLASH_GetError();
  389.              return FlashStatus;
  390.   }
  391.  
  392.  
  393.   /* Set Page0 as valid page: Write VALID_PAGE at Page0 base address */
  394.   uint32_t rc = HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD,PAGE0_BASE_ADDRESS, VALID_PAGE);
  395.    /* If program operation was failed, a Flash error code is returned */
  396.  
  397.     if (rc!= HAL_OK)
  398.    {
  399.           FlashStatus = HAL_FLASH_GetError();
  400.         return FlashStatus;
  401.    }
  402.  
  403.   /* Return Page1 erase operation status */
  404.   return FlashStatus;
  405. }
  406.  
  407. /**
  408.   * @brief  Find valid Page for write or read operation
  409.   * @param  Operation: operation to achieve on the valid page.
  410.   *   This parameter can be one of the following values:
  411.   *     @arg READ_FROM_VALID_PAGE: read operation from valid page
  412.   *     @arg WRITE_IN_VALID_PAGE: write operation from valid page
  413.   * @retval Valid page number (PAGE0 or PAGE1) or NO_VALID_PAGE in case
  414.   *   of no valid page was found
  415.   */
  416. static uint16_t EE_FindValidPage(uint8_t Operation)
  417. {
  418.   uint16_t PageStatus0 = 6, PageStatus1 = 6;
  419.  
  420.   /* Get Page0 actual status */
  421.   PageStatus0 = (*(__IO uint16_t*)PAGE0_BASE_ADDRESS);
  422.  
  423.   /* Get Page1 actual status */
  424.   PageStatus1 = (*(__IO uint16_t*)PAGE1_BASE_ADDRESS);
  425.  
  426.   /* Write or read operation */
  427.   switch (Operation)
  428.   {
  429.     case WRITE_IN_VALID_PAGE:   /* ---- Write operation ---- */
  430.       if (PageStatus1 == VALID_PAGE)
  431.       {
  432.         /* Page0 receiving data */
  433.         if (PageStatus0 == RECEIVE_DATA)
  434.         {
  435.           return PAGE0;         /* Page0 valid */
  436.         }
  437.         else
  438.         {
  439.           return PAGE1;         /* Page1 valid */
  440.         }
  441.       }
  442.       else if (PageStatus0 == VALID_PAGE)
  443.       {
  444.         /* Page1 receiving data */
  445.         if (PageStatus1 == RECEIVE_DATA)
  446.         {
  447.           return PAGE1;         /* Page1 valid */
  448.         }
  449.         else
  450.         {
  451.           return PAGE0;         /* Page0 valid */
  452.         }
  453.       }
  454.       else
  455.       {
  456.         return NO_VALID_PAGE;   /* No valid Page */
  457.       }
  458.  
  459.     case READ_FROM_VALID_PAGE:  /* ---- Read operation ---- */
  460.       if (PageStatus0 == VALID_PAGE)
  461.       {
  462.         return PAGE0;           /* Page0 valid */
  463.       }
  464.       else if (PageStatus1 == VALID_PAGE)
  465.       {
  466.         return PAGE1;           /* Page1 valid */
  467.       }
  468.       else
  469.       {
  470.         return NO_VALID_PAGE ;  /* No valid Page */
  471.       }
  472.  
  473.     default:
  474.       return PAGE0;             /* Page0 valid */
  475.   }
  476. }
  477.  
  478. /**
  479.   * @brief  Verify if active page is full and Writes variable in EEPROM.
  480.   * @param  VirtAddress: 16 bit virtual address of the variable
  481.   * @param  Data: 16 bit data to be written as variable value
  482.   * @retval Success or error status:
  483.   *           - FLASH_COMPLETE: on success
  484.   *           - PAGE_FULL: if valid page is full
  485.   *           - NO_VALID_PAGE: if no valid page was found
  486.   *           - Flash error code: on write Flash error
  487.   */
  488. static uint16_t EE_VerifyPageFullWriteVariable(uint16_t VirtAddress, uint16_t Data)
  489. {
  490.   FLASH_Status FlashStatus = HAL_FLASH_ERROR_NONE;
  491.   uint16_t ValidPage = PAGE0;
  492.   uint32_t Address = 0x08010000, PageEndAddress = 0x080107FF;
  493.  
  494.   /* Get valid Page for write operation */
  495.   ValidPage = EE_FindValidPage(WRITE_IN_VALID_PAGE);
  496.  
  497.   /* Check if there is no valid page */
  498.   if (ValidPage == NO_VALID_PAGE)
  499.   {
  500.     return  NO_VALID_PAGE;
  501.   }
  502.  
  503.   /* Get the valid Page start Address */
  504.   Address = (uint32_t)(PAGE0_BASE_ADDRESS + (uint32_t)(ValidPage * PAGE_SIZE));
  505.  
  506.   /* Get the valid Page end Address */
  507.   PageEndAddress = (uint32_t)((PAGE0_BASE_ADDRESS - 2) + (uint32_t)((1 + ValidPage) * PAGE_SIZE));
  508.  
  509.   /* Check each active page address starting from begining */
  510.   while (Address < PageEndAddress)
  511.   {
  512.     /* Verify if Address and Address+2 contents are 0xFFFFFFFF */
  513.     if ((*(__IO uint32_t*)Address) == 0xFFFFFFFF)
  514.     {
  515.       /* Set variable data */
  516.        HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD,Address, Data);
  517.        /* If program operation was failed, a Flash error code is returned */
  518.       FlashStatus = HAL_FLASH_GetError();
  519.         if (FlashStatus != HAL_FLASH_ERROR_NONE)
  520.        {
  521.          return FlashStatus;
  522.        }
  523.      /* Set variable virtual address */
  524.       HAL_FLASH_Unlock();
  525.       HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD,Address + 2 ,VirtAddress);
  526.        /* If program operation was failed, a Flash error code is returned */
  527.       FlashStatus = HAL_FLASH_GetError();
  528.       /* Return program operation status */
  529.       return FlashStatus;
  530.     }
  531.     else
  532.     {
  533.       /* Next address location */
  534.       Address = Address + 4;
  535.     }
  536.   }
  537.  
  538.   /* Return PAGE_FULL in case the valid page is full */
  539.   return PAGE_FULL;
  540. }
  541.  
  542. /**
  543.   * @brief  Transfers last updated variables data from the full Page to
  544.   *   an empty one.
  545.   * @param  VirtAddress: 16 bit virtual address of the variable
  546.   * @param  Data: 16 bit data to be written as variable value
  547.   * @retval Success or error status:
  548.   *           - FLASH_COMPLETE: on success
  549.   *           - PAGE_FULL: if valid page is full
  550.   *           - NO_VALID_PAGE: if no valid page was found
  551.   *           - Flash error code: on write Flash error
  552.   */
  553. static uint16_t EE_PageTransfer(uint16_t VirtAddress, uint16_t Data)
  554. {
  555.   FLASH_Status FlashStatus = HAL_FLASH_ERROR_NONE;
  556.   uint32_t NewPageAddress = 0x080103FF, OldPageAddress = 0x08010000;
  557.   uint16_t ValidPage = PAGE0, VarIdx = 0;
  558.   uint16_t EepromStatus = 0, ReadStatus = 0;
  559.  
  560.   /* Get active Page for read operation */
  561.   ValidPage = EE_FindValidPage(READ_FROM_VALID_PAGE);
  562.  
  563.   if (ValidPage == PAGE1)       /* Page1 valid */
  564.   {
  565.     /* New page address where variable will be moved to */
  566.     NewPageAddress = PAGE0_BASE_ADDRESS;
  567.  
  568.     /* Old page address where variable will be taken from */
  569.     OldPageAddress = PAGE1_BASE_ADDRESS;
  570.   }
  571.   else if (ValidPage == PAGE0)  /* Page0 valid */
  572.   {
  573.     /* New page address where variable will be moved to */
  574.     NewPageAddress = PAGE1_BASE_ADDRESS;
  575.  
  576.     /* Old page address where variable will be taken from */
  577.     OldPageAddress = PAGE0_BASE_ADDRESS;
  578.   }
  579.   else
  580.   {
  581.     return NO_VALID_PAGE;       /* No valid Page */
  582.   }
  583.  
  584.   /* Set the new Page status to RECEIVE_DATA status */
  585.   HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD,NewPageAddress,RECEIVE_DATA);
  586.   FlashStatus = HAL_FLASH_GetError();
  587.   /* If program operation was failed, a Flash error code is returned */
  588.   if (FlashStatus !=  HAL_FLASH_ERROR_NONE)
  589.   {
  590.     return FlashStatus;
  591.   }
  592.  
  593.   /* Write the variable passed as parameter in the new active page */
  594.   EepromStatus = EE_VerifyPageFullWriteVariable(VirtAddress, Data);
  595.   /* If program operation was failed, a Flash error code is returned */
  596.   if (EepromStatus !=  HAL_FLASH_ERROR_NONE)
  597.   {
  598.     return EepromStatus;
  599.   }
  600.  
  601.   /* Transfer process: transfer variables from old to the new active page */
  602.   for (VarIdx = 0; VarIdx < NumbOfVar; VarIdx++)
  603.   {
  604.     if (VirtAddVarTab[VarIdx] != VirtAddress)  /* Check each variable except the one passed as parameter */
  605.     {
  606.       /* Read the other last variable updates */
  607.       ReadStatus = EE_ReadVariable(VirtAddVarTab[VarIdx], &DataVar);
  608.       /* In case variable corresponding to the virtual address was found */
  609.       if (ReadStatus != 0x1)
  610.       {
  611.         /* Transfer the variable to the new active page */
  612.         EepromStatus = EE_VerifyPageFullWriteVariable(VirtAddVarTab[VarIdx], DataVar);
  613.         /* If program operation was failed, a Flash error code is returned */
  614.         if (EepromStatus != HAL_FLASH_ERROR_NONE)
  615.         {
  616.           return EepromStatus;
  617.         }
  618.       }
  619.     }
  620.   }
  621.  
  622.   /* Erase the old Page: Set old Page status to ERASED status */
  623.   FLASH_PageErase(OldPageAddress);
  624.   /* If erase operation was failed, a Flash error code is returned */
  625.   FlashStatus = HAL_FLASH_GetError();
  626.   if (FlashStatus !=  HAL_FLASH_ERROR_NONE)
  627.   {
  628.     return FlashStatus;
  629.   }
  630.  
  631.   /* Set new Page status to VALID_PAGE status */
  632.   HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD,NewPageAddress, VALID_PAGE);
  633.   /* If program operation was failed, a Flash error code is returned */
  634.   FlashStatus = HAL_FLASH_GetError();
  635.   if (FlashStatus !=  HAL_FLASH_ERROR_NONE)
  636.   {
  637.     return FlashStatus;
  638.   }
  639.  
  640.   /* Return last operation flash status */
  641.   return FlashStatus;
  642. }
  643.  
  644. /**
  645.   * @}
  646.   */
  647.  
  648. /******************* (C) COPYRIGHT 2009 STMicroelectronics *****END OF FILE****/
  649.