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 | } |