EEPROM emulation (STM algorithm described in the application notes: AN4061, AN3969, AN2594, AN3390, AN4056) with added multipage possibility. For Nucleo-F030 and others boards with similar microcontrolers.

Dependencies:   mbed

Description in AN4061 from STM.

Changed (compared with the original code AN4061):

  • possibility of a larger size of emulated EEPROM (using multiple Flash pages)
  • dummy variables prevent overwrite code in Flash by algorithm of EEPROM emulation



Macro PAGE_NB_PVP (in eeprom.h) defines the size of the virtual page. Eg. For F030 where Flash page are 1kB value 4 gives 4kB.

Size 4kB virtual page gives you the ability to use max. approx. 1k of 16-bit variables.

Committer:
mega64
Date:
Sat Sep 24 00:52:55 2016 +0000
Revision:
0:2eda09ff61d0
Added possibility to increase size of virtual pages of emulation

Who changed what in which revision?

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