Rev 79 | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
66 | mjames | 1 | /* |
2 | * nvram.c |
||
3 | * |
||
4 | * Created on: 4 Jun 2017 |
||
5 | * Author: Mike |
||
6 | */ |
||
7 | |||
8 | /* Includes ------------------------------------------------------------------*/ |
||
9 | #include "stm32l1xx_hal.h" |
||
10 | |||
11 | #include "nvram.h" |
||
12 | |||
13 | // NVRAM hardware erases to all 0x |
||
14 | nvram_info_t const HARDWARE_ERASED = {.u32 = 0UL}; |
||
15 | // Marked as erased change to all 1 |
||
16 | nvram_info_t const MARKED_ERASED = {.u32 = ~0UL}; |
||
17 | // marked as unusable change pattern to something in between |
||
80 | mjames | 18 | nvram_info_t const MARKED_UNUSABLE = {.u32 = 0x555555FFUL}; |
66 | mjames | 19 | |
20 | nvram_info_t NVRAM_Base[NVRAM_WORDS] __attribute__((section(".NVRAM_Data"))); // set by linker |
||
21 | |||
22 | static void |
||
80 | mjames | 23 | WriteNVRAM(int offset, nvram_info_t data) |
66 | mjames | 24 | { |
25 | HAL_FLASHEx_DATAEEPROM_Unlock(); |
||
80 | mjames | 26 | HAL_FLASHEx_DATAEEPROM_Program(FLASH_TYPEPROGRAMDATA_WORD, (uint32_t)(&NVRAM_Base[offset]), data.u32); |
66 | mjames | 27 | HAL_FLASHEx_DATAEEPROM_Lock(); |
28 | } |
||
29 | |||
30 | static void |
||
80 | mjames | 31 | EraseNVRAM(int offset) |
66 | mjames | 32 | { |
33 | HAL_FLASHEx_DATAEEPROM_Unlock(); |
||
80 | mjames | 34 | HAL_FLASHEx_DATAEEPROM_Erase(FLASH_TYPEERASEDATA_WORD, (uint32_t)(&NVRAM_Base[offset])); |
66 | mjames | 35 | HAL_FLASHEx_DATAEEPROM_Lock(); |
36 | } |
||
37 | |||
38 | void write_nvram_data(nvram_info_t data) |
||
39 | { |
||
80 | mjames | 40 | #if defined SEMIHOSTING |
41 | printf("write\n"); |
||
42 | #endif |
||
43 | |||
66 | mjames | 44 | int base = 0; |
45 | |||
46 | /* search blank */ |
||
47 | for (int ptr = 0; ptr < NVRAM_WORDS; ptr++) |
||
48 | { |
||
49 | // erase the entry just found |
||
50 | if (NVRAM_Base[ptr].data.tag == data.data.tag) |
||
51 | { |
||
79 | mjames | 52 | // erase previous data, delete any entries that have a matching tag |
80 | mjames | 53 | #if defined SEMIHOSTING |
54 | printf("marked erased %d\n", ptr); |
||
55 | #endif |
||
56 | WriteNVRAM(ptr, MARKED_ERASED); |
||
57 | |||
58 | base = ptr; |
||
66 | mjames | 59 | } |
60 | } |
||
80 | mjames | 61 | |
66 | mjames | 62 | // search forward for next erased or empty element, use it |
63 | for (int offset = 1; offset < NVRAM_WORDS + 1; offset++) |
||
64 | { |
||
65 | int index = (base + offset) % NVRAM_WORDS; |
||
66 | if (NVRAM_Base[index].u32 == MARKED_ERASED.u32 || NVRAM_Base[index].u32 == HARDWARE_ERASED.u32) |
||
67 | { |
||
68 | if (NVRAM_Base[index].u32 != HARDWARE_ERASED.u32) |
||
80 | mjames | 69 | { |
70 | #if defined SEMIHOSTING |
||
71 | printf("erase %d\n", index); |
||
72 | #endif |
||
73 | |||
74 | EraseNVRAM(index); |
||
75 | } |
||
76 | #if defined SEMIHOSTING |
||
77 | printf("write %d=%d\n", index, data.data.pos); |
||
78 | #endif |
||
79 | WriteNVRAM(index, data); |
||
66 | mjames | 80 | // now check to see if it actually went |
81 | if (NVRAM_Base[index].u32 != data.u32) |
||
82 | { |
||
80 | mjames | 83 | #if defined SEMIHOSTING |
84 | printf("unusable %d\n", index); |
||
85 | #endif |
||
86 | WriteNVRAM(index, MARKED_UNUSABLE); // mark as neither unused or used |
||
66 | mjames | 87 | continue; |
88 | } |
||
89 | return; |
||
90 | } |
||
91 | } |
||
92 | } |
||
93 | |||
94 | nvram_info_t *find_nvram_data(uint8_t searchTag) |
||
80 | mjames | 95 | { |
96 | #if defined SEMIHOSTING |
||
97 | printf("find\n"); |
||
98 | #endif |
||
66 | mjames | 99 | for (int ptr = 0; ptr < NVRAM_WORDS; ptr++) |
100 | { |
||
101 | if (NVRAM_Base[ptr].data.tag == searchTag) |
||
80 | mjames | 102 | { |
103 | #if defined SEMIHOSTING |
||
104 | printf("found %d=%d\n", ptr, NVRAM_Base[ptr].data.pos); |
||
105 | #endif |
||
66 | mjames | 106 | return &NVRAM_Base[ptr]; |
80 | mjames | 107 | } |
66 | mjames | 108 | } |
109 | return NULL; |
||
110 | } |
||
70 | mjames | 111 | |
112 | void erase_nvram() |
||
113 | { |
||
80 | mjames | 114 | #if defined SEMIHOSTING |
115 | printf("erase all\n"); |
||
116 | #endif |
||
70 | mjames | 117 | for (int ptr = 0; ptr < NVRAM_WORDS; ptr++) |
80 | mjames | 118 | EraseNVRAM(ptr); |
70 | mjames | 119 | } |