EEPROM EMULATION STM32F429 - MBED

Dependents:   DISCO-F429ZI_LCDTS_RET15-01

Committer:
Gabriel_2112
Date:
Fri Sep 21 11:27:40 2018 +0000
Revision:
0:9599d2d2296a
LENGTH FLASH

Who changed what in which revision?

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