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