200117StepMotorControl

Dependencies:   X_NUCLEO_IHM02A1 TextLCD

Committer:
danjecsr
Date:
Thu Jan 16 06:27:47 2020 +0000
Revision:
28:ed18e436f437
1st(2020.01.16)

Who changed what in which revision?

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