f

Dependencies:   TS_DISCO_F746NG mbed LCD_DISCO_F746NG mbed-rtos BSP_DISCO_F746NG FatFS X_NUCLEO_IHM02A1

Committer:
emperord
Date:
Fri Mar 08 13:48:46 2019 +0000
Revision:
2:37a61db8b04b
f

Who changed what in which revision?

UserRevisionLine numberNew contents of line
emperord 2:37a61db8b04b 1 /**
emperord 2:37a61db8b04b 2 ******************************************************************************
emperord 2:37a61db8b04b 3 * @file EEPROM/EEPROM_Emulation/src/eeprom.c
emperord 2:37a61db8b04b 4 * @author MCD Application Team
emperord 2:37a61db8b04b 5 * @version V1.0.1
emperord 2:37a61db8b04b 6 * @date 29-January-2016
emperord 2:37a61db8b04b 7 * @brief This file provides all the EEPROM emulation firmware functions.
emperord 2:37a61db8b04b 8 ******************************************************************************
emperord 2:37a61db8b04b 9 * @attention
emperord 2:37a61db8b04b 10 *
emperord 2:37a61db8b04b 11 * <h2><center>&copy; COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
emperord 2:37a61db8b04b 12 *
emperord 2:37a61db8b04b 13 * Redistribution and use in source and binary forms, with or without modification,
emperord 2:37a61db8b04b 14 * are permitted provided that the following conditions are met:
emperord 2:37a61db8b04b 15 * 1. Redistributions of source code must retain the above copyright notice,
emperord 2:37a61db8b04b 16 * this list of conditions and the following disclaimer.
emperord 2:37a61db8b04b 17 * 2. Redistributions in binary form must reproduce the above copyright notice,
emperord 2:37a61db8b04b 18 * this list of conditions and the following disclaimer in the documentation
emperord 2:37a61db8b04b 19 * and/or other materials provided with the distribution.
emperord 2:37a61db8b04b 20 * 3. Neither the name of STMicroelectronics nor the names of its contributors
emperord 2:37a61db8b04b 21 * may be used to endorse or promote products derived from this software
emperord 2:37a61db8b04b 22 * without specific prior written permission.
emperord 2:37a61db8b04b 23 *
emperord 2:37a61db8b04b 24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
emperord 2:37a61db8b04b 25 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
emperord 2:37a61db8b04b 26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
emperord 2:37a61db8b04b 27 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
emperord 2:37a61db8b04b 28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
emperord 2:37a61db8b04b 29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
emperord 2:37a61db8b04b 30 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
emperord 2:37a61db8b04b 31 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
emperord 2:37a61db8b04b 32 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
emperord 2:37a61db8b04b 33 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
emperord 2:37a61db8b04b 34 *
emperord 2:37a61db8b04b 35 ******************************************************************************
emperord 2:37a61db8b04b 36 */
emperord 2:37a61db8b04b 37
emperord 2:37a61db8b04b 38 /** @addtogroup EEPROM_Emulation
emperord 2:37a61db8b04b 39 * @{
emperord 2:37a61db8b04b 40 */
emperord 2:37a61db8b04b 41
emperord 2:37a61db8b04b 42 /* Includes ------------------------------------------------------------------*/
emperord 2:37a61db8b04b 43 #include "eeprom.h"
emperord 2:37a61db8b04b 44
emperord 2:37a61db8b04b 45 /* Private typedef -----------------------------------------------------------*/
emperord 2:37a61db8b04b 46 /* Private define ------------------------------------------------------------*/
emperord 2:37a61db8b04b 47 /* Private macro -------------------------------------------------------------*/
emperord 2:37a61db8b04b 48 /* Private variables ---------------------------------------------------------*/
emperord 2:37a61db8b04b 49
emperord 2:37a61db8b04b 50 /* Dummy variables to protect eeprom pages if code size is bigger than 32kb (F401)
emperord 2:37a61db8b04b 51 needed in Mbed online compiler to avoid conflict with linker (N.S.) */
emperord 2:37a61db8b04b 52 const uint8_t Eeprom_area0[PAGE_SIZE] __attribute__((at(PAGE0_BASE_ADDRESS),used))={ [0 ... (PAGE_SIZE-1)] = 0xFF };
emperord 2:37a61db8b04b 53 const uint8_t Eeprom_area1[PAGE_SIZE] __attribute__((at(PAGE1_BASE_ADDRESS),used))={ [0 ... (PAGE_SIZE-1)] = 0xFF };
emperord 2:37a61db8b04b 54
emperord 2:37a61db8b04b 55
emperord 2:37a61db8b04b 56 /* Global variable used to store variable value in read sequence */
emperord 2:37a61db8b04b 57 uint16_t DataVar = 0;
emperord 2:37a61db8b04b 58
emperord 2:37a61db8b04b 59 /* Virtual address defined by the user: 0xFFFF value is prohibited */
emperord 2:37a61db8b04b 60 extern uint16_t VirtAddVarTab[NB_OF_VAR];
emperord 2:37a61db8b04b 61
emperord 2:37a61db8b04b 62 /* Private function prototypes -----------------------------------------------*/
emperord 2:37a61db8b04b 63 /* Private functions ---------------------------------------------------------*/
emperord 2:37a61db8b04b 64 static HAL_StatusTypeDef EE_Format(void);
emperord 2:37a61db8b04b 65 static uint16_t EE_FindValidPage(uint8_t Operation);
emperord 2:37a61db8b04b 66 static uint16_t EE_VerifyPageFullWriteVariable(uint16_t VirtAddress, uint16_t Data);
emperord 2:37a61db8b04b 67 static uint16_t EE_PageTransfer(uint16_t VirtAddress, uint16_t Data);
emperord 2:37a61db8b04b 68 static uint16_t EE_VerifyPageFullyErased(uint32_t Address);
emperord 2:37a61db8b04b 69
emperord 2:37a61db8b04b 70 /**
emperord 2:37a61db8b04b 71 * @brief Restore the pages to a known good state in case of page's status
emperord 2:37a61db8b04b 72 * corruption after a power loss.
emperord 2:37a61db8b04b 73 * @param None.
emperord 2:37a61db8b04b 74 * @retval - Flash error code: on write Flash error
emperord 2:37a61db8b04b 75 * - FLASH_COMPLETE: on success
emperord 2:37a61db8b04b 76 */
emperord 2:37a61db8b04b 77 uint16_t EE_Init(void)
emperord 2:37a61db8b04b 78 {
emperord 2:37a61db8b04b 79 uint16_t PageStatus0 = 6, PageStatus1 = 6;
emperord 2:37a61db8b04b 80 uint16_t VarIdx = 0;
emperord 2:37a61db8b04b 81 uint16_t EepromStatus = 0, ReadStatus = 0;
emperord 2:37a61db8b04b 82 int16_t x = -1;
emperord 2:37a61db8b04b 83 HAL_StatusTypeDef FlashStatus;
emperord 2:37a61db8b04b 84 uint32_t SectorError = 0;
emperord 2:37a61db8b04b 85 FLASH_EraseInitTypeDef pEraseInit;
emperord 2:37a61db8b04b 86
emperord 2:37a61db8b04b 87
emperord 2:37a61db8b04b 88 /* Get Page0 status */
emperord 2:37a61db8b04b 89 PageStatus0 = (*(__IO uint16_t*)PAGE0_BASE_ADDRESS);
emperord 2:37a61db8b04b 90 /* Get Page1 status */
emperord 2:37a61db8b04b 91 PageStatus1 = (*(__IO uint16_t*)PAGE1_BASE_ADDRESS);
emperord 2:37a61db8b04b 92
emperord 2:37a61db8b04b 93 pEraseInit.TypeErase = TYPEERASE_SECTORS;
emperord 2:37a61db8b04b 94 pEraseInit.Sector = PAGE0_ID;
emperord 2:37a61db8b04b 95 pEraseInit.NbSectors = 1;
emperord 2:37a61db8b04b 96 pEraseInit.VoltageRange = VOLTAGE_RANGE;
emperord 2:37a61db8b04b 97
emperord 2:37a61db8b04b 98 /* Check for invalid header states and repair if necessary */
emperord 2:37a61db8b04b 99 switch (PageStatus0)
emperord 2:37a61db8b04b 100 {
emperord 2:37a61db8b04b 101 case ERASED:
emperord 2:37a61db8b04b 102 if (PageStatus1 == VALID_PAGE) /* Page0 erased, Page1 valid */
emperord 2:37a61db8b04b 103 {
emperord 2:37a61db8b04b 104 /* Erase Page0 */
emperord 2:37a61db8b04b 105 if(!EE_VerifyPageFullyErased(PAGE0_BASE_ADDRESS))
emperord 2:37a61db8b04b 106 {
emperord 2:37a61db8b04b 107 FlashStatus = HAL_FLASHEx_Erase(&pEraseInit, &SectorError);
emperord 2:37a61db8b04b 108 /* If erase operation was failed, a Flash error code is returned */
emperord 2:37a61db8b04b 109 if (FlashStatus != HAL_OK)
emperord 2:37a61db8b04b 110 {
emperord 2:37a61db8b04b 111 return FlashStatus;
emperord 2:37a61db8b04b 112 }
emperord 2:37a61db8b04b 113 }
emperord 2:37a61db8b04b 114 }
emperord 2:37a61db8b04b 115 else if (PageStatus1 == RECEIVE_DATA) /* Page0 erased, Page1 receive */
emperord 2:37a61db8b04b 116 {
emperord 2:37a61db8b04b 117 /* Erase Page0 */
emperord 2:37a61db8b04b 118 if(!EE_VerifyPageFullyErased(PAGE0_BASE_ADDRESS))
emperord 2:37a61db8b04b 119 {
emperord 2:37a61db8b04b 120 FlashStatus = HAL_FLASHEx_Erase(&pEraseInit, &SectorError);
emperord 2:37a61db8b04b 121 /* If erase operation was failed, a Flash error code is returned */
emperord 2:37a61db8b04b 122 if (FlashStatus != HAL_OK)
emperord 2:37a61db8b04b 123 {
emperord 2:37a61db8b04b 124 return FlashStatus;
emperord 2:37a61db8b04b 125 }
emperord 2:37a61db8b04b 126 }
emperord 2:37a61db8b04b 127 /* Mark Page1 as valid */
emperord 2:37a61db8b04b 128 FlashStatus = HAL_FLASH_Program(TYPEPROGRAM_HALFWORD, PAGE1_BASE_ADDRESS, VALID_PAGE);
emperord 2:37a61db8b04b 129 /* If program operation was failed, a Flash error code is returned */
emperord 2:37a61db8b04b 130 if (FlashStatus != HAL_OK)
emperord 2:37a61db8b04b 131 {
emperord 2:37a61db8b04b 132 return FlashStatus;
emperord 2:37a61db8b04b 133 }
emperord 2:37a61db8b04b 134 }
emperord 2:37a61db8b04b 135 else /* First EEPROM access (Page0&1 are erased) or invalid state -> format EEPROM */
emperord 2:37a61db8b04b 136 {
emperord 2:37a61db8b04b 137 /* Erase both Page0 and Page1 and set Page0 as valid page */
emperord 2:37a61db8b04b 138 FlashStatus = EE_Format();
emperord 2:37a61db8b04b 139 /* If erase/program operation was failed, a Flash error code is returned */
emperord 2:37a61db8b04b 140 if (FlashStatus != HAL_OK)
emperord 2:37a61db8b04b 141 {
emperord 2:37a61db8b04b 142 return FlashStatus;
emperord 2:37a61db8b04b 143 }
emperord 2:37a61db8b04b 144 }
emperord 2:37a61db8b04b 145 break;
emperord 2:37a61db8b04b 146
emperord 2:37a61db8b04b 147 case RECEIVE_DATA:
emperord 2:37a61db8b04b 148 if (PageStatus1 == VALID_PAGE) /* Page0 receive, Page1 valid */
emperord 2:37a61db8b04b 149 {
emperord 2:37a61db8b04b 150 /* Transfer data from Page1 to Page0 */
emperord 2:37a61db8b04b 151 for (VarIdx = 0; VarIdx < NB_OF_VAR; VarIdx++)
emperord 2:37a61db8b04b 152 {
emperord 2:37a61db8b04b 153 if (( *(__IO uint16_t*)(PAGE0_BASE_ADDRESS + 6)) == VirtAddVarTab[VarIdx])
emperord 2:37a61db8b04b 154 {
emperord 2:37a61db8b04b 155 x = VarIdx;
emperord 2:37a61db8b04b 156 }
emperord 2:37a61db8b04b 157 if (VarIdx != x)
emperord 2:37a61db8b04b 158 {
emperord 2:37a61db8b04b 159 /* Read the last variables' updates */
emperord 2:37a61db8b04b 160 ReadStatus = EE_ReadVariable(VirtAddVarTab[VarIdx], &DataVar);
emperord 2:37a61db8b04b 161 /* In case variable corresponding to the virtual address was found */
emperord 2:37a61db8b04b 162 if (ReadStatus != 0x1)
emperord 2:37a61db8b04b 163 {
emperord 2:37a61db8b04b 164 /* Transfer the variable to the Page0 */
emperord 2:37a61db8b04b 165 EepromStatus = EE_VerifyPageFullWriteVariable(VirtAddVarTab[VarIdx], DataVar);
emperord 2:37a61db8b04b 166 /* If program operation was failed, a Flash error code is returned */
emperord 2:37a61db8b04b 167 if (EepromStatus != HAL_OK)
emperord 2:37a61db8b04b 168 {
emperord 2:37a61db8b04b 169 return EepromStatus;
emperord 2:37a61db8b04b 170 }
emperord 2:37a61db8b04b 171 }
emperord 2:37a61db8b04b 172 }
emperord 2:37a61db8b04b 173 }
emperord 2:37a61db8b04b 174 /* Mark Page0 as valid */
emperord 2:37a61db8b04b 175 FlashStatus = HAL_FLASH_Program(TYPEPROGRAM_HALFWORD, PAGE0_BASE_ADDRESS, VALID_PAGE);
emperord 2:37a61db8b04b 176 /* If program operation was failed, a Flash error code is returned */
emperord 2:37a61db8b04b 177 if (FlashStatus != HAL_OK)
emperord 2:37a61db8b04b 178 {
emperord 2:37a61db8b04b 179 return FlashStatus;
emperord 2:37a61db8b04b 180 }
emperord 2:37a61db8b04b 181 pEraseInit.Sector = PAGE1_ID;
emperord 2:37a61db8b04b 182 pEraseInit.NbSectors = 1;
emperord 2:37a61db8b04b 183 pEraseInit.VoltageRange = VOLTAGE_RANGE;
emperord 2:37a61db8b04b 184 /* Erase Page1 */
emperord 2:37a61db8b04b 185 if(!EE_VerifyPageFullyErased(PAGE1_BASE_ADDRESS))
emperord 2:37a61db8b04b 186 {
emperord 2:37a61db8b04b 187 FlashStatus = HAL_FLASHEx_Erase(&pEraseInit, &SectorError);
emperord 2:37a61db8b04b 188 /* If erase operation was failed, a Flash error code is returned */
emperord 2:37a61db8b04b 189 if (FlashStatus != HAL_OK)
emperord 2:37a61db8b04b 190 {
emperord 2:37a61db8b04b 191 return FlashStatus;
emperord 2:37a61db8b04b 192 }
emperord 2:37a61db8b04b 193 }
emperord 2:37a61db8b04b 194 }
emperord 2:37a61db8b04b 195 else if (PageStatus1 == ERASED) /* Page0 receive, Page1 erased */
emperord 2:37a61db8b04b 196 {
emperord 2:37a61db8b04b 197 pEraseInit.Sector = PAGE1_ID;
emperord 2:37a61db8b04b 198 pEraseInit.NbSectors = 1;
emperord 2:37a61db8b04b 199 pEraseInit.VoltageRange = VOLTAGE_RANGE;
emperord 2:37a61db8b04b 200 /* Erase Page1 */
emperord 2:37a61db8b04b 201 if(!EE_VerifyPageFullyErased(PAGE1_BASE_ADDRESS))
emperord 2:37a61db8b04b 202 {
emperord 2:37a61db8b04b 203 FlashStatus = HAL_FLASHEx_Erase(&pEraseInit, &SectorError);
emperord 2:37a61db8b04b 204 /* If erase operation was failed, a Flash error code is returned */
emperord 2:37a61db8b04b 205 if (FlashStatus != HAL_OK)
emperord 2:37a61db8b04b 206 {
emperord 2:37a61db8b04b 207 return FlashStatus;
emperord 2:37a61db8b04b 208 }
emperord 2:37a61db8b04b 209 }
emperord 2:37a61db8b04b 210 /* Mark Page0 as valid */
emperord 2:37a61db8b04b 211 FlashStatus = HAL_FLASH_Program(TYPEPROGRAM_HALFWORD, PAGE0_BASE_ADDRESS, VALID_PAGE);
emperord 2:37a61db8b04b 212 /* If program operation was failed, a Flash error code is returned */
emperord 2:37a61db8b04b 213 if (FlashStatus != HAL_OK)
emperord 2:37a61db8b04b 214 {
emperord 2:37a61db8b04b 215 return FlashStatus;
emperord 2:37a61db8b04b 216 }
emperord 2:37a61db8b04b 217 }
emperord 2:37a61db8b04b 218 else /* Invalid state -> format eeprom */
emperord 2:37a61db8b04b 219 {
emperord 2:37a61db8b04b 220 /* Erase both Page0 and Page1 and set Page0 as valid page */
emperord 2:37a61db8b04b 221 FlashStatus = EE_Format();
emperord 2:37a61db8b04b 222 /* If erase/program operation was failed, a Flash error code is returned */
emperord 2:37a61db8b04b 223 if (FlashStatus != HAL_OK)
emperord 2:37a61db8b04b 224 {
emperord 2:37a61db8b04b 225 return FlashStatus;
emperord 2:37a61db8b04b 226 }
emperord 2:37a61db8b04b 227 }
emperord 2:37a61db8b04b 228 break;
emperord 2:37a61db8b04b 229
emperord 2:37a61db8b04b 230 case VALID_PAGE:
emperord 2:37a61db8b04b 231 if (PageStatus1 == VALID_PAGE) /* Invalid state -> format eeprom */
emperord 2:37a61db8b04b 232 {
emperord 2:37a61db8b04b 233 /* Erase both Page0 and Page1 and set Page0 as valid page */
emperord 2:37a61db8b04b 234 FlashStatus = EE_Format();
emperord 2:37a61db8b04b 235 /* If erase/program operation was failed, a Flash error code is returned */
emperord 2:37a61db8b04b 236 if (FlashStatus != HAL_OK)
emperord 2:37a61db8b04b 237 {
emperord 2:37a61db8b04b 238 return FlashStatus;
emperord 2:37a61db8b04b 239 }
emperord 2:37a61db8b04b 240 }
emperord 2:37a61db8b04b 241 else if (PageStatus1 == ERASED) /* Page0 valid, Page1 erased */
emperord 2:37a61db8b04b 242 {
emperord 2:37a61db8b04b 243 pEraseInit.Sector = PAGE1_ID;
emperord 2:37a61db8b04b 244 pEraseInit.NbSectors = 1;
emperord 2:37a61db8b04b 245 pEraseInit.VoltageRange = VOLTAGE_RANGE;
emperord 2:37a61db8b04b 246 /* Erase Page1 */
emperord 2:37a61db8b04b 247 if(!EE_VerifyPageFullyErased(PAGE1_BASE_ADDRESS))
emperord 2:37a61db8b04b 248 {
emperord 2:37a61db8b04b 249 FlashStatus = HAL_FLASHEx_Erase(&pEraseInit, &SectorError);
emperord 2:37a61db8b04b 250 /* If erase operation was failed, a Flash error code is returned */
emperord 2:37a61db8b04b 251 if (FlashStatus != HAL_OK)
emperord 2:37a61db8b04b 252 {
emperord 2:37a61db8b04b 253 return FlashStatus;
emperord 2:37a61db8b04b 254 }
emperord 2:37a61db8b04b 255 }
emperord 2:37a61db8b04b 256 }
emperord 2:37a61db8b04b 257 else /* Page0 valid, Page1 receive */
emperord 2:37a61db8b04b 258 {
emperord 2:37a61db8b04b 259 /* Transfer data from Page0 to Page1 */
emperord 2:37a61db8b04b 260 for (VarIdx = 0; VarIdx < NB_OF_VAR; VarIdx++)
emperord 2:37a61db8b04b 261 {
emperord 2:37a61db8b04b 262 if ((*(__IO uint16_t*)(PAGE1_BASE_ADDRESS + 6)) == VirtAddVarTab[VarIdx])
emperord 2:37a61db8b04b 263 {
emperord 2:37a61db8b04b 264 x = VarIdx;
emperord 2:37a61db8b04b 265 }
emperord 2:37a61db8b04b 266 if (VarIdx != x)
emperord 2:37a61db8b04b 267 {
emperord 2:37a61db8b04b 268 /* Read the last variables' updates */
emperord 2:37a61db8b04b 269 ReadStatus = EE_ReadVariable(VirtAddVarTab[VarIdx], &DataVar);
emperord 2:37a61db8b04b 270 /* In case variable corresponding to the virtual address was found */
emperord 2:37a61db8b04b 271 if (ReadStatus != 0x1)
emperord 2:37a61db8b04b 272 {
emperord 2:37a61db8b04b 273 /* Transfer the variable to the Page1 */
emperord 2:37a61db8b04b 274 EepromStatus = EE_VerifyPageFullWriteVariable(VirtAddVarTab[VarIdx], DataVar);
emperord 2:37a61db8b04b 275 /* If program operation was failed, a Flash error code is returned */
emperord 2:37a61db8b04b 276 if (EepromStatus != HAL_OK)
emperord 2:37a61db8b04b 277 {
emperord 2:37a61db8b04b 278 return EepromStatus;
emperord 2:37a61db8b04b 279 }
emperord 2:37a61db8b04b 280 }
emperord 2:37a61db8b04b 281 }
emperord 2:37a61db8b04b 282 }
emperord 2:37a61db8b04b 283 /* Mark Page1 as valid */
emperord 2:37a61db8b04b 284 FlashStatus = HAL_FLASH_Program(TYPEPROGRAM_HALFWORD, PAGE1_BASE_ADDRESS, VALID_PAGE);
emperord 2:37a61db8b04b 285 /* If program operation was failed, a Flash error code is returned */
emperord 2:37a61db8b04b 286 if (FlashStatus != HAL_OK)
emperord 2:37a61db8b04b 287 {
emperord 2:37a61db8b04b 288 return FlashStatus;
emperord 2:37a61db8b04b 289 }
emperord 2:37a61db8b04b 290 pEraseInit.Sector = PAGE0_ID;
emperord 2:37a61db8b04b 291 pEraseInit.NbSectors = 1;
emperord 2:37a61db8b04b 292 pEraseInit.VoltageRange = VOLTAGE_RANGE;
emperord 2:37a61db8b04b 293 /* Erase Page0 */
emperord 2:37a61db8b04b 294 if(!EE_VerifyPageFullyErased(PAGE0_BASE_ADDRESS))
emperord 2:37a61db8b04b 295 {
emperord 2:37a61db8b04b 296 FlashStatus = HAL_FLASHEx_Erase(&pEraseInit, &SectorError);
emperord 2:37a61db8b04b 297 /* If erase operation was failed, a Flash error code is returned */
emperord 2:37a61db8b04b 298 if (FlashStatus != HAL_OK)
emperord 2:37a61db8b04b 299 {
emperord 2:37a61db8b04b 300 return FlashStatus;
emperord 2:37a61db8b04b 301 }
emperord 2:37a61db8b04b 302 }
emperord 2:37a61db8b04b 303 }
emperord 2:37a61db8b04b 304 break;
emperord 2:37a61db8b04b 305
emperord 2:37a61db8b04b 306 default: /* Any other state -> format eeprom */
emperord 2:37a61db8b04b 307 /* Erase both Page0 and Page1 and set Page0 as valid page */
emperord 2:37a61db8b04b 308 FlashStatus = EE_Format();
emperord 2:37a61db8b04b 309 /* If erase/program operation was failed, a Flash error code is returned */
emperord 2:37a61db8b04b 310 if (FlashStatus != HAL_OK)
emperord 2:37a61db8b04b 311 {
emperord 2:37a61db8b04b 312 return FlashStatus;
emperord 2:37a61db8b04b 313 }
emperord 2:37a61db8b04b 314 break;
emperord 2:37a61db8b04b 315 }
emperord 2:37a61db8b04b 316
emperord 2:37a61db8b04b 317 return HAL_OK;
emperord 2:37a61db8b04b 318 }
emperord 2:37a61db8b04b 319
emperord 2:37a61db8b04b 320 /**
emperord 2:37a61db8b04b 321 * @brief Verify if specified page is fully erased.
emperord 2:37a61db8b04b 322 * @param Address: page address
emperord 2:37a61db8b04b 323 * This parameter can be one of the following values:
emperord 2:37a61db8b04b 324 * @arg PAGE0_BASE_ADDRESS: Page0 base address
emperord 2:37a61db8b04b 325 * @arg PAGE1_BASE_ADDRESS: Page1 base address
emperord 2:37a61db8b04b 326 * @retval page fully erased status:
emperord 2:37a61db8b04b 327 * - 0: if Page not erased
emperord 2:37a61db8b04b 328 * - 1: if Page erased
emperord 2:37a61db8b04b 329 */
emperord 2:37a61db8b04b 330 uint16_t EE_VerifyPageFullyErased(uint32_t Address)
emperord 2:37a61db8b04b 331 {
emperord 2:37a61db8b04b 332 uint32_t readstatus = 1;
emperord 2:37a61db8b04b 333 uint16_t addressvalue = 0x5555;
emperord 2:37a61db8b04b 334 uint32_t end_address;
emperord 2:37a61db8b04b 335
emperord 2:37a61db8b04b 336 if (PAGE0_BASE_ADDRESS==Address)
emperord 2:37a61db8b04b 337 {
emperord 2:37a61db8b04b 338 end_address = PAGE0_END_ADDRESS;
emperord 2:37a61db8b04b 339 }
emperord 2:37a61db8b04b 340 else
emperord 2:37a61db8b04b 341 {
emperord 2:37a61db8b04b 342 end_address = PAGE1_END_ADDRESS;
emperord 2:37a61db8b04b 343 };
emperord 2:37a61db8b04b 344
emperord 2:37a61db8b04b 345
emperord 2:37a61db8b04b 346 /* Check each active page address starting from end */
emperord 2:37a61db8b04b 347 while (Address <= end_address)
emperord 2:37a61db8b04b 348 {
emperord 2:37a61db8b04b 349 /* Get the current location content to be compared with virtual address */
emperord 2:37a61db8b04b 350 addressvalue = (*(__IO uint16_t*)Address);
emperord 2:37a61db8b04b 351
emperord 2:37a61db8b04b 352 /* Compare the read address with the virtual address */
emperord 2:37a61db8b04b 353 if (addressvalue != ERASED)
emperord 2:37a61db8b04b 354 {
emperord 2:37a61db8b04b 355
emperord 2:37a61db8b04b 356 /* In case variable value is read, reset readstatus flag */
emperord 2:37a61db8b04b 357 readstatus = 0;
emperord 2:37a61db8b04b 358
emperord 2:37a61db8b04b 359 break;
emperord 2:37a61db8b04b 360 }
emperord 2:37a61db8b04b 361 /* Next address location */
emperord 2:37a61db8b04b 362 Address = Address + 4;
emperord 2:37a61db8b04b 363 }
emperord 2:37a61db8b04b 364
emperord 2:37a61db8b04b 365 /* Return readstatus value: (0: Page not erased, 1: Page erased) */
emperord 2:37a61db8b04b 366 return readstatus;
emperord 2:37a61db8b04b 367 }
emperord 2:37a61db8b04b 368
emperord 2:37a61db8b04b 369 /**
emperord 2:37a61db8b04b 370 * @brief Returns the last stored variable data, if found, which correspond to
emperord 2:37a61db8b04b 371 * the passed virtual address
emperord 2:37a61db8b04b 372 * @param VirtAddress: Variable virtual address
emperord 2:37a61db8b04b 373 * @param Data: Global variable contains the read variable value
emperord 2:37a61db8b04b 374 * @retval Success or error status:
emperord 2:37a61db8b04b 375 * - 0: if variable was found
emperord 2:37a61db8b04b 376 * - 1: if the variable was not found
emperord 2:37a61db8b04b 377 * - NO_VALID_PAGE: if no valid page was found.
emperord 2:37a61db8b04b 378 */
emperord 2:37a61db8b04b 379 uint16_t EE_ReadVariable(uint16_t VirtAddress, uint16_t* Data)
emperord 2:37a61db8b04b 380 {
emperord 2:37a61db8b04b 381 uint16_t ValidPage = PAGE0;
emperord 2:37a61db8b04b 382 uint16_t AddressValue = 0x5555, ReadStatus = 1;
emperord 2:37a61db8b04b 383 uint32_t Address = EEPROM_START_ADDRESS, PageStartAddress = EEPROM_START_ADDRESS;
emperord 2:37a61db8b04b 384
emperord 2:37a61db8b04b 385 /* Get active Page for read operation */
emperord 2:37a61db8b04b 386 ValidPage = EE_FindValidPage(READ_FROM_VALID_PAGE);
emperord 2:37a61db8b04b 387
emperord 2:37a61db8b04b 388 /* Check if there is no valid page */
emperord 2:37a61db8b04b 389 if (ValidPage == NO_VALID_PAGE)
emperord 2:37a61db8b04b 390 {
emperord 2:37a61db8b04b 391 return NO_VALID_PAGE;
emperord 2:37a61db8b04b 392 }
emperord 2:37a61db8b04b 393
emperord 2:37a61db8b04b 394 /* Get the valid Page start Address */
emperord 2:37a61db8b04b 395 PageStartAddress = (uint32_t)(EEPROM_START_ADDRESS + (uint32_t)(ValidPage * PAGE_SIZE));
emperord 2:37a61db8b04b 396
emperord 2:37a61db8b04b 397 /* Get the valid Page end Address */
emperord 2:37a61db8b04b 398 Address = (uint32_t)((EEPROM_START_ADDRESS - 2) + (uint32_t)((1 + ValidPage) * PAGE_SIZE));
emperord 2:37a61db8b04b 399
emperord 2:37a61db8b04b 400 /* Check each active page address starting from end */
emperord 2:37a61db8b04b 401 while (Address > (PageStartAddress + 2))
emperord 2:37a61db8b04b 402 {
emperord 2:37a61db8b04b 403 /* Get the current location content to be compared with virtual address */
emperord 2:37a61db8b04b 404 AddressValue = (*(__IO uint16_t*)Address);
emperord 2:37a61db8b04b 405
emperord 2:37a61db8b04b 406 /* Compare the read address with the virtual address */
emperord 2:37a61db8b04b 407 if (AddressValue == VirtAddress)
emperord 2:37a61db8b04b 408 {
emperord 2:37a61db8b04b 409 /* Get content of Address-2 which is variable value */
emperord 2:37a61db8b04b 410 *Data = (*(__IO uint16_t*)(Address - 2));
emperord 2:37a61db8b04b 411
emperord 2:37a61db8b04b 412 /* In case variable value is read, reset ReadStatus flag */
emperord 2:37a61db8b04b 413 ReadStatus = 0;
emperord 2:37a61db8b04b 414
emperord 2:37a61db8b04b 415 break;
emperord 2:37a61db8b04b 416 }
emperord 2:37a61db8b04b 417 else
emperord 2:37a61db8b04b 418 {
emperord 2:37a61db8b04b 419 /* Next address location */
emperord 2:37a61db8b04b 420 Address = Address - 4;
emperord 2:37a61db8b04b 421 }
emperord 2:37a61db8b04b 422 }
emperord 2:37a61db8b04b 423
emperord 2:37a61db8b04b 424 /* Return ReadStatus value: (0: variable exist, 1: variable doesn't exist) */
emperord 2:37a61db8b04b 425 return ReadStatus;
emperord 2:37a61db8b04b 426 }
emperord 2:37a61db8b04b 427
emperord 2:37a61db8b04b 428 /**
emperord 2:37a61db8b04b 429 * @brief Writes/upadtes variable data in EEPROM.
emperord 2:37a61db8b04b 430 * @param VirtAddress: Variable virtual address
emperord 2:37a61db8b04b 431 * @param Data: 16 bit data to be written
emperord 2:37a61db8b04b 432 * @retval Success or error status:
emperord 2:37a61db8b04b 433 * - FLASH_COMPLETE: on success
emperord 2:37a61db8b04b 434 * - PAGE_FULL: if valid page is full
emperord 2:37a61db8b04b 435 * - NO_VALID_PAGE: if no valid page was found
emperord 2:37a61db8b04b 436 * - Flash error code: on write Flash error
emperord 2:37a61db8b04b 437 */
emperord 2:37a61db8b04b 438 uint16_t EE_WriteVariable(uint16_t VirtAddress, uint16_t Data)
emperord 2:37a61db8b04b 439 {
emperord 2:37a61db8b04b 440 uint16_t Status = 0;
emperord 2:37a61db8b04b 441
emperord 2:37a61db8b04b 442 /* Write the variable virtual address and value in the EEPROM */
emperord 2:37a61db8b04b 443 Status = EE_VerifyPageFullWriteVariable(VirtAddress, Data);
emperord 2:37a61db8b04b 444
emperord 2:37a61db8b04b 445 /* In case the EEPROM active page is full */
emperord 2:37a61db8b04b 446 if (Status == PAGE_FULL)
emperord 2:37a61db8b04b 447 {
emperord 2:37a61db8b04b 448 /* Perform Page transfer */
emperord 2:37a61db8b04b 449 Status = EE_PageTransfer(VirtAddress, Data);
emperord 2:37a61db8b04b 450 }
emperord 2:37a61db8b04b 451
emperord 2:37a61db8b04b 452 /* Return last operation status */
emperord 2:37a61db8b04b 453 return Status;
emperord 2:37a61db8b04b 454 }
emperord 2:37a61db8b04b 455
emperord 2:37a61db8b04b 456 /**
emperord 2:37a61db8b04b 457 * @brief Erases PAGE and PAGE1 and writes VALID_PAGE header to PAGE
emperord 2:37a61db8b04b 458 * @param None
emperord 2:37a61db8b04b 459 * @retval Status of the last operation (Flash write or erase) done during
emperord 2:37a61db8b04b 460 * EEPROM formating
emperord 2:37a61db8b04b 461 */
emperord 2:37a61db8b04b 462 static HAL_StatusTypeDef EE_Format(void)
emperord 2:37a61db8b04b 463 {
emperord 2:37a61db8b04b 464 HAL_StatusTypeDef FlashStatus = HAL_OK;
emperord 2:37a61db8b04b 465 uint32_t SectorError = 0;
emperord 2:37a61db8b04b 466 FLASH_EraseInitTypeDef pEraseInit;
emperord 2:37a61db8b04b 467
emperord 2:37a61db8b04b 468 pEraseInit.TypeErase = FLASH_TYPEERASE_SECTORS;
emperord 2:37a61db8b04b 469 pEraseInit.Sector = PAGE0_ID;
emperord 2:37a61db8b04b 470 pEraseInit.NbSectors = 1;
emperord 2:37a61db8b04b 471 pEraseInit.VoltageRange = VOLTAGE_RANGE;
emperord 2:37a61db8b04b 472 /* Erase Page0 */
emperord 2:37a61db8b04b 473 if(!EE_VerifyPageFullyErased(PAGE0_BASE_ADDRESS))
emperord 2:37a61db8b04b 474 {
emperord 2:37a61db8b04b 475 FlashStatus = HAL_FLASHEx_Erase(&pEraseInit, &SectorError);
emperord 2:37a61db8b04b 476 /* If erase operation was failed, a Flash error code is returned */
emperord 2:37a61db8b04b 477 if (FlashStatus != HAL_OK)
emperord 2:37a61db8b04b 478 {
emperord 2:37a61db8b04b 479 return FlashStatus;
emperord 2:37a61db8b04b 480 }
emperord 2:37a61db8b04b 481 }
emperord 2:37a61db8b04b 482 /* Set Page0 as valid page: Write VALID_PAGE at Page0 base address */
emperord 2:37a61db8b04b 483 FlashStatus = HAL_FLASH_Program(TYPEPROGRAM_HALFWORD, PAGE0_BASE_ADDRESS, VALID_PAGE);
emperord 2:37a61db8b04b 484 /* If program operation was failed, a Flash error code is returned */
emperord 2:37a61db8b04b 485 if (FlashStatus != HAL_OK)
emperord 2:37a61db8b04b 486 {
emperord 2:37a61db8b04b 487 return FlashStatus;
emperord 2:37a61db8b04b 488 }
emperord 2:37a61db8b04b 489
emperord 2:37a61db8b04b 490 pEraseInit.Sector = PAGE1_ID;
emperord 2:37a61db8b04b 491 /* Erase Page1 */
emperord 2:37a61db8b04b 492 if(!EE_VerifyPageFullyErased(PAGE1_BASE_ADDRESS))
emperord 2:37a61db8b04b 493 {
emperord 2:37a61db8b04b 494 FlashStatus = HAL_FLASHEx_Erase(&pEraseInit, &SectorError);
emperord 2:37a61db8b04b 495 /* If erase operation was failed, a Flash error code is returned */
emperord 2:37a61db8b04b 496 if (FlashStatus != HAL_OK)
emperord 2:37a61db8b04b 497 {
emperord 2:37a61db8b04b 498 return FlashStatus;
emperord 2:37a61db8b04b 499 }
emperord 2:37a61db8b04b 500 }
emperord 2:37a61db8b04b 501
emperord 2:37a61db8b04b 502 return HAL_OK;
emperord 2:37a61db8b04b 503 }
emperord 2:37a61db8b04b 504
emperord 2:37a61db8b04b 505 /**
emperord 2:37a61db8b04b 506 * @brief Find valid Page for write or read operation
emperord 2:37a61db8b04b 507 * @param Operation: operation to achieve on the valid page.
emperord 2:37a61db8b04b 508 * This parameter can be one of the following values:
emperord 2:37a61db8b04b 509 * @arg READ_FROM_VALID_PAGE: read operation from valid page
emperord 2:37a61db8b04b 510 * @arg WRITE_IN_VALID_PAGE: write operation from valid page
emperord 2:37a61db8b04b 511 * @retval Valid page number (PAGE or PAGE1) or NO_VALID_PAGE in case
emperord 2:37a61db8b04b 512 * of no valid page was found
emperord 2:37a61db8b04b 513 */
emperord 2:37a61db8b04b 514 static uint16_t EE_FindValidPage(uint8_t Operation)
emperord 2:37a61db8b04b 515 {
emperord 2:37a61db8b04b 516 uint16_t PageStatus0 = 6, PageStatus1 = 6;
emperord 2:37a61db8b04b 517
emperord 2:37a61db8b04b 518 /* Get Page0 actual status */
emperord 2:37a61db8b04b 519 PageStatus0 = (*(__IO uint16_t*)PAGE0_BASE_ADDRESS);
emperord 2:37a61db8b04b 520
emperord 2:37a61db8b04b 521 /* Get Page1 actual status */
emperord 2:37a61db8b04b 522 PageStatus1 = (*(__IO uint16_t*)PAGE1_BASE_ADDRESS);
emperord 2:37a61db8b04b 523
emperord 2:37a61db8b04b 524 /* Write or read operation */
emperord 2:37a61db8b04b 525 switch (Operation)
emperord 2:37a61db8b04b 526 {
emperord 2:37a61db8b04b 527 case WRITE_IN_VALID_PAGE: /* ---- Write operation ---- */
emperord 2:37a61db8b04b 528 if (PageStatus1 == VALID_PAGE)
emperord 2:37a61db8b04b 529 {
emperord 2:37a61db8b04b 530 /* Page0 receiving data */
emperord 2:37a61db8b04b 531 if (PageStatus0 == RECEIVE_DATA)
emperord 2:37a61db8b04b 532 {
emperord 2:37a61db8b04b 533 return PAGE0; /* Page0 valid */
emperord 2:37a61db8b04b 534 }
emperord 2:37a61db8b04b 535 else
emperord 2:37a61db8b04b 536 {
emperord 2:37a61db8b04b 537 return PAGE1; /* Page1 valid */
emperord 2:37a61db8b04b 538 }
emperord 2:37a61db8b04b 539 }
emperord 2:37a61db8b04b 540 else if (PageStatus0 == VALID_PAGE)
emperord 2:37a61db8b04b 541 {
emperord 2:37a61db8b04b 542 /* Page1 receiving data */
emperord 2:37a61db8b04b 543 if (PageStatus1 == RECEIVE_DATA)
emperord 2:37a61db8b04b 544 {
emperord 2:37a61db8b04b 545 return PAGE1; /* Page1 valid */
emperord 2:37a61db8b04b 546 }
emperord 2:37a61db8b04b 547 else
emperord 2:37a61db8b04b 548 {
emperord 2:37a61db8b04b 549 return PAGE0; /* Page0 valid */
emperord 2:37a61db8b04b 550 }
emperord 2:37a61db8b04b 551 }
emperord 2:37a61db8b04b 552 else
emperord 2:37a61db8b04b 553 {
emperord 2:37a61db8b04b 554 return NO_VALID_PAGE; /* No valid Page */
emperord 2:37a61db8b04b 555 }
emperord 2:37a61db8b04b 556
emperord 2:37a61db8b04b 557 case READ_FROM_VALID_PAGE: /* ---- Read operation ---- */
emperord 2:37a61db8b04b 558 if (PageStatus0 == VALID_PAGE)
emperord 2:37a61db8b04b 559 {
emperord 2:37a61db8b04b 560 return PAGE0; /* Page0 valid */
emperord 2:37a61db8b04b 561 }
emperord 2:37a61db8b04b 562 else if (PageStatus1 == VALID_PAGE)
emperord 2:37a61db8b04b 563 {
emperord 2:37a61db8b04b 564 return PAGE1; /* Page1 valid */
emperord 2:37a61db8b04b 565 }
emperord 2:37a61db8b04b 566 else
emperord 2:37a61db8b04b 567 {
emperord 2:37a61db8b04b 568 return NO_VALID_PAGE ; /* No valid Page */
emperord 2:37a61db8b04b 569 }
emperord 2:37a61db8b04b 570
emperord 2:37a61db8b04b 571 default:
emperord 2:37a61db8b04b 572 return PAGE0; /* Page0 valid */
emperord 2:37a61db8b04b 573 }
emperord 2:37a61db8b04b 574 }
emperord 2:37a61db8b04b 575
emperord 2:37a61db8b04b 576 /**
emperord 2:37a61db8b04b 577 * @brief Verify if active page is full and Writes variable in EEPROM.
emperord 2:37a61db8b04b 578 * @param VirtAddress: 16 bit virtual address of the variable
emperord 2:37a61db8b04b 579 * @param Data: 16 bit data to be written as variable value
emperord 2:37a61db8b04b 580 * @retval Success or error status:
emperord 2:37a61db8b04b 581 * - FLASH_COMPLETE: on success
emperord 2:37a61db8b04b 582 * - PAGE_FULL: if valid page is full
emperord 2:37a61db8b04b 583 * - NO_VALID_PAGE: if no valid page was found
emperord 2:37a61db8b04b 584 * - Flash error code: on write Flash error
emperord 2:37a61db8b04b 585 */
emperord 2:37a61db8b04b 586 static uint16_t EE_VerifyPageFullWriteVariable(uint16_t VirtAddress, uint16_t Data)
emperord 2:37a61db8b04b 587 {
emperord 2:37a61db8b04b 588 HAL_StatusTypeDef FlashStatus = HAL_OK;
emperord 2:37a61db8b04b 589 uint16_t ValidPage = PAGE0;
emperord 2:37a61db8b04b 590 uint32_t Address = EEPROM_START_ADDRESS, PageEndAddress = EEPROM_START_ADDRESS+PAGE_SIZE;
emperord 2:37a61db8b04b 591
emperord 2:37a61db8b04b 592 /* Get valid Page for write operation */
emperord 2:37a61db8b04b 593 ValidPage = EE_FindValidPage(WRITE_IN_VALID_PAGE);
emperord 2:37a61db8b04b 594
emperord 2:37a61db8b04b 595 /* Check if there is no valid page */
emperord 2:37a61db8b04b 596 if (ValidPage == NO_VALID_PAGE)
emperord 2:37a61db8b04b 597 {
emperord 2:37a61db8b04b 598 return NO_VALID_PAGE;
emperord 2:37a61db8b04b 599 }
emperord 2:37a61db8b04b 600
emperord 2:37a61db8b04b 601 /* Get the valid Page start Address */
emperord 2:37a61db8b04b 602 Address = (uint32_t)(EEPROM_START_ADDRESS + (uint32_t)(ValidPage * PAGE_SIZE));
emperord 2:37a61db8b04b 603
emperord 2:37a61db8b04b 604 /* Get the valid Page end Address */
emperord 2:37a61db8b04b 605 PageEndAddress = (uint32_t)((EEPROM_START_ADDRESS - 1) + (uint32_t)((ValidPage + 1) * PAGE_SIZE));
emperord 2:37a61db8b04b 606
emperord 2:37a61db8b04b 607 /* Check each active page address starting from begining */
emperord 2:37a61db8b04b 608 while (Address < PageEndAddress)
emperord 2:37a61db8b04b 609 {
emperord 2:37a61db8b04b 610 /* Verify if Address and Address+2 contents are 0xFFFFFFFF */
emperord 2:37a61db8b04b 611 if ((*(__IO uint32_t*)Address) == 0xFFFFFFFF)
emperord 2:37a61db8b04b 612 {
emperord 2:37a61db8b04b 613 /* Set variable data */
emperord 2:37a61db8b04b 614 FlashStatus = HAL_FLASH_Program(TYPEPROGRAM_HALFWORD, Address, Data);
emperord 2:37a61db8b04b 615 /* If program operation was failed, a Flash error code is returned */
emperord 2:37a61db8b04b 616 if (FlashStatus != HAL_OK)
emperord 2:37a61db8b04b 617 {
emperord 2:37a61db8b04b 618 return FlashStatus;
emperord 2:37a61db8b04b 619 }
emperord 2:37a61db8b04b 620 /* Set variable virtual address */
emperord 2:37a61db8b04b 621 FlashStatus = HAL_FLASH_Program(TYPEPROGRAM_HALFWORD, Address + 2, VirtAddress);
emperord 2:37a61db8b04b 622 /* Return program operation status */
emperord 2:37a61db8b04b 623 return FlashStatus;
emperord 2:37a61db8b04b 624 }
emperord 2:37a61db8b04b 625 else
emperord 2:37a61db8b04b 626 {
emperord 2:37a61db8b04b 627 /* Next address location */
emperord 2:37a61db8b04b 628 Address = Address + 4;
emperord 2:37a61db8b04b 629 }
emperord 2:37a61db8b04b 630 }
emperord 2:37a61db8b04b 631
emperord 2:37a61db8b04b 632 /* Return PAGE_FULL in case the valid page is full */
emperord 2:37a61db8b04b 633 return PAGE_FULL;
emperord 2:37a61db8b04b 634 }
emperord 2:37a61db8b04b 635
emperord 2:37a61db8b04b 636 /**
emperord 2:37a61db8b04b 637 * @brief Transfers last updated variables data from the full Page to
emperord 2:37a61db8b04b 638 * an empty one.
emperord 2:37a61db8b04b 639 * @param VirtAddress: 16 bit virtual address of the variable
emperord 2:37a61db8b04b 640 * @param Data: 16 bit data to be written as variable value
emperord 2:37a61db8b04b 641 * @retval Success or error status:
emperord 2:37a61db8b04b 642 * - FLASH_COMPLETE: on success
emperord 2:37a61db8b04b 643 * - PAGE_FULL: if valid page is full
emperord 2:37a61db8b04b 644 * - NO_VALID_PAGE: if no valid page was found
emperord 2:37a61db8b04b 645 * - Flash error code: on write Flash error
emperord 2:37a61db8b04b 646 */
emperord 2:37a61db8b04b 647 static uint16_t EE_PageTransfer(uint16_t VirtAddress, uint16_t Data)
emperord 2:37a61db8b04b 648 {
emperord 2:37a61db8b04b 649 HAL_StatusTypeDef FlashStatus = HAL_OK;
emperord 2:37a61db8b04b 650 uint32_t NewPageAddress = EEPROM_START_ADDRESS;
emperord 2:37a61db8b04b 651 uint16_t OldPageId=0;
emperord 2:37a61db8b04b 652 uint16_t ValidPage = PAGE0, VarIdx = 0;
emperord 2:37a61db8b04b 653 uint16_t EepromStatus = 0, ReadStatus = 0;
emperord 2:37a61db8b04b 654 uint32_t SectorError = 0;
emperord 2:37a61db8b04b 655 FLASH_EraseInitTypeDef pEraseInit;
emperord 2:37a61db8b04b 656
emperord 2:37a61db8b04b 657 /* Get active Page for read operation */
emperord 2:37a61db8b04b 658 ValidPage = EE_FindValidPage(READ_FROM_VALID_PAGE);
emperord 2:37a61db8b04b 659
emperord 2:37a61db8b04b 660 if (ValidPage == PAGE1) /* Page1 valid */
emperord 2:37a61db8b04b 661 {
emperord 2:37a61db8b04b 662 /* New page address where variable will be moved to */
emperord 2:37a61db8b04b 663 NewPageAddress = PAGE0_BASE_ADDRESS;
emperord 2:37a61db8b04b 664
emperord 2:37a61db8b04b 665 /* Old page ID where variable will be taken from */
emperord 2:37a61db8b04b 666 OldPageId = PAGE1_ID;
emperord 2:37a61db8b04b 667 }
emperord 2:37a61db8b04b 668 else if (ValidPage == PAGE0) /* Page0 valid */
emperord 2:37a61db8b04b 669 {
emperord 2:37a61db8b04b 670 /* New page address where variable will be moved to */
emperord 2:37a61db8b04b 671 NewPageAddress = PAGE1_BASE_ADDRESS;
emperord 2:37a61db8b04b 672
emperord 2:37a61db8b04b 673 /* Old page ID where variable will be taken from */
emperord 2:37a61db8b04b 674 OldPageId = PAGE0_ID;
emperord 2:37a61db8b04b 675 }
emperord 2:37a61db8b04b 676 else
emperord 2:37a61db8b04b 677 {
emperord 2:37a61db8b04b 678 return NO_VALID_PAGE; /* No valid Page */
emperord 2:37a61db8b04b 679 }
emperord 2:37a61db8b04b 680
emperord 2:37a61db8b04b 681 /* Set the new Page status to RECEIVE_DATA status */
emperord 2:37a61db8b04b 682 FlashStatus = HAL_FLASH_Program(TYPEPROGRAM_HALFWORD, NewPageAddress, RECEIVE_DATA);
emperord 2:37a61db8b04b 683 /* If program operation was failed, a Flash error code is returned */
emperord 2:37a61db8b04b 684 if (FlashStatus != HAL_OK)
emperord 2:37a61db8b04b 685 {
emperord 2:37a61db8b04b 686 return FlashStatus;
emperord 2:37a61db8b04b 687 }
emperord 2:37a61db8b04b 688
emperord 2:37a61db8b04b 689 /* Write the variable passed as parameter in the new active page */
emperord 2:37a61db8b04b 690 EepromStatus = EE_VerifyPageFullWriteVariable(VirtAddress, Data);
emperord 2:37a61db8b04b 691 /* If program operation was failed, a Flash error code is returned */
emperord 2:37a61db8b04b 692 if (EepromStatus != HAL_OK)
emperord 2:37a61db8b04b 693 {
emperord 2:37a61db8b04b 694 return EepromStatus;
emperord 2:37a61db8b04b 695 }
emperord 2:37a61db8b04b 696
emperord 2:37a61db8b04b 697 /* Transfer process: transfer variables from old to the new active page */
emperord 2:37a61db8b04b 698 for (VarIdx = 0; VarIdx < NB_OF_VAR; VarIdx++)
emperord 2:37a61db8b04b 699 {
emperord 2:37a61db8b04b 700 if (VirtAddVarTab[VarIdx] != VirtAddress) /* Check each variable except the one passed as parameter */
emperord 2:37a61db8b04b 701 {
emperord 2:37a61db8b04b 702 /* Read the other last variable updates */
emperord 2:37a61db8b04b 703 ReadStatus = EE_ReadVariable(VirtAddVarTab[VarIdx], &DataVar);
emperord 2:37a61db8b04b 704 /* In case variable corresponding to the virtual address was found */
emperord 2:37a61db8b04b 705 if (ReadStatus != 0x1)
emperord 2:37a61db8b04b 706 {
emperord 2:37a61db8b04b 707 /* Transfer the variable to the new active page */
emperord 2:37a61db8b04b 708 EepromStatus = EE_VerifyPageFullWriteVariable(VirtAddVarTab[VarIdx], DataVar);
emperord 2:37a61db8b04b 709 /* If program operation was failed, a Flash error code is returned */
emperord 2:37a61db8b04b 710 if (EepromStatus != HAL_OK)
emperord 2:37a61db8b04b 711 {
emperord 2:37a61db8b04b 712 return EepromStatus;
emperord 2:37a61db8b04b 713 }
emperord 2:37a61db8b04b 714 }
emperord 2:37a61db8b04b 715 }
emperord 2:37a61db8b04b 716 }
emperord 2:37a61db8b04b 717
emperord 2:37a61db8b04b 718 pEraseInit.TypeErase = TYPEERASE_SECTORS;
emperord 2:37a61db8b04b 719 pEraseInit.Sector = OldPageId;
emperord 2:37a61db8b04b 720 pEraseInit.NbSectors = 1;
emperord 2:37a61db8b04b 721 pEraseInit.VoltageRange = VOLTAGE_RANGE;
emperord 2:37a61db8b04b 722
emperord 2:37a61db8b04b 723 /* Erase the old Page: Set old Page status to ERASED status */
emperord 2:37a61db8b04b 724 FlashStatus = HAL_FLASHEx_Erase(&pEraseInit, &SectorError);
emperord 2:37a61db8b04b 725 /* If erase operation was failed, a Flash error code is returned */
emperord 2:37a61db8b04b 726 if (FlashStatus != HAL_OK)
emperord 2:37a61db8b04b 727 {
emperord 2:37a61db8b04b 728 return FlashStatus;
emperord 2:37a61db8b04b 729 }
emperord 2:37a61db8b04b 730
emperord 2:37a61db8b04b 731 /* Set new Page status to VALID_PAGE status */
emperord 2:37a61db8b04b 732 FlashStatus = HAL_FLASH_Program(TYPEPROGRAM_HALFWORD, NewPageAddress, VALID_PAGE);
emperord 2:37a61db8b04b 733 /* If program operation was failed, a Flash error code is returned */
emperord 2:37a61db8b04b 734 if (FlashStatus != HAL_OK)
emperord 2:37a61db8b04b 735 {
emperord 2:37a61db8b04b 736 return FlashStatus;
emperord 2:37a61db8b04b 737 }
emperord 2:37a61db8b04b 738
emperord 2:37a61db8b04b 739 /* Return last operation flash status */
emperord 2:37a61db8b04b 740 return FlashStatus;
emperord 2:37a61db8b04b 741 }
emperord 2:37a61db8b04b 742
emperord 2:37a61db8b04b 743 /**
emperord 2:37a61db8b04b 744 * @}
emperord 2:37a61db8b04b 745 */
emperord 2:37a61db8b04b 746
emperord 2:37a61db8b04b 747 /******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/