Rev 10 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
| Rev 10 | Rev 23 | ||
|---|---|---|---|
| Line 18... | Line 18... | ||
| 18 | 18 | ||
| 19 | // decided to allocate 2 pages of Flash as NVRAM |
19 | // decided to allocate 2 pages of Flash as NVRAM |
| 20 | #define NVRAM_WORDS (2 * NVRAM_PAGESIZE) |
20 | #define NVRAM_WORDS (2 * NVRAM_PAGESIZE) |
| 21 | 21 | ||
| 22 | // Flash hardware erases to all 0 |
22 | // Flash hardware erases to all 0 |
| 23 | nvram_info_t const HARDWARE_ERASED = {.u16 = (uint16_t)~0U}; |
23 | nvram_info_t const HARDWARE_ERASED = {.word = (uint32_t)0UL}; |
| 24 | // Marked as erased change to all 1 |
24 | // Marked as erased change to all 1 |
| 25 | nvram_info_t const MARKED_ERASED = {.u16 = (uint16_t)0U}; |
25 | nvram_info_t const MARKED_ERASED = {.word = (uint32_t)~0UL}; |
| 26 | 26 | ||
| 27 | // allocate the memory for storing the NVRAM data |
27 | // allocate the memory for storing the NVRAM data |
| 28 | nvram_info_t NVRAM_Base[NVRAM_WORDS] __attribute__((section(".nvram"))) = { [0 ... NVRAM_WORDS-1].u16 = (uint16_t)~0U}; // set by linker |
28 | nvram_info_t NVRAM_Base[NVRAM_WORDS] __attribute__((section(".nvram"))) = { [0 ... NVRAM_WORDS-1].word = (uint32_t)0UL}; // set by linker |
| 29 | 29 | ||
| 30 | static void |
30 | static void |
| 31 | WriteNVRAM(nvram_info_t *Address, nvram_info_t data) |
31 | WriteNVRAM(nvram_info_t *Address, nvram_info_t data) |
| 32 | { |
32 | { |
| 33 | HAL_FLASH_Unlock(); |
33 | HAL_FLASH_Unlock(); |
| 34 | HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, (uint32_t)Address, data.u16); |
34 | HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, (uint32_t)Address, data.word); |
| 35 | HAL_FLASH_Lock(); |
35 | HAL_FLASH_Lock(); |
| 36 | } |
36 | } |
| 37 | 37 | ||
| 38 | static void |
38 | static void |
| 39 | EraseNVRAM(nvram_info_t *Address) |
39 | EraseNVRAM(nvram_info_t *Address) |
| Line 59... | Line 59... | ||
| 59 | int index = (ptr + base) % NVRAM_WORDS; |
59 | int index = (ptr + base) % NVRAM_WORDS; |
| 60 | // erase the entry just found |
60 | // erase the entry just found |
| 61 | if (NVRAM_Base[index].data.tag == data.data.tag) |
61 | if (NVRAM_Base[index].data.tag == data.data.tag) |
| 62 | { |
62 | { |
| 63 | // is this the same data as we are writing ? if so return immediately |
63 | // is this the same data as we are writing ? if so return immediately |
| 64 | if(NVRAM_Base[index].u16 == data.u16) |
64 | if(NVRAM_Base[index].word == data.word) |
| 65 | return 0; |
65 | return 0; |
| 66 | // different data |
66 | // different data |
| 67 | // erase previous data |
67 | // erase previous data |
| 68 | WriteNVRAM(&NVRAM_Base[index], MARKED_ERASED); |
68 | WriteNVRAM(&NVRAM_Base[index], MARKED_ERASED); |
| 69 | base = index+1; // look at next element |
69 | base = index+1; // look at next element |
| Line 73... | Line 73... | ||
| 73 | // search forward for next hardware erased element, use it |
73 | // search forward for next hardware erased element, use it |
| 74 | for (int offset = 0; offset < NVRAM_WORDS; offset++) |
74 | for (int offset = 0; offset < NVRAM_WORDS; offset++) |
| 75 | { |
75 | { |
| 76 | int index = (base + offset) % NVRAM_WORDS; |
76 | int index = (base + offset) % NVRAM_WORDS; |
| 77 | 77 | ||
| 78 | if (NVRAM_Base[index].u16 == HARDWARE_ERASED.u16) |
78 | if (NVRAM_Base[index].word == HARDWARE_ERASED.word) |
| 79 | { |
79 | { |
| 80 | // if we cross a page by incrementing into it need action |
80 | // if we cross a page by incrementing into it need action |
| 81 | if (index % NVRAM_PAGESIZE == 0) |
81 | if (index % NVRAM_PAGESIZE == 0) |
| 82 | pageCrossed = 1; |
82 | pageCrossed = 1; |
| 83 | 83 | ||
| 84 | WriteNVRAM(&NVRAM_Base[index], data); |
84 | WriteNVRAM(&NVRAM_Base[index], data); |
| 85 | // now check to see if it actually wrote correctly |
85 | // now check to see if it actually wrote correctly |
| 86 | if (NVRAM_Base[index].u16 != data.u16) |
86 | if (NVRAM_Base[index].word != data.word) |
| 87 | { |
87 | { |
| 88 | WriteNVRAM(&NVRAM_Base[index], MARKED_ERASED); // Set to all erased if the data did not write properly |
88 | WriteNVRAM(&NVRAM_Base[index], MARKED_ERASED); // Set to all erased if the data did not write properly |
| 89 | continue; |
89 | continue; |
| 90 | } |
90 | } |
| 91 | // record where the data was written |
91 | // record where the data was written |
| Line 107... | Line 107... | ||
| 107 | // Now have the index pointing into the page where we need to copy the data to |
107 | // Now have the index pointing into the page where we need to copy the data to |
| 108 | // for any data in the other page, copy it to the new page |
108 | // for any data in the other page, copy it to the new page |
| 109 | int oldPageBase = index >= NVRAM_PAGESIZE ? 0 : NVRAM_PAGESIZE; |
109 | int oldPageBase = index >= NVRAM_PAGESIZE ? 0 : NVRAM_PAGESIZE; |
| 110 | for (int i = oldPageBase; i < oldPageBase + NVRAM_WORDS; i++) |
110 | for (int i = oldPageBase; i < oldPageBase + NVRAM_WORDS; i++) |
| 111 | { |
111 | { |
| 112 | if (NVRAM_Base[i].u16 != HARDWARE_ERASED.u16 && NVRAM_Base[i].u16 != MARKED_ERASED.u16) |
112 | if (NVRAM_Base[i].word != HARDWARE_ERASED.word && NVRAM_Base[i].word != MARKED_ERASED.word) |
| 113 | { |
113 | { |
| 114 | int base = i; |
114 | int base = i; |
| 115 | // copy data forwards |
115 | // copy data forwards |
| 116 | _write_nvram_data(NVRAM_Base[i], &base); |
116 | _write_nvram_data(NVRAM_Base[i], &base); |
| 117 | } |
117 | } |