aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--tmk_core/common.mk7
-rwxr-xr-xtmk_core/common/chibios/eeprom_stm32.c673
-rwxr-xr-xtmk_core/common/chibios/eeprom_stm32.h89
-rw-r--r--tmk_core/common/chibios/eeprom_teensy.c (renamed from tmk_core/common/chibios/eeprom.c)0
-rwxr-xr-xtmk_core/common/chibios/flash_stm32.c180
-rwxr-xr-xtmk_core/common/chibios/flash_stm32.h53
-rw-r--r--tmk_core/common/eeconfig.c11
-rw-r--r--tmk_core/common/eeconfig.h16
-rw-r--r--tmk_core/protocol/chibios/main.c7
9 files changed, 1035 insertions, 1 deletions
diff --git a/tmk_core/common.mk b/tmk_core/common.mk
index fd91d29dc..319d196ae 100644
--- a/tmk_core/common.mk
+++ b/tmk_core/common.mk
@@ -31,7 +31,12 @@ endif
31 31
32ifeq ($(PLATFORM),CHIBIOS) 32ifeq ($(PLATFORM),CHIBIOS)
33 TMK_COMMON_SRC += $(PLATFORM_COMMON_DIR)/printf.c 33 TMK_COMMON_SRC += $(PLATFORM_COMMON_DIR)/printf.c
34 TMK_COMMON_SRC += $(PLATFORM_COMMON_DIR)/eeprom.c 34 ifeq ($(MCU_SERIES), STM32F3xx)
35 TMK_COMMON_SRC += $(PLATFORM_COMMON_DIR)/eeprom_stm32.c
36 TMK_COMMON_SRC += $(PLATFORM_COMMON_DIR)/flash_stm32.c
37 else
38 TMK_COMMON_SRC += $(PLATFORM_COMMON_DIR)/eeprom_teensy.c
39endif
35 ifeq ($(strip $(AUTO_SHIFT_ENABLE)), yes) 40 ifeq ($(strip $(AUTO_SHIFT_ENABLE)), yes)
36 TMK_COMMON_SRC += $(CHIBIOS)/os/various/syscalls.c 41 TMK_COMMON_SRC += $(CHIBIOS)/os/various/syscalls.c
37 endif 42 endif
diff --git a/tmk_core/common/chibios/eeprom_stm32.c b/tmk_core/common/chibios/eeprom_stm32.c
new file mode 100755
index 000000000..3c1945122
--- /dev/null
+++ b/tmk_core/common/chibios/eeprom_stm32.c
@@ -0,0 +1,673 @@
1/*
2 * This software is experimental and a work in progress.
3 * Under no circumstances should these files be used in relation to any critical system(s).
4 * Use of these files is at your own risk.
5 *
6 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
7 * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
8 * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
9 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
10 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
11 * DEALINGS IN THE SOFTWARE.
12 *
13 * This files are free to use from https://github.com/rogerclarkmelbourne/Arduino_STM32 and
14 * https://github.com/leaflabs/libmaple
15 *
16 * Modifications for QMK and STM32F303 by Yiancar
17 */
18
19#include "eeprom_stm32.h"
20
21 FLASH_Status EE_ErasePage(uint32_t);
22
23 uint16_t EE_CheckPage(uint32_t, uint16_t);
24 uint16_t EE_CheckErasePage(uint32_t, uint16_t);
25 uint16_t EE_Format(void);
26 uint32_t EE_FindValidPage(void);
27 uint16_t EE_GetVariablesCount(uint32_t, uint16_t);
28 uint16_t EE_PageTransfer(uint32_t, uint32_t, uint16_t);
29 uint16_t EE_VerifyPageFullWriteVariable(uint16_t, uint16_t);
30
31 uint32_t PageBase0 = EEPROM_PAGE0_BASE;
32 uint32_t PageBase1 = EEPROM_PAGE1_BASE;
33 uint32_t PageSize = EEPROM_PAGE_SIZE;
34 uint16_t Status = EEPROM_NOT_INIT;
35
36// See http://www.st.com/web/en/resource/technical/document/application_note/CD00165693.pdf
37
38/**
39 * @brief Check page for blank
40 * @param page base address
41 * @retval Success or error
42 * EEPROM_BAD_FLASH: page not empty after erase
43 * EEPROM_OK: page blank
44 */
45uint16_t EE_CheckPage(uint32_t pageBase, uint16_t status)
46{
47 uint32_t pageEnd = pageBase + (uint32_t)PageSize;
48
49 // Page Status not EEPROM_ERASED and not a "state"
50 if ((*(__IO uint16_t*)pageBase) != EEPROM_ERASED && (*(__IO uint16_t*)pageBase) != status)
51 return EEPROM_BAD_FLASH;
52 for(pageBase += 4; pageBase < pageEnd; pageBase += 4)
53 if ((*(__IO uint32_t*)pageBase) != 0xFFFFFFFF) // Verify if slot is empty
54 return EEPROM_BAD_FLASH;
55 return EEPROM_OK;
56}
57
58/**
59 * @brief Erase page with increment erase counter (page + 2)
60 * @param page base address
61 * @retval Success or error
62 * FLASH_COMPLETE: success erase
63 * - Flash error code: on write Flash error
64 */
65FLASH_Status EE_ErasePage(uint32_t pageBase)
66{
67 FLASH_Status FlashStatus;
68 uint16_t data = (*(__IO uint16_t*)(pageBase));
69 if ((data == EEPROM_ERASED) || (data == EEPROM_VALID_PAGE) || (data == EEPROM_RECEIVE_DATA))
70 data = (*(__IO uint16_t*)(pageBase + 2)) + 1;
71 else
72 data = 0;
73
74 FlashStatus = FLASH_ErasePage(pageBase);
75 if (FlashStatus == FLASH_COMPLETE)
76 FlashStatus = FLASH_ProgramHalfWord(pageBase + 2, data);
77
78 return FlashStatus;
79}
80
81/**
82 * @brief Check page for blank and erase it
83 * @param page base address
84 * @retval Success or error
85 * - Flash error code: on write Flash error
86 * - EEPROM_BAD_FLASH: page not empty after erase
87 * - EEPROM_OK: page blank
88 */
89uint16_t EE_CheckErasePage(uint32_t pageBase, uint16_t status)
90{
91 uint16_t FlashStatus;
92 if (EE_CheckPage(pageBase, status) != EEPROM_OK)
93 {
94 FlashStatus = EE_ErasePage(pageBase);
95 if (FlashStatus != FLASH_COMPLETE)
96 return FlashStatus;
97 return EE_CheckPage(pageBase, status);
98 }
99 return EEPROM_OK;
100}
101
102/**
103 * @brief Find valid Page for write or read operation
104 * @param Page0: Page0 base address
105 * Page1: Page1 base address
106 * @retval Valid page address (PAGE0 or PAGE1) or NULL in case of no valid page was found
107 */
108uint32_t EE_FindValidPage(void)
109{
110 uint16_t status0 = (*(__IO uint16_t*)PageBase0); // Get Page0 actual status
111 uint16_t status1 = (*(__IO uint16_t*)PageBase1); // Get Page1 actual status
112
113 if (status0 == EEPROM_VALID_PAGE && status1 == EEPROM_ERASED)
114 return PageBase0;
115 if (status1 == EEPROM_VALID_PAGE && status0 == EEPROM_ERASED)
116 return PageBase1;
117
118 return 0;
119}
120
121/**
122 * @brief Calculate unique variables in EEPROM
123 * @param start: address of first slot to check (page + 4)
124 * @param end: page end address
125 * @param address: 16 bit virtual address of the variable to excluse (or 0XFFFF)
126 * @retval count of variables
127 */
128uint16_t EE_GetVariablesCount(uint32_t pageBase, uint16_t skipAddress)
129{
130 uint16_t varAddress, nextAddress;
131 uint32_t idx;
132 uint32_t pageEnd = pageBase + (uint32_t)PageSize;
133 uint16_t count = 0;
134
135 for (pageBase += 6; pageBase < pageEnd; pageBase += 4)
136 {
137 varAddress = (*(__IO uint16_t*)pageBase);
138 if (varAddress == 0xFFFF || varAddress == skipAddress)
139 continue;
140
141 count++;
142 for(idx = pageBase + 4; idx < pageEnd; idx += 4)
143 {
144 nextAddress = (*(__IO uint16_t*)idx);
145 if (nextAddress == varAddress)
146 {
147 count--;
148 break;
149 }
150 }
151 }
152 return count;
153}
154
155/**
156 * @brief Transfers last updated variables data from the full Page to an empty one.
157 * @param newPage: new page base address
158 * @param oldPage: old page base address
159 * @param SkipAddress: 16 bit virtual address of the variable (or 0xFFFF)
160 * @retval Success or error status:
161 * - FLASH_COMPLETE: on success
162 * - EEPROM_OUT_SIZE: if valid new page is full
163 * - Flash error code: on write Flash error
164 */
165uint16_t EE_PageTransfer(uint32_t newPage, uint32_t oldPage, uint16_t SkipAddress)
166{
167 uint32_t oldEnd, newEnd;
168 uint32_t oldIdx, newIdx, idx;
169 uint16_t address, data, found;
170 FLASH_Status FlashStatus;
171
172 // Transfer process: transfer variables from old to the new active page
173 newEnd = newPage + ((uint32_t)PageSize);
174
175 // Find first free element in new page
176 for (newIdx = newPage + 4; newIdx < newEnd; newIdx += 4)
177 if ((*(__IO uint32_t*)newIdx) == 0xFFFFFFFF) // Verify if element
178 break; // contents are 0xFFFFFFFF
179 if (newIdx >= newEnd)
180 return EEPROM_OUT_SIZE;
181
182 oldEnd = oldPage + 4;
183 oldIdx = oldPage + (uint32_t)(PageSize - 2);
184
185 for (; oldIdx > oldEnd; oldIdx -= 4)
186 {
187 address = *(__IO uint16_t*)oldIdx;
188 if (address == 0xFFFF || address == SkipAddress)
189 continue; // it's means that power off after write data
190
191 found = 0;
192 for (idx = newPage + 6; idx < newIdx; idx += 4)
193 if ((*(__IO uint16_t*)(idx)) == address)
194 {
195 found = 1;
196 break;
197 }
198
199 if (found)
200 continue;
201
202 if (newIdx < newEnd)
203 {
204 data = (*(__IO uint16_t*)(oldIdx - 2));
205
206 FlashStatus = FLASH_ProgramHalfWord(newIdx, data);
207 if (FlashStatus != FLASH_COMPLETE)
208 return FlashStatus;
209
210 FlashStatus = FLASH_ProgramHalfWord(newIdx + 2, address);
211 if (FlashStatus != FLASH_COMPLETE)
212 return FlashStatus;
213
214 newIdx += 4;
215 }
216 else
217 return EEPROM_OUT_SIZE;
218 }
219
220 // Erase the old Page: Set old Page status to EEPROM_EEPROM_ERASED status
221 data = EE_CheckErasePage(oldPage, EEPROM_ERASED);
222 if (data != EEPROM_OK)
223 return data;
224
225 // Set new Page status
226 FlashStatus = FLASH_ProgramHalfWord(newPage, EEPROM_VALID_PAGE);
227 if (FlashStatus != FLASH_COMPLETE)
228 return FlashStatus;
229
230 return EEPROM_OK;
231}
232
233/**
234 * @brief Verify if active page is full and Writes variable in EEPROM.
235 * @param Address: 16 bit virtual address of the variable
236 * @param Data: 16 bit data to be written as variable value
237 * @retval Success or error status:
238 * - FLASH_COMPLETE: on success
239 * - EEPROM_PAGE_FULL: if valid page is full (need page transfer)
240 * - EEPROM_NO_VALID_PAGE: if no valid page was found
241 * - EEPROM_OUT_SIZE: if EEPROM size exceeded
242 * - Flash error code: on write Flash error
243 */
244uint16_t EE_VerifyPageFullWriteVariable(uint16_t Address, uint16_t Data)
245{
246 FLASH_Status FlashStatus;
247 uint32_t idx, pageBase, pageEnd, newPage;
248 uint16_t count;
249
250 // Get valid Page for write operation
251 pageBase = EE_FindValidPage();
252 if (pageBase == 0)
253 return EEPROM_NO_VALID_PAGE;
254
255 // Get the valid Page end Address
256 pageEnd = pageBase + PageSize; // Set end of page
257
258 for (idx = pageEnd - 2; idx > pageBase; idx -= 4)
259 {
260 if ((*(__IO uint16_t*)idx) == Address) // Find last value for address
261 {
262 count = (*(__IO uint16_t*)(idx - 2)); // Read last data
263 if (count == Data)
264 return EEPROM_OK;
265 if (count == 0xFFFF)
266 {
267 FlashStatus = FLASH_ProgramHalfWord(idx - 2, Data); // Set variable data
268 if (FlashStatus == FLASH_COMPLETE)
269 return EEPROM_OK;
270 }
271 break;
272 }
273 }
274
275 // Check each active page address starting from begining
276 for (idx = pageBase + 4; idx < pageEnd; idx += 4)
277 if ((*(__IO uint32_t*)idx) == 0xFFFFFFFF) // Verify if element
278 { // contents are 0xFFFFFFFF
279 FlashStatus = FLASH_ProgramHalfWord(idx, Data); // Set variable data
280 if (FlashStatus != FLASH_COMPLETE)
281 return FlashStatus;
282 FlashStatus = FLASH_ProgramHalfWord(idx + 2, Address); // Set variable virtual address
283 if (FlashStatus != FLASH_COMPLETE)
284 return FlashStatus;
285 return EEPROM_OK;
286 }
287
288 // Empty slot not found, need page transfer
289 // Calculate unique variables in page
290 count = EE_GetVariablesCount(pageBase, Address) + 1;
291 if (count >= (PageSize / 4 - 1))
292 return EEPROM_OUT_SIZE;
293
294 if (pageBase == PageBase1)
295 newPage = PageBase0; // New page address where variable will be moved to
296 else
297 newPage = PageBase1;
298
299 // Set the new Page status to RECEIVE_DATA status
300 FlashStatus = FLASH_ProgramHalfWord(newPage, EEPROM_RECEIVE_DATA);
301 if (FlashStatus != FLASH_COMPLETE)
302 return FlashStatus;
303
304 // Write the variable passed as parameter in the new active page
305 FlashStatus = FLASH_ProgramHalfWord(newPage + 4, Data);
306 if (FlashStatus != FLASH_COMPLETE)
307 return FlashStatus;
308
309 FlashStatus = FLASH_ProgramHalfWord(newPage + 6, Address);
310 if (FlashStatus != FLASH_COMPLETE)
311 return FlashStatus;
312
313 return EE_PageTransfer(newPage, pageBase, Address);
314}
315
316/*EEPROMClass::EEPROMClass(void)
317{
318 PageBase0 = EEPROM_PAGE0_BASE;
319 PageBase1 = EEPROM_PAGE1_BASE;
320 PageSize = EEPROM_PAGE_SIZE;
321 Status = EEPROM_NOT_INIT;
322}*/
323/*
324uint16_t EEPROM_init(uint32_t pageBase0, uint32_t pageBase1, uint32_t pageSize)
325{
326 PageBase0 = pageBase0;
327 PageBase1 = pageBase1;
328 PageSize = pageSize;
329 return EEPROM_init();
330}*/
331
332uint16_t EEPROM_init(void)
333{
334 uint16_t status0 = 6, status1 = 6;
335 FLASH_Status FlashStatus;
336
337 FLASH_Unlock();
338 Status = EEPROM_NO_VALID_PAGE;
339
340 status0 = (*(__IO uint16_t *)PageBase0);
341 status1 = (*(__IO uint16_t *)PageBase1);
342
343 switch (status0)
344 {
345/*
346 Page0 Page1
347 ----- -----
348 EEPROM_ERASED EEPROM_VALID_PAGE Page1 valid, Page0 erased
349 EEPROM_RECEIVE_DATA Page1 need set to valid, Page0 erased
350 EEPROM_ERASED make EE_Format
351 any Error: EEPROM_NO_VALID_PAGE
352*/
353 case EEPROM_ERASED:
354 if (status1 == EEPROM_VALID_PAGE) // Page0 erased, Page1 valid
355 Status = EE_CheckErasePage(PageBase0, EEPROM_ERASED);
356 else if (status1 == EEPROM_RECEIVE_DATA) // Page0 erased, Page1 receive
357 {
358 FlashStatus = FLASH_ProgramHalfWord(PageBase1, EEPROM_VALID_PAGE);
359 if (FlashStatus != FLASH_COMPLETE)
360 Status = FlashStatus;
361 else
362 Status = EE_CheckErasePage(PageBase0, EEPROM_ERASED);
363 }
364 else if (status1 == EEPROM_ERASED) // Both in erased state so format EEPROM
365 Status = EEPROM_format();
366 break;
367/*
368 Page0 Page1
369 ----- -----
370 EEPROM_RECEIVE_DATA EEPROM_VALID_PAGE Transfer Page1 to Page0
371 EEPROM_ERASED Page0 need set to valid, Page1 erased
372 any EEPROM_NO_VALID_PAGE
373*/
374 case EEPROM_RECEIVE_DATA:
375 if (status1 == EEPROM_VALID_PAGE) // Page0 receive, Page1 valid
376 Status = EE_PageTransfer(PageBase0, PageBase1, 0xFFFF);
377 else if (status1 == EEPROM_ERASED) // Page0 receive, Page1 erased
378 {
379 Status = EE_CheckErasePage(PageBase1, EEPROM_ERASED);
380 if (Status == EEPROM_OK)
381 {
382 FlashStatus = FLASH_ProgramHalfWord(PageBase0, EEPROM_VALID_PAGE);
383 if (FlashStatus != FLASH_COMPLETE)
384 Status = FlashStatus;
385 else
386 Status = EEPROM_OK;
387 }
388 }
389 break;
390/*
391 Page0 Page1
392 ----- -----
393 EEPROM_VALID_PAGE EEPROM_VALID_PAGE Error: EEPROM_NO_VALID_PAGE
394 EEPROM_RECEIVE_DATA Transfer Page0 to Page1
395 any Page0 valid, Page1 erased
396*/
397 case EEPROM_VALID_PAGE:
398 if (status1 == EEPROM_VALID_PAGE) // Both pages valid
399 Status = EEPROM_NO_VALID_PAGE;
400 else if (status1 == EEPROM_RECEIVE_DATA)
401 Status = EE_PageTransfer(PageBase1, PageBase0, 0xFFFF);
402 else
403 Status = EE_CheckErasePage(PageBase1, EEPROM_ERASED);
404 break;
405/*
406 Page0 Page1
407 ----- -----
408 any EEPROM_VALID_PAGE Page1 valid, Page0 erased
409 EEPROM_RECEIVE_DATA Page1 valid, Page0 erased
410 any EEPROM_NO_VALID_PAGE
411*/
412 default:
413 if (status1 == EEPROM_VALID_PAGE)
414 Status = EE_CheckErasePage(PageBase0, EEPROM_ERASED); // Check/Erase Page0
415 else if (status1 == EEPROM_RECEIVE_DATA)
416 {
417 FlashStatus = FLASH_ProgramHalfWord(PageBase1, EEPROM_VALID_PAGE);
418 if (FlashStatus != FLASH_COMPLETE)
419 Status = FlashStatus;
420 else
421 Status = EE_CheckErasePage(PageBase0, EEPROM_ERASED);
422 }
423 break;
424 }
425 return Status;
426}
427
428/**
429 * @brief Erases PAGE0 and PAGE1 and writes EEPROM_VALID_PAGE / 0 header to PAGE0
430 * @param PAGE0 and PAGE1 base addresses
431 * @retval Status of the last operation (Flash write or erase) done during EEPROM formating
432 */
433uint16_t EEPROM_format(void)
434{
435 uint16_t status;
436 FLASH_Status FlashStatus;
437
438 FLASH_Unlock();
439
440 // Erase Page0
441 status = EE_CheckErasePage(PageBase0, EEPROM_VALID_PAGE);
442 if (status != EEPROM_OK)
443 return status;
444 if ((*(__IO uint16_t*)PageBase0) == EEPROM_ERASED)
445 {
446 // Set Page0 as valid page: Write VALID_PAGE at Page0 base address
447 FlashStatus = FLASH_ProgramHalfWord(PageBase0, EEPROM_VALID_PAGE);
448 if (FlashStatus != FLASH_COMPLETE)
449 return FlashStatus;
450 }
451 // Erase Page1
452 return EE_CheckErasePage(PageBase1, EEPROM_ERASED);
453}
454
455/**
456 * @brief Returns the erase counter for current page
457 * @param Data: Global variable contains the read variable value
458 * @retval Success or error status:
459 * - EEPROM_OK: if erases counter return.
460 * - EEPROM_NO_VALID_PAGE: if no valid page was found.
461 */
462uint16_t EEPROM_erases(uint16_t *Erases)
463{
464 uint32_t pageBase;
465 if (Status != EEPROM_OK)
466 if (EEPROM_init() != EEPROM_OK)
467 return Status;
468
469 // Get active Page for read operation
470 pageBase = EE_FindValidPage();
471 if (pageBase == 0)
472 return EEPROM_NO_VALID_PAGE;
473
474 *Erases = (*(__IO uint16_t*)pageBase+2);
475 return EEPROM_OK;
476}
477
478/**
479 * @brief Returns the last stored variable data, if found,
480 * which correspond to the passed virtual address
481 * @param Address: Variable virtual address
482 * @retval Data for variable or EEPROM_DEFAULT_DATA, if any errors
483 */
484/*
485uint16_t EEPROM_read (uint16_t Address)
486{
487 uint16_t data;
488 EEPROM_read(Address, &data);
489 return data;
490}*/
491
492/**
493 * @brief Returns the last stored variable data, if found,
494 * which correspond to the passed virtual address
495 * @param Address: Variable virtual address
496 * @param Data: Pointer to data variable
497 * @retval Success or error status:
498 * - EEPROM_OK: if variable was found
499 * - EEPROM_BAD_ADDRESS: if the variable was not found
500 * - EEPROM_NO_VALID_PAGE: if no valid page was found.
501 */
502uint16_t EEPROM_read(uint16_t Address, uint16_t *Data)
503{
504 uint32_t pageBase, pageEnd;
505
506 // Set default data (empty EEPROM)
507 *Data = EEPROM_DEFAULT_DATA;
508
509 if (Status == EEPROM_NOT_INIT)
510 if (EEPROM_init() != EEPROM_OK)
511 return Status;
512
513 // Get active Page for read operation
514 pageBase = EE_FindValidPage();
515 if (pageBase == 0)
516 return EEPROM_NO_VALID_PAGE;
517
518 // Get the valid Page end Address
519 pageEnd = pageBase + ((uint32_t)(PageSize - 2));
520
521 // Check each active page address starting from end
522 for (pageBase += 6; pageEnd >= pageBase; pageEnd -= 4)
523 if ((*(__IO uint16_t*)pageEnd) == Address) // Compare the read address with the virtual address
524 {
525 *Data = (*(__IO uint16_t*)(pageEnd - 2)); // Get content of Address-2 which is variable value
526 return EEPROM_OK;
527 }
528
529 // Return ReadStatus value: (0: variable exist, 1: variable doesn't exist)
530 return EEPROM_BAD_ADDRESS;
531}
532
533/**
534 * @brief Writes/upadtes variable data in EEPROM.
535 * @param VirtAddress: Variable virtual address
536 * @param Data: 16 bit data to be written
537 * @retval Success or error status:
538 * - FLASH_COMPLETE: on success
539 * - EEPROM_BAD_ADDRESS: if address = 0xFFFF
540 * - EEPROM_PAGE_FULL: if valid page is full
541 * - EEPROM_NO_VALID_PAGE: if no valid page was found
542 * - EEPROM_OUT_SIZE: if no empty EEPROM variables
543 * - Flash error code: on write Flash error
544 */
545uint16_t EEPROM_write(uint16_t Address, uint16_t Data)
546{
547 if (Status == EEPROM_NOT_INIT)
548 if (EEPROM_init() != EEPROM_OK)
549 return Status;
550
551 if (Address == 0xFFFF)
552 return EEPROM_BAD_ADDRESS;
553
554 // Write the variable virtual address and value in the EEPROM
555 uint16_t status = EE_VerifyPageFullWriteVariable(Address, Data);
556 return status;
557}
558
559/**
560 * @brief Writes/upadtes variable data in EEPROM.
561 The value is written only if differs from the one already saved at the same address.
562 * @param VirtAddress: Variable virtual address
563 * @param Data: 16 bit data to be written
564 * @retval Success or error status:
565 * - EEPROM_SAME_VALUE: If new Data matches existing EEPROM Data
566 * - FLASH_COMPLETE: on success
567 * - EEPROM_BAD_ADDRESS: if address = 0xFFFF
568 * - EEPROM_PAGE_FULL: if valid page is full
569 * - EEPROM_NO_VALID_PAGE: if no valid page was found
570 * - EEPROM_OUT_SIZE: if no empty EEPROM variables
571 * - Flash error code: on write Flash error
572 */
573uint16_t EEPROM_update(uint16_t Address, uint16_t Data)
574{
575 uint16_t temp;
576 EEPROM_read(Address, &temp);
577 if (Address == Data)
578 return EEPROM_SAME_VALUE;
579 else
580 return EEPROM_write(Address, Data);
581}
582
583/**
584 * @brief Return number of variable
585 * @retval Number of variables
586 */
587uint16_t EEPROM_count(uint16_t *Count)
588{
589 if (Status == EEPROM_NOT_INIT)
590 if (EEPROM_init() != EEPROM_OK)
591 return Status;
592
593 // Get valid Page for write operation
594 uint32_t pageBase = EE_FindValidPage();
595 if (pageBase == 0)
596 return EEPROM_NO_VALID_PAGE; // No valid page, return max. numbers
597
598 *Count = EE_GetVariablesCount(pageBase, 0xFFFF);
599 return EEPROM_OK;
600}
601
602uint16_t EEPROM_maxcount(void)
603{
604 return ((PageSize / 4)-1);
605}
606
607
608uint8_t eeprom_read_byte (const uint8_t *Address)
609{
610 const uint16_t p = (const uint32_t) Address;
611 uint16_t temp;
612 EEPROM_read(p, &temp);
613 return (uint8_t) temp;
614}
615
616void eeprom_write_byte (uint8_t *Address, uint8_t Value)
617{
618 uint16_t p = (uint32_t) Address;
619 EEPROM_write(p, (uint16_t) Value);
620}
621
622void eeprom_update_byte (uint8_t *Address, uint8_t Value)
623{
624 uint16_t p = (uint32_t) Address;
625 EEPROM_update(p, (uint16_t) Value);
626}
627
628uint16_t eeprom_read_word (const uint16_t *Address)
629{
630 const uint16_t p = (const uint32_t) Address;
631 uint16_t temp;
632 EEPROM_read(p, &temp);
633 return temp;
634}
635
636void eeprom_write_word (uint16_t *Address, uint16_t Value)
637{
638 uint16_t p = (uint32_t) Address;
639 EEPROM_write(p, Value);
640}
641
642void eeprom_update_word (uint16_t *Address, uint16_t Value)
643{
644 uint16_t p = (uint32_t) Address;
645 EEPROM_update(p, Value);
646}
647
648uint32_t eeprom_read_dword (const uint32_t *Address)
649{
650 const uint16_t p = (const uint32_t) Address;
651 uint16_t temp1, temp2;
652 EEPROM_read(p, &temp1);
653 EEPROM_read(p + 1, &temp2);
654 return temp1 | (temp2 << 16);
655}
656
657void eeprom_write_dword (uint32_t *Address, uint32_t Value)
658{
659 uint16_t temp = (uint16_t) Value;
660 uint16_t p = (uint32_t) Address;
661 EEPROM_write(p, temp);
662 temp = (uint16_t) (Value >> 16);
663 EEPROM_write(p + 1, temp);
664}
665
666void eeprom_update_dword (uint32_t *Address, uint32_t Value)
667{
668 uint16_t temp = (uint16_t) Value;
669 uint16_t p = (uint32_t) Address;
670 EEPROM_update(p, temp);
671 temp = (uint16_t) (Value >> 16);
672 EEPROM_update(p + 1, temp);
673}
diff --git a/tmk_core/common/chibios/eeprom_stm32.h b/tmk_core/common/chibios/eeprom_stm32.h
new file mode 100755
index 000000000..d06d30266
--- /dev/null
+++ b/tmk_core/common/chibios/eeprom_stm32.h
@@ -0,0 +1,89 @@
1/*
2 * This software is experimental and a work in progress.
3 * Under no circumstances should these files be used in relation to any critical system(s).
4 * Use of these files is at your own risk.
5 *
6 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
7 * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
8 * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
9 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
10 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
11 * DEALINGS IN THE SOFTWARE.
12 *
13 * This files are free to use from https://github.com/rogerclarkmelbourne/Arduino_STM32 and
14 * https://github.com/leaflabs/libmaple
15 *
16 * Modifications for QMK and STM32F303 by Yiancar
17 */
18
19// This file must be modified if the MCU is not defined below.
20// This library also assumes that the pages are not used by the firmware.
21
22#ifndef __EEPROM_H
23#define __EEPROM_H
24
25#include "ch.h"
26#include "hal.h"
27#include "flash_stm32.h"
28
29// HACK ALERT. This definition may not match your processor
30// To Do. Work out correct value for EEPROM_PAGE_SIZE on the STM32F103CT6 etc
31#define MCU_STM32F303CC
32
33#ifndef EEPROM_PAGE_SIZE
34 #if defined (MCU_STM32F103RB)
35 #define EEPROM_PAGE_SIZE (uint16_t)0x400 /* Page size = 1KByte */
36 #elif defined (MCU_STM32F103ZE) || defined (MCU_STM32F103RE) || defined (MCU_STM32F103RD) || defined (MCU_STM32F303CC)
37 #define EEPROM_PAGE_SIZE (uint16_t)0x800 /* Page size = 2KByte */
38 #else
39 #error "No MCU type specified. Add something like -DMCU_STM32F103RB to your compiler arguments (probably in a Makefile)."
40 #endif
41#endif
42
43#ifndef EEPROM_START_ADDRESS
44 #if defined (MCU_STM32F103RB)
45 #define EEPROM_START_ADDRESS ((uint32_t)(0x8000000 + 128 * 1024 - 2 * EEPROM_PAGE_SIZE))
46 #elif defined (MCU_STM32F103ZE) || defined (MCU_STM32F103RE)
47 #define EEPROM_START_ADDRESS ((uint32_t)(0x8000000 + 512 * 1024 - 2 * EEPROM_PAGE_SIZE))
48 #elif defined (MCU_STM32F103RD)
49 #define EEPROM_START_ADDRESS ((uint32_t)(0x8000000 + 384 * 1024 - 2 * EEPROM_PAGE_SIZE))
50 #elif defined (MCU_STM32F303CC)
51 #define EEPROM_START_ADDRESS ((uint32_t)(0x8000000 + 250 * 1024 - 2 * EEPROM_PAGE_SIZE))
52 #else
53 #error "No MCU type specified. Add something like -DMCU_STM32F103RB to your compiler arguments (probably in a Makefile)."
54 #endif
55#endif
56
57/* Pages 0 and 1 base and end addresses */
58#define EEPROM_PAGE0_BASE ((uint32_t)(EEPROM_START_ADDRESS + 0x000))
59#define EEPROM_PAGE1_BASE ((uint32_t)(EEPROM_START_ADDRESS + EEPROM_PAGE_SIZE))
60
61/* Page status definitions */
62#define EEPROM_ERASED ((uint16_t)0xFFFF) /* PAGE is empty */
63#define EEPROM_RECEIVE_DATA ((uint16_t)0xEEEE) /* PAGE is marked to receive data */
64#define EEPROM_VALID_PAGE ((uint16_t)0x0000) /* PAGE containing valid data */
65
66/* Page full define */
67enum uint16_t
68 {
69 EEPROM_OK = ((uint16_t)0x0000),
70 EEPROM_OUT_SIZE = ((uint16_t)0x0081),
71 EEPROM_BAD_ADDRESS = ((uint16_t)0x0082),
72 EEPROM_BAD_FLASH = ((uint16_t)0x0083),
73 EEPROM_NOT_INIT = ((uint16_t)0x0084),
74 EEPROM_SAME_VALUE = ((uint16_t)0x0085),
75 EEPROM_NO_VALID_PAGE = ((uint16_t)0x00AB)
76 };
77
78#define EEPROM_DEFAULT_DATA 0xFFFF
79
80 uint16_t EEPROM_init(void);
81 uint16_t EEPROM_format(void);
82 uint16_t EEPROM_erases(uint16_t *);
83 uint16_t EEPROM_read (uint16_t address, uint16_t *data);
84 uint16_t EEPROM_write(uint16_t address, uint16_t data);
85 uint16_t EEPROM_update(uint16_t address, uint16_t data);
86 uint16_t EEPROM_count(uint16_t *);
87 uint16_t EEPROM_maxcount(void);
88
89#endif /* __EEPROM_H */
diff --git a/tmk_core/common/chibios/eeprom.c b/tmk_core/common/chibios/eeprom_teensy.c
index 9061b790c..9061b790c 100644
--- a/tmk_core/common/chibios/eeprom.c
+++ b/tmk_core/common/chibios/eeprom_teensy.c
diff --git a/tmk_core/common/chibios/flash_stm32.c b/tmk_core/common/chibios/flash_stm32.c
new file mode 100755
index 000000000..e7199ac7b
--- /dev/null
+++ b/tmk_core/common/chibios/flash_stm32.c
@@ -0,0 +1,180 @@
1/*
2 * This software is experimental and a work in progress.
3 * Under no circumstances should these files be used in relation to any critical system(s).
4 * Use of these files is at your own risk.
5 *
6 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
7 * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
8 * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
9 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
10 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
11 * DEALINGS IN THE SOFTWARE.
12 *
13 * This files are free to use from https://github.com/rogerclarkmelbourne/Arduino_STM32 and
14 * https://github.com/leaflabs/libmaple
15 *
16 * Modifications for QMK and STM32F303 by Yiancar
17 */
18
19#define STM32F303xC
20
21#include "stm32f3xx.h"
22#include "flash_stm32.h"
23
24#define FLASH_KEY1 ((uint32_t)0x45670123)
25#define FLASH_KEY2 ((uint32_t)0xCDEF89AB)
26
27/* Delay definition */
28#define EraseTimeout ((uint32_t)0x00000FFF)
29#define ProgramTimeout ((uint32_t)0x0000001F)
30
31#define ASSERT(exp) (void)((0))
32
33/**
34 * @brief Inserts a time delay.
35 * @param None
36 * @retval None
37 */
38static void delay(void)
39{
40 __IO uint32_t i = 0;
41 for(i = 0xFF; i != 0; i--) { }
42}
43
44/**
45 * @brief Returns the FLASH Status.
46 * @param None
47 * @retval FLASH Status: The returned value can be: FLASH_BUSY, FLASH_ERROR_PG,
48 * FLASH_ERROR_WRP or FLASH_COMPLETE
49 */
50FLASH_Status FLASH_GetStatus(void)
51{
52 if ((FLASH->SR & FLASH_SR_BSY) == FLASH_SR_BSY)
53 return FLASH_BUSY;
54
55 if ((FLASH->SR & FLASH_SR_PGERR) != 0)
56 return FLASH_ERROR_PG;
57
58 if ((FLASH->SR & FLASH_SR_WRPERR) != 0 )
59 return FLASH_ERROR_WRP;
60
61 if ((FLASH->SR & FLASH_OBR_OPTERR) != 0 )
62 return FLASH_ERROR_OPT;
63
64 return FLASH_COMPLETE;
65}
66
67/**
68 * @brief Waits for a Flash operation to complete or a TIMEOUT to occur.
69 * @param Timeout: FLASH progamming Timeout
70 * @retval FLASH Status: The returned value can be: FLASH_ERROR_PG,
71 * FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
72 */
73FLASH_Status FLASH_WaitForLastOperation(uint32_t Timeout)
74{
75 FLASH_Status status;
76
77 /* Check for the Flash Status */
78 status = FLASH_GetStatus();
79 /* Wait for a Flash operation to complete or a TIMEOUT to occur */
80 while ((status == FLASH_BUSY) && (Timeout != 0x00))
81 {
82 delay();
83 status = FLASH_GetStatus();
84 Timeout--;
85 }
86 if (Timeout == 0)
87 status = FLASH_TIMEOUT;
88 /* Return the operation status */
89 return status;
90}
91
92/**
93 * @brief Erases a specified FLASH page.
94 * @param Page_Address: The page address to be erased.
95 * @retval FLASH Status: The returned value can be: FLASH_BUSY, FLASH_ERROR_PG,
96 * FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
97 */
98FLASH_Status FLASH_ErasePage(uint32_t Page_Address)
99{
100 FLASH_Status status = FLASH_COMPLETE;
101 /* Check the parameters */
102 ASSERT(IS_FLASH_ADDRESS(Page_Address));
103 /* Wait for last operation to be completed */
104 status = FLASH_WaitForLastOperation(EraseTimeout);
105
106 if(status == FLASH_COMPLETE)
107 {
108 /* if the previous operation is completed, proceed to erase the page */
109 FLASH->CR |= FLASH_CR_PER;
110 FLASH->AR = Page_Address;
111 FLASH->CR |= FLASH_CR_STRT;
112
113 /* Wait for last operation to be completed */
114 status = FLASH_WaitForLastOperation(EraseTimeout);
115 if(status != FLASH_TIMEOUT)
116 {
117 /* if the erase operation is completed, disable the PER Bit */
118 FLASH->CR &= ~FLASH_CR_PER;
119 }
120 FLASH->SR = (FLASH_SR_EOP | FLASH_SR_PGERR | FLASH_SR_WRPERR);
121 }
122 /* Return the Erase Status */
123 return status;
124}
125
126/**
127 * @brief Programs a half word at a specified address.
128 * @param Address: specifies the address to be programmed.
129 * @param Data: specifies the data to be programmed.
130 * @retval FLASH Status: The returned value can be: FLASH_ERROR_PG,
131 * FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
132 */
133FLASH_Status FLASH_ProgramHalfWord(uint32_t Address, uint16_t Data)
134{
135 FLASH_Status status = FLASH_BAD_ADDRESS;
136
137 if (IS_FLASH_ADDRESS(Address))
138 {
139 /* Wait for last operation to be completed */
140 status = FLASH_WaitForLastOperation(ProgramTimeout);
141 if(status == FLASH_COMPLETE)
142 {
143 /* if the previous operation is completed, proceed to program the new data */
144 FLASH->CR |= FLASH_CR_PG;
145 *(__IO uint16_t*)Address = Data;
146 /* Wait for last operation to be completed */
147 status = FLASH_WaitForLastOperation(ProgramTimeout);
148 if(status != FLASH_TIMEOUT)
149 {
150 /* if the program operation is completed, disable the PG Bit */
151 FLASH->CR &= ~FLASH_CR_PG;
152 }
153 FLASH->SR = (FLASH_SR_EOP | FLASH_SR_PGERR | FLASH_SR_WRPERR);
154 }
155 }
156 return status;
157}
158
159/**
160 * @brief Unlocks the FLASH Program Erase Controller.
161 * @param None
162 * @retval None
163 */
164void FLASH_Unlock(void)
165{
166 /* Authorize the FPEC Access */
167 FLASH->KEYR = FLASH_KEY1;
168 FLASH->KEYR = FLASH_KEY2;
169}
170
171/**
172 * @brief Locks the FLASH Program Erase Controller.
173 * @param None
174 * @retval None
175 */
176void FLASH_Lock(void)
177{
178 /* Set the Lock Bit to lock the FPEC and the FCR */
179 FLASH->CR |= FLASH_CR_LOCK;
180}
diff --git a/tmk_core/common/chibios/flash_stm32.h b/tmk_core/common/chibios/flash_stm32.h
new file mode 100755
index 000000000..cc065cbca
--- /dev/null
+++ b/tmk_core/common/chibios/flash_stm32.h
@@ -0,0 +1,53 @@
1/*
2 * This software is experimental and a work in progress.
3 * Under no circumstances should these files be used in relation to any critical system(s).
4 * Use of these files is at your own risk.
5 *
6 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
7 * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
8 * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
9 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
10 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
11 * DEALINGS IN THE SOFTWARE.
12 *
13 * This files are free to use from https://github.com/rogerclarkmelbourne/Arduino_STM32 and
14 * https://github.com/leaflabs/libmaple
15 *
16 * Modifications for QMK and STM32F303 by Yiancar
17 */
18
19#ifndef __FLASH_STM32_H
20#define __FLASH_STM32_H
21
22#ifdef __cplusplus
23 extern "C" {
24#endif
25
26#include "ch.h"
27#include "hal.h"
28
29typedef enum
30 {
31 FLASH_BUSY = 1,
32 FLASH_ERROR_PG,
33 FLASH_ERROR_WRP,
34 FLASH_ERROR_OPT,
35 FLASH_COMPLETE,
36 FLASH_TIMEOUT,
37 FLASH_BAD_ADDRESS
38 } FLASH_Status;
39
40#define IS_FLASH_ADDRESS(ADDRESS) (((ADDRESS) >= 0x08000000) && ((ADDRESS) < 0x0807FFFF))
41
42FLASH_Status FLASH_WaitForLastOperation(uint32_t Timeout);
43FLASH_Status FLASH_ErasePage(uint32_t Page_Address);
44FLASH_Status FLASH_ProgramHalfWord(uint32_t Address, uint16_t Data);
45
46void FLASH_Unlock(void);
47void FLASH_Lock(void);
48
49#ifdef __cplusplus
50}
51#endif
52
53#endif /* __FLASH_STM32_H */
diff --git a/tmk_core/common/eeconfig.c b/tmk_core/common/eeconfig.c
index 3e5987ee3..35de574a9 100644
--- a/tmk_core/common/eeconfig.c
+++ b/tmk_core/common/eeconfig.c
@@ -3,12 +3,20 @@
3#include "eeprom.h" 3#include "eeprom.h"
4#include "eeconfig.h" 4#include "eeconfig.h"
5 5
6#ifdef STM32F303xC
7#include "hal.h"
8#include "eeprom_stm32.h"
9#endif
10
6/** \brief eeconfig initialization 11/** \brief eeconfig initialization
7 * 12 *
8 * FIXME: needs doc 13 * FIXME: needs doc
9 */ 14 */
10void eeconfig_init(void) 15void eeconfig_init(void)
11{ 16{
17#ifdef STM32F303xC
18 EEPROM_format();
19#endif
12 eeprom_update_word(EECONFIG_MAGIC, EECONFIG_MAGIC_NUMBER); 20 eeprom_update_word(EECONFIG_MAGIC, EECONFIG_MAGIC_NUMBER);
13 eeprom_update_byte(EECONFIG_DEBUG, 0); 21 eeprom_update_byte(EECONFIG_DEBUG, 0);
14 eeprom_update_byte(EECONFIG_DEFAULT_LAYER, 0); 22 eeprom_update_byte(EECONFIG_DEFAULT_LAYER, 0);
@@ -43,6 +51,9 @@ void eeconfig_enable(void)
43 */ 51 */
44void eeconfig_disable(void) 52void eeconfig_disable(void)
45{ 53{
54#ifdef STM32F303xC
55 EEPROM_format();
56#endif
46 eeprom_update_word(EECONFIG_MAGIC, 0xFFFF); 57 eeprom_update_word(EECONFIG_MAGIC, 0xFFFF);
47} 58}
48 59
diff --git a/tmk_core/common/eeconfig.h b/tmk_core/common/eeconfig.h
index 1397a90c7..fa498df48 100644
--- a/tmk_core/common/eeconfig.h
+++ b/tmk_core/common/eeconfig.h
@@ -25,6 +25,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
25#define EECONFIG_MAGIC_NUMBER (uint16_t)0xFEED 25#define EECONFIG_MAGIC_NUMBER (uint16_t)0xFEED
26 26
27/* eeprom parameteter address */ 27/* eeprom parameteter address */
28#if !defined(STM32F303xC)
28#define EECONFIG_MAGIC (uint16_t *)0 29#define EECONFIG_MAGIC (uint16_t *)0
29#define EECONFIG_DEBUG (uint8_t *)2 30#define EECONFIG_DEBUG (uint8_t *)2
30#define EECONFIG_DEFAULT_LAYER (uint8_t *)3 31#define EECONFIG_DEFAULT_LAYER (uint8_t *)3
@@ -38,6 +39,21 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
38// EEHANDS for two handed boards 39// EEHANDS for two handed boards
39#define EECONFIG_HANDEDNESS (uint8_t *)14 40#define EECONFIG_HANDEDNESS (uint8_t *)14
40 41
42#else
43/* STM32F3 uses 16byte block. Reconfigure memory map */
44#define EECONFIG_MAGIC (uint16_t *)0
45#define EECONFIG_DEBUG (uint8_t *)1
46#define EECONFIG_DEFAULT_LAYER (uint8_t *)2
47#define EECONFIG_KEYMAP (uint8_t *)3
48#define EECONFIG_MOUSEKEY_ACCEL (uint8_t *)4
49#define EECONFIG_BACKLIGHT (uint8_t *)5
50#define EECONFIG_AUDIO (uint8_t *)6
51#define EECONFIG_RGBLIGHT (uint32_t *)7
52#define EECONFIG_UNICODEMODE (uint8_t *)9
53#define EECONFIG_STENOMODE (uint8_t *)10
54// EEHANDS for two handed boards
55#define EECONFIG_HANDEDNESS (uint8_t *)11
56#endif
41 57
42/* debug bit */ 58/* debug bit */
43#define EECONFIG_DEBUG_ENABLE (1<<0) 59#define EECONFIG_DEBUG_ENABLE (1<<0)
diff --git a/tmk_core/protocol/chibios/main.c b/tmk_core/protocol/chibios/main.c
index f2abc438d..568c1edb2 100644
--- a/tmk_core/protocol/chibios/main.c
+++ b/tmk_core/protocol/chibios/main.c
@@ -44,6 +44,9 @@
44#ifdef MIDI_ENABLE 44#ifdef MIDI_ENABLE
45#include "qmk_midi.h" 45#include "qmk_midi.h"
46#endif 46#endif
47#ifdef STM32F303xC
48#include "eeprom_stm32.h"
49#endif
47#include "suspend.h" 50#include "suspend.h"
48#include "wait.h" 51#include "wait.h"
49 52
@@ -109,6 +112,10 @@ int main(void) {
109 halInit(); 112 halInit();
110 chSysInit(); 113 chSysInit();
111 114
115#ifdef STM32F303xC
116 EEPROM_init();
117#endif
118
112 // TESTING 119 // TESTING
113 // chThdCreateStatic(waThread1, sizeof(waThread1), NORMALPRIO, Thread1, NULL); 120 // chThdCreateStatic(waThread1, sizeof(waThread1), NORMALPRIO, Thread1, NULL);
114 121