1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
21
22
25
26
27
28
36
37
38
39
40
41
42
43
44
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
89
90
91
92
101
102
103
104
108
109
119
120
121
122
123
124
125
148
149
150
151
155
156
157
158
159
168
169
170
171
172
173
174
175
184
185
186
187
191
192
202
203
204
205
206
215
216
231
232
233
234
257
258
259
260
264
265
266
267
268
277
278
279
280
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
418
419
420
421
422
423
429
430
431
432
433
434
435
436
437
438
439
440
449
450
451
452
456
457
458
459
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
587
588
589
590
591
592
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
635
636
643
647
648
649
650
651
655
656
657
658
659
663
664
665
684
685
686
687
688
689
690
691
692
693
697
698
699
700
701
705
706
707
708
709
710
/* ... */
/* ... */
#include "eeprom.h"
Includes
uint16_t DataVar = 0;
extern uint16_t VirtAddVarTab[NB_OF_VAR];
Private variables
static HAL_StatusTypeDef EE_Format(void);
static uint16_t EE_FindValidPage(uint8_t Operation);
static uint16_t EE_VerifyPageFullWriteVariable(uint16_t VirtAddress, uint16_t Data);
static uint16_t EE_PageTransfer(uint16_t VirtAddress, uint16_t Data);
static uint16_t EE_VerifyPageFullyErased(uint32_t Address);
/* ... */
uint16_t EE_Init(void)
{
uint16_t PageStatus0 = 6, PageStatus1 = 6;
uint16_t VarIdx = 0;
uint16_t EepromStatus = 0, ReadStatus = 0;
int16_t x = -1;
HAL_StatusTypeDef FlashStatus;
uint32_t SectorError = 0;
FLASH_EraseInitTypeDef pEraseInit;
PageStatus0 = (*(__IO uint16_t*)PAGE0_BASE_ADDRESS);
PageStatus1 = (*(__IO uint16_t*)PAGE1_BASE_ADDRESS);
pEraseInit.TypeErase = TYPEERASE_SECTORS;
pEraseInit.Sector = PAGE0_ID;
pEraseInit.NbSectors = 1;
pEraseInit.VoltageRange = VOLTAGE_RANGE;
switch (PageStatus0)
{
case ERASED:
if (PageStatus1 == VALID_PAGE)
{
if(!EE_VerifyPageFullyErased(PAGE0_BASE_ADDRESS))
{
FlashStatus = HAL_FLASHEx_Erase(&pEraseInit, &SectorError);
if (FlashStatus != HAL_OK)
{
return FlashStatus;
}if (FlashStatus != HAL_OK) { ... }
}if (!EE_VerifyPageFullyErased(PAGE0_BASE_ADDRESS)) { ... }
...}
else if (PageStatus1 == RECEIVE_DATA)
{
if(!EE_VerifyPageFullyErased(PAGE0_BASE_ADDRESS))
{
FlashStatus = HAL_FLASHEx_Erase(&pEraseInit, &SectorError);
if (FlashStatus != HAL_OK)
{
return FlashStatus;
}if (FlashStatus != HAL_OK) { ... }
}if (!EE_VerifyPageFullyErased(PAGE0_BASE_ADDRESS)) { ... }
FlashStatus = HAL_FLASH_Program(TYPEPROGRAM_HALFWORD, PAGE1_BASE_ADDRESS, VALID_PAGE);
if (FlashStatus != HAL_OK)
{
return FlashStatus;
}if (FlashStatus != HAL_OK) { ... }
...}
else
{
FlashStatus = EE_Format();
if (FlashStatus != HAL_OK)
{
return FlashStatus;
}if (FlashStatus != HAL_OK) { ... }
}else { ... }
break;
case ERASED:
case RECEIVE_DATA:
if (PageStatus1 == VALID_PAGE)
{
for (VarIdx = 0; VarIdx < NB_OF_VAR; VarIdx++)
{
if (( *(__IO uint16_t*)(PAGE0_BASE_ADDRESS + 6)) == VirtAddVarTab[VarIdx])
{
x = VarIdx;
}if (( *(__IO uint16_t*)(PAGE0_BASE_ADDRESS + 6)) == VirtAddVarTab[VarIdx]) { ... }
if (VarIdx != x)
{
ReadStatus = EE_ReadVariable(VirtAddVarTab[VarIdx], &DataVar);
if (ReadStatus != 0x1)
{
EepromStatus = EE_VerifyPageFullWriteVariable(VirtAddVarTab[VarIdx], DataVar);
if (EepromStatus != HAL_OK)
{
return EepromStatus;
}if (EepromStatus != HAL_OK) { ... }
}if (ReadStatus != 0x1) { ... }
}if (VarIdx != x) { ... }
}for (VarIdx = 0; VarIdx < NB_OF_VAR; VarIdx++) { ... }
FlashStatus = HAL_FLASH_Program(TYPEPROGRAM_HALFWORD, PAGE0_BASE_ADDRESS, VALID_PAGE);
if (FlashStatus != HAL_OK)
{
return FlashStatus;
}if (FlashStatus != HAL_OK) { ... }
pEraseInit.Sector = PAGE1_ID;
pEraseInit.NbSectors = 1;
pEraseInit.VoltageRange = VOLTAGE_RANGE;
if(!EE_VerifyPageFullyErased(PAGE1_BASE_ADDRESS))
{
FlashStatus = HAL_FLASHEx_Erase(&pEraseInit, &SectorError);
if (FlashStatus != HAL_OK)
{
return FlashStatus;
}if (FlashStatus != HAL_OK) { ... }
}if (!EE_VerifyPageFullyErased(PAGE1_BASE_ADDRESS)) { ... }
...}
else if (PageStatus1 == ERASED)
{
pEraseInit.Sector = PAGE1_ID;
pEraseInit.NbSectors = 1;
pEraseInit.VoltageRange = VOLTAGE_RANGE;
if(!EE_VerifyPageFullyErased(PAGE1_BASE_ADDRESS))
{
FlashStatus = HAL_FLASHEx_Erase(&pEraseInit, &SectorError);
if (FlashStatus != HAL_OK)
{
return FlashStatus;
}if (FlashStatus != HAL_OK) { ... }
}if (!EE_VerifyPageFullyErased(PAGE1_BASE_ADDRESS)) { ... }
FlashStatus = HAL_FLASH_Program(TYPEPROGRAM_HALFWORD, PAGE0_BASE_ADDRESS, VALID_PAGE);
if (FlashStatus != HAL_OK)
{
return FlashStatus;
}if (FlashStatus != HAL_OK) { ... }
...}
else
{
FlashStatus = EE_Format();
if (FlashStatus != HAL_OK)
{
return FlashStatus;
}if (FlashStatus != HAL_OK) { ... }
}else { ... }
break;
case RECEIVE_DATA:
case VALID_PAGE:
if (PageStatus1 == VALID_PAGE)
{
FlashStatus = EE_Format();
if (FlashStatus != HAL_OK)
{
return FlashStatus;
}if (FlashStatus != HAL_OK) { ... }
...}
else if (PageStatus1 == ERASED)
{
pEraseInit.Sector = PAGE1_ID;
pEraseInit.NbSectors = 1;
pEraseInit.VoltageRange = VOLTAGE_RANGE;
if(!EE_VerifyPageFullyErased(PAGE1_BASE_ADDRESS))
{
FlashStatus = HAL_FLASHEx_Erase(&pEraseInit, &SectorError);
if (FlashStatus != HAL_OK)
{
return FlashStatus;
}if (FlashStatus != HAL_OK) { ... }
}if (!EE_VerifyPageFullyErased(PAGE1_BASE_ADDRESS)) { ... }
...}
else
{
for (VarIdx = 0; VarIdx < NB_OF_VAR; VarIdx++)
{
if ((*(__IO uint16_t*)(PAGE1_BASE_ADDRESS + 6)) == VirtAddVarTab[VarIdx])
{
x = VarIdx;
}if ((*(__IO uint16_t*)(PAGE1_BASE_ADDRESS + 6)) == VirtAddVarTab[VarIdx]) { ... }
if (VarIdx != x)
{
ReadStatus = EE_ReadVariable(VirtAddVarTab[VarIdx], &DataVar);
if (ReadStatus != 0x1)
{
EepromStatus = EE_VerifyPageFullWriteVariable(VirtAddVarTab[VarIdx], DataVar);
if (EepromStatus != HAL_OK)
{
return EepromStatus;
}if (EepromStatus != HAL_OK) { ... }
}if (ReadStatus != 0x1) { ... }
}if (VarIdx != x) { ... }
}for (VarIdx = 0; VarIdx < NB_OF_VAR; VarIdx++) { ... }
FlashStatus = HAL_FLASH_Program(TYPEPROGRAM_HALFWORD, PAGE1_BASE_ADDRESS, VALID_PAGE);
if (FlashStatus != HAL_OK)
{
return FlashStatus;
}if (FlashStatus != HAL_OK) { ... }
pEraseInit.Sector = PAGE0_ID;
pEraseInit.NbSectors = 1;
pEraseInit.VoltageRange = VOLTAGE_RANGE;
if(!EE_VerifyPageFullyErased(PAGE0_BASE_ADDRESS))
{
FlashStatus = HAL_FLASHEx_Erase(&pEraseInit, &SectorError);
if (FlashStatus != HAL_OK)
{
return FlashStatus;
}if (FlashStatus != HAL_OK) { ... }
}if (!EE_VerifyPageFullyErased(PAGE0_BASE_ADDRESS)) { ... }
}else { ... }
break;
case VALID_PAGE:
default:
FlashStatus = EE_Format();
if (FlashStatus != HAL_OK)
{
return FlashStatus;
}if (FlashStatus != HAL_OK) { ... }
break;default
}switch (PageStatus0) { ... }
return HAL_OK;
}{ ... }
/* ... */
uint16_t EE_VerifyPageFullyErased(uint32_t Address)
{
uint32_t EndAddress;
uint32_t ReadStatus = 1;
uint16_t AddressValue = 0x5555;
EndAddress = (uint32_t)(Address + (PAGE_SIZE - 4U));
while (Address <= EndAddress)
{
AddressValue = (*(__IO uint16_t*)Address);
if (AddressValue != ERASED)
{
ReadStatus = 0;
break;
}if (AddressValue != ERASED) { ... }
Address = Address + 4;
}while (Address <= EndAddress) { ... }
return ReadStatus;
}{ ... }
/* ... */
uint16_t EE_ReadVariable(uint16_t VirtAddress, uint16_t* Data)
{
uint16_t ValidPage = PAGE0;
uint16_t AddressValue = 0x5555, ReadStatus = 1;
uint32_t Address = EEPROM_START_ADDRESS, PageStartAddress = EEPROM_START_ADDRESS;
ValidPage = EE_FindValidPage(READ_FROM_VALID_PAGE);
if (ValidPage == NO_VALID_PAGE)
{
return NO_VALID_PAGE;
}if (ValidPage == NO_VALID_PAGE) { ... }
PageStartAddress = (uint32_t)(EEPROM_START_ADDRESS + (uint32_t)(ValidPage * PAGE_SIZE));
Address = (uint32_t)((EEPROM_START_ADDRESS - 2) + (uint32_t)((1 + ValidPage) * PAGE_SIZE));
while (Address > (PageStartAddress + 2))
{
AddressValue = (*(__IO uint16_t*)Address);
if (AddressValue == VirtAddress)
{
*Data = (*(__IO uint16_t*)(Address - 2));
ReadStatus = 0;
break;
}if (AddressValue == VirtAddress) { ... }
else
{
Address = Address - 4;
}else { ... }
}while (Address > (PageStartAddress + 2)) { ... }
return ReadStatus;
}{ ... }
/* ... */
uint16_t EE_WriteVariable(uint16_t VirtAddress, uint16_t Data)
{
uint16_t Status = 0;
Status = EE_VerifyPageFullWriteVariable(VirtAddress, Data);
if (Status == PAGE_FULL)
{
Status = EE_PageTransfer(VirtAddress, Data);
}if (Status == PAGE_FULL) { ... }
return Status;
}{ ... }
/* ... */
static HAL_StatusTypeDef EE_Format(void)
{
HAL_StatusTypeDef FlashStatus = HAL_OK;
uint32_t SectorError = 0;
FLASH_EraseInitTypeDef pEraseInit;
pEraseInit.TypeErase = FLASH_TYPEERASE_SECTORS;
pEraseInit.Sector = PAGE0_ID;
pEraseInit.NbSectors = 1;
pEraseInit.VoltageRange = VOLTAGE_RANGE;
if(!EE_VerifyPageFullyErased(PAGE0_BASE_ADDRESS))
{
FlashStatus = HAL_FLASHEx_Erase(&pEraseInit, &SectorError);
if (FlashStatus != HAL_OK)
{
return FlashStatus;
}if (FlashStatus != HAL_OK) { ... }
}if (!EE_VerifyPageFullyErased(PAGE0_BASE_ADDRESS)) { ... }
FlashStatus = HAL_FLASH_Program(TYPEPROGRAM_HALFWORD, PAGE0_BASE_ADDRESS, VALID_PAGE);
if (FlashStatus != HAL_OK)
{
return FlashStatus;
}if (FlashStatus != HAL_OK) { ... }
pEraseInit.Sector = PAGE1_ID;
if(!EE_VerifyPageFullyErased(PAGE1_BASE_ADDRESS))
{
FlashStatus = HAL_FLASHEx_Erase(&pEraseInit, &SectorError);
if (FlashStatus != HAL_OK)
{
return FlashStatus;
}if (FlashStatus != HAL_OK) { ... }
}if (!EE_VerifyPageFullyErased(PAGE1_BASE_ADDRESS)) { ... }
return HAL_OK;
}{ ... }
/* ... */
static uint16_t EE_FindValidPage(uint8_t Operation)
{
uint16_t PageStatus0 = 6, PageStatus1 = 6;
PageStatus0 = (*(__IO uint16_t*)PAGE0_BASE_ADDRESS);
PageStatus1 = (*(__IO uint16_t*)PAGE1_BASE_ADDRESS);
switch (Operation)
{
case WRITE_IN_VALID_PAGE:
if (PageStatus1 == VALID_PAGE)
{
if (PageStatus0 == RECEIVE_DATA)
{
return PAGE0;
}if (PageStatus0 == RECEIVE_DATA) { ... }
else
{
return PAGE1;
}else { ... }
}if (PageStatus1 == VALID_PAGE) { ... }
else if (PageStatus0 == VALID_PAGE)
{
if (PageStatus1 == RECEIVE_DATA)
{
return PAGE1;
}if (PageStatus1 == RECEIVE_DATA) { ... }
else
{
return PAGE0;
}else { ... }
}else if (PageStatus0 == VALID_PAGE) { ... }
else
{
return NO_VALID_PAGE;
}else { ... }
case WRITE_IN_VALID_PAGE:
case READ_FROM_VALID_PAGE:
if (PageStatus0 == VALID_PAGE)
{
return PAGE0;
}if (PageStatus0 == VALID_PAGE) { ... }
else if (PageStatus1 == VALID_PAGE)
{
return PAGE1;
}else if (PageStatus1 == VALID_PAGE) { ... }
else
{
return NO_VALID_PAGE ;
}else { ... }
case READ_FROM_VALID_PAGE:
default:
return PAGE0; default
}switch (Operation) { ... }
}{ ... }
/* ... */
static uint16_t EE_VerifyPageFullWriteVariable(uint16_t VirtAddress, uint16_t Data)
{
HAL_StatusTypeDef FlashStatus = HAL_OK;
uint16_t ValidPage = PAGE0;
uint32_t Address = EEPROM_START_ADDRESS, PageEndAddress = EEPROM_START_ADDRESS+PAGE_SIZE;
ValidPage = EE_FindValidPage(WRITE_IN_VALID_PAGE);
if (ValidPage == NO_VALID_PAGE)
{
return NO_VALID_PAGE;
}if (ValidPage == NO_VALID_PAGE) { ... }
Address = (uint32_t)(EEPROM_START_ADDRESS + (uint32_t)(ValidPage * PAGE_SIZE));
PageEndAddress = (uint32_t)((EEPROM_START_ADDRESS - 1) + (uint32_t)((ValidPage + 1) * PAGE_SIZE));
while (Address < PageEndAddress)
{
if ((*(__IO uint32_t*)Address) == 0xFFFFFFFF)
{
FlashStatus = HAL_FLASH_Program(TYPEPROGRAM_HALFWORD, Address, Data);
if (FlashStatus != HAL_OK)
{
return FlashStatus;
}if (FlashStatus != HAL_OK) { ... }
FlashStatus = HAL_FLASH_Program(TYPEPROGRAM_HALFWORD, Address + 2, VirtAddress);
return FlashStatus;
}if ((*(__IO uint32_t*)Address) == 0xFFFFFFFF) { ... }
else
{
Address = Address + 4;
}else { ... }
}while (Address < PageEndAddress) { ... }
return PAGE_FULL;
}{ ... }
/* ... */
static uint16_t EE_PageTransfer(uint16_t VirtAddress, uint16_t Data)
{
HAL_StatusTypeDef FlashStatus = HAL_OK;
uint32_t NewPageAddress = EEPROM_START_ADDRESS;
uint16_t OldPageId=0;
uint16_t ValidPage = PAGE0, VarIdx = 0;
uint16_t EepromStatus = 0, ReadStatus = 0;
uint32_t SectorError = 0;
FLASH_EraseInitTypeDef pEraseInit;
ValidPage = EE_FindValidPage(READ_FROM_VALID_PAGE);
if (ValidPage == PAGE1)
{
NewPageAddress = PAGE0_BASE_ADDRESS;
OldPageId = PAGE1_ID;
...}
else if (ValidPage == PAGE0)
{
NewPageAddress = PAGE1_BASE_ADDRESS;
OldPageId = PAGE0_ID;
...}
else
{
return NO_VALID_PAGE;
}else { ... }
FlashStatus = HAL_FLASH_Program(TYPEPROGRAM_HALFWORD, NewPageAddress, RECEIVE_DATA);
if (FlashStatus != HAL_OK)
{
return FlashStatus;
}if (FlashStatus != HAL_OK) { ... }
EepromStatus = EE_VerifyPageFullWriteVariable(VirtAddress, Data);
if (EepromStatus != HAL_OK)
{
return EepromStatus;
}if (EepromStatus != HAL_OK) { ... }
for (VarIdx = 0; VarIdx < NB_OF_VAR; VarIdx++)
{
if (VirtAddVarTab[VarIdx] != VirtAddress)
{
ReadStatus = EE_ReadVariable(VirtAddVarTab[VarIdx], &DataVar);
if (ReadStatus != 0x1)
{
EepromStatus = EE_VerifyPageFullWriteVariable(VirtAddVarTab[VarIdx], DataVar);
if (EepromStatus != HAL_OK)
{
return EepromStatus;
}if (EepromStatus != HAL_OK) { ... }
}if (ReadStatus != 0x1) { ... }
...}
}for (VarIdx = 0; VarIdx < NB_OF_VAR; VarIdx++) { ... }
pEraseInit.TypeErase = TYPEERASE_SECTORS;
pEraseInit.Sector = OldPageId;
pEraseInit.NbSectors = 1;
pEraseInit.VoltageRange = VOLTAGE_RANGE;
FlashStatus = HAL_FLASHEx_Erase(&pEraseInit, &SectorError);
if (FlashStatus != HAL_OK)
{
return FlashStatus;
}if (FlashStatus != HAL_OK) { ... }
FlashStatus = HAL_FLASH_Program(TYPEPROGRAM_HALFWORD, NewPageAddress, VALID_PAGE);
if (FlashStatus != HAL_OK)
{
return FlashStatus;
}if (FlashStatus != HAL_OK) { ... }
return FlashStatus;
}{ ... }
/* ... */