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