Rev 9 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 9 | Rev 10 | ||
---|---|---|---|
Line 17... | Line 17... | ||
17 | #define NVRAM_PAGESIZE (1024 / sizeof(nvram_info_t)) |
17 | #define NVRAM_PAGESIZE (1024 / sizeof(nvram_info_t)) |
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 | // NVRAM hardware erases to all 0x |
22 | // Flash hardware erases to all 0 |
23 | nvram_info_t const HARDWARE_ERASED = {.u16 = 0UL}; |
23 | nvram_info_t const HARDWARE_ERASED = {.u16 = (uint16_t)~0U}; |
24 | // Marked as erased change to all 1 |
24 | // Marked as erased change to all 1 |
25 | nvram_info_t const MARKED_ERASED = {.u16 = ~0UL}; |
25 | nvram_info_t const MARKED_ERASED = {.u16 = (uint16_t)0U}; |
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"))); // set by linker |
28 | nvram_info_t NVRAM_Base[NVRAM_WORDS] __attribute__((section(".nvram"))) = { [0 ... NVRAM_WORDS-1].u16 = (uint16_t)~0U}; // 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(); |
Line 36... | Line 36... | ||
36 | } |
36 | } |
37 | 37 | ||
38 | static void |
38 | static void |
39 | EraseNVRAM(nvram_info_t *Address) |
39 | EraseNVRAM(nvram_info_t *Address) |
40 | { |
40 | { |
41 | FLASH_EraseInitTypeDef erase = {.TypeErase = FLASH_TYPEERASE_PAGES, .PageAddress = Address, .NbPages = 1}; |
41 | FLASH_EraseInitTypeDef erase = {.TypeErase = FLASH_TYPEERASE_PAGES, .PageAddress = (uint32_t)Address, .NbPages = 1}; |
42 | uint32_t err; |
42 | uint32_t err; |
43 | HAL_FLASH_Unlock(); |
43 | HAL_FLASH_Unlock(); |
44 | HAL_FLASHEx_Erase(&erase, &err); |
44 | HAL_FLASHEx_Erase(&erase, &err); |
45 | HAL_FLASH_Lock(); |
45 | HAL_FLASH_Lock(); |
46 | } |
46 | } |
Line 51... | Line 51... | ||
51 | static uint8_t _write_nvram_data(nvram_info_t data, int *pIndex) |
51 | static uint8_t _write_nvram_data(nvram_info_t data, int *pIndex) |
52 | { |
52 | { |
53 | int base = *pIndex; |
53 | int base = *pIndex; |
54 | uint8_t pageCrossed = 0; |
54 | uint8_t pageCrossed = 0; |
55 | 55 | ||
56 | /* search blank */ |
56 | // search for correct data |
57 | for (int ptr = 0; ptr < NVRAM_WORDS; ptr++) |
57 | for (int ptr = 0; ptr < NVRAM_WORDS; ptr++) |
58 | { |
58 | { |
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 |
|
- | 64 | if(NVRAM_Base[index].u16 == data.u16) |
|
- | 65 | return 0; |
|
- | 66 | // different data |
|
63 | // erase previous data |
67 | // erase previous data |
64 | WriteNVRAM(&NVRAM_Base[index], MARKED_ERASED); |
68 | WriteNVRAM(&NVRAM_Base[index], MARKED_ERASED); |
65 | base = ptr; |
69 | base = index+1; // look at next element |
66 | break; |
70 | break; |
67 | } |
71 | } |
68 | } |
72 | } |
69 | // search forward for next erased or empty element, use it |
73 | // search forward for next hardware erased element, use it |
70 | for (int offset = 1; offset < NVRAM_WORDS + 1; offset++) |
74 | for (int offset = 0; offset < NVRAM_WORDS; offset++) |
71 | { |
75 | { |
72 | int index = (base + offset) % NVRAM_WORDS; |
76 | int index = (base + offset) % NVRAM_WORDS; |
73 | 77 | ||
74 | if (NVRAM_Base[index].u16 == HARDWARE_ERASED.u16) |
78 | if (NVRAM_Base[index].u16 == HARDWARE_ERASED.u16) |
75 | { |
79 | { |
Line 79... | Line 83... | ||
79 | 83 | ||
80 | WriteNVRAM(&NVRAM_Base[index], data); |
84 | WriteNVRAM(&NVRAM_Base[index], data); |
81 | // now check to see if it actually wrote correctly |
85 | // now check to see if it actually wrote correctly |
82 | if (NVRAM_Base[index].u16 != data.u16) |
86 | if (NVRAM_Base[index].u16 != data.u16) |
83 | { |
87 | { |
84 | WriteNVRAM(&NVRAM_Base[index], MARKED_ERASED); // Set to all 1 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 |
85 | continue; |
89 | continue; |
86 | } |
90 | } |
87 | // record where the data was written |
91 | // record where the data was written |
88 | *pIndex = index; |
92 | *pIndex = index; |
89 | return pageCrossed; |
93 | return pageCrossed; |
Line 110... | Line 114... | ||
110 | int base = i; |
114 | int base = i; |
111 | // copy data forwards |
115 | // copy data forwards |
112 | _write_nvram_data(NVRAM_Base[i], &base); |
116 | _write_nvram_data(NVRAM_Base[i], &base); |
113 | } |
117 | } |
114 | // erase the page we just copied out of |
118 | // erase the page we just copied out of |
115 | EraseNVRAM(&NVRAM_Base[oldPageBase]); |
- | |
116 | } |
119 | } |
- | 120 | EraseNVRAM(&NVRAM_Base[oldPageBase]); |
|
117 | } |
121 | } |
118 | 122 | ||
119 | nvram_info_t *find_nvram_data(uint8_t searchTag) |
123 | nvram_info_t *find_nvram_data(uint8_t searchTag) |
120 | { |
124 | { |
121 | for (int ptr = 0; ptr < NVRAM_WORDS; ptr++) |
125 | for (int ptr = 0; ptr < NVRAM_WORDS; ptr++) |