diff options
Diffstat (limited to 'tmk_core/common')
-rw-r--r-- | tmk_core/common/action_tapping.c | 2 | ||||
-rw-r--r-- | tmk_core/common/avr/sleep_led.c (renamed from tmk_core/common/sleep_led.c) | 0 | ||||
-rw-r--r-- | tmk_core/common/bootmagic.c | 7 | ||||
-rw-r--r-- | tmk_core/common/chibios/bootloader.c | 47 | ||||
-rw-r--r-- | tmk_core/common/chibios/eeprom.c | 588 | ||||
-rw-r--r-- | tmk_core/common/chibios/printf.c | 240 | ||||
-rw-r--r-- | tmk_core/common/chibios/printf.h | 111 | ||||
-rw-r--r-- | tmk_core/common/chibios/sleep_led.c | 226 | ||||
-rw-r--r-- | tmk_core/common/chibios/suspend.c | 65 | ||||
-rw-r--r-- | tmk_core/common/chibios/timer.c | 27 | ||||
-rw-r--r-- | tmk_core/common/command.c | 23 | ||||
-rw-r--r-- | tmk_core/common/eeconfig.c (renamed from tmk_core/common/avr/eeconfig.c) | 2 | ||||
-rw-r--r-- | tmk_core/common/eeprom.h | 22 | ||||
-rw-r--r-- | tmk_core/common/magic.c | 4 | ||||
-rw-r--r-- | tmk_core/common/print.c | 8 | ||||
-rw-r--r-- | tmk_core/common/print.h | 10 | ||||
-rw-r--r-- | tmk_core/common/progmem.h | 4 | ||||
-rw-r--r-- | tmk_core/common/report.h | 5 | ||||
-rw-r--r-- | tmk_core/common/wait.h | 8 |
19 files changed, 1378 insertions, 21 deletions
diff --git a/tmk_core/common/action_tapping.c b/tmk_core/common/action_tapping.c index ff78d7f2a..e16e11be7 100644 --- a/tmk_core/common/action_tapping.c +++ b/tmk_core/common/action_tapping.c | |||
@@ -257,7 +257,7 @@ bool process_tapping(keyrecord_t *keyp) | |||
257 | return true; | 257 | return true; |
258 | } | 258 | } |
259 | } else { | 259 | } else { |
260 | if (!IS_NOEVENT(event)) debug("Tapping: other key just after tap.\n"); | 260 | if (!IS_NOEVENT(event)) debug("Tapping: other key just after tap.\n") {}; |
261 | process_record(keyp); | 261 | process_record(keyp); |
262 | return true; | 262 | return true; |
263 | } | 263 | } |
diff --git a/tmk_core/common/sleep_led.c b/tmk_core/common/avr/sleep_led.c index dab3eb0f3..dab3eb0f3 100644 --- a/tmk_core/common/sleep_led.c +++ b/tmk_core/common/avr/sleep_led.c | |||
diff --git a/tmk_core/common/bootmagic.c b/tmk_core/common/bootmagic.c index 30e8a0f20..90275a18b 100644 --- a/tmk_core/common/bootmagic.c +++ b/tmk_core/common/bootmagic.c | |||
@@ -1,6 +1,6 @@ | |||
1 | #include <stdint.h> | 1 | #include <stdint.h> |
2 | #include <stdbool.h> | 2 | #include <stdbool.h> |
3 | #include <util/delay.h> | 3 | #include "wait.h" |
4 | #include "matrix.h" | 4 | #include "matrix.h" |
5 | #include "bootloader.h" | 5 | #include "bootloader.h" |
6 | #include "debug.h" | 6 | #include "debug.h" |
@@ -10,6 +10,7 @@ | |||
10 | #include "eeconfig.h" | 10 | #include "eeconfig.h" |
11 | #include "bootmagic.h" | 11 | #include "bootmagic.h" |
12 | 12 | ||
13 | keymap_config_t keymap_config; | ||
13 | 14 | ||
14 | void bootmagic(void) | 15 | void bootmagic(void) |
15 | { | 16 | { |
@@ -19,9 +20,9 @@ void bootmagic(void) | |||
19 | } | 20 | } |
20 | 21 | ||
21 | /* do scans in case of bounce */ | 22 | /* do scans in case of bounce */ |
22 | print("boogmagic scan: ... "); | 23 | print("bootmagic scan: ... "); |
23 | uint8_t scan = 100; | 24 | uint8_t scan = 100; |
24 | while (scan--) { matrix_scan(); _delay_ms(10); } | 25 | while (scan--) { matrix_scan(); wait_ms(10); } |
25 | print("done.\n"); | 26 | print("done.\n"); |
26 | 27 | ||
27 | /* bootmagic skip */ | 28 | /* bootmagic skip */ |
diff --git a/tmk_core/common/chibios/bootloader.c b/tmk_core/common/chibios/bootloader.c new file mode 100644 index 000000000..8a533ab6f --- /dev/null +++ b/tmk_core/common/chibios/bootloader.c | |||
@@ -0,0 +1,47 @@ | |||
1 | #include "bootloader.h" | ||
2 | |||
3 | #include "ch.h" | ||
4 | #include "hal.h" | ||
5 | |||
6 | #ifdef STM32_BOOTLOADER_ADDRESS | ||
7 | /* STM32 */ | ||
8 | |||
9 | #if defined(STM32F0XX) | ||
10 | /* This code should be checked whether it runs correctly on platforms */ | ||
11 | #define SYMVAL(sym) (uint32_t)(((uint8_t *)&(sym)) - ((uint8_t *)0)) | ||
12 | extern uint32_t __ram0_end__; | ||
13 | |||
14 | void bootloader_jump(void) { | ||
15 | *((unsigned long *)(SYMVAL(__ram0_end__) - 4)) = 0xDEADBEEF; // set magic flag => reset handler will jump into boot loader | ||
16 | NVIC_SystemReset(); | ||
17 | } | ||
18 | |||
19 | #else /* defined(STM32F0XX) */ | ||
20 | #error Check that the bootloader code works on your platform and add it to bootloader.c! | ||
21 | #endif /* defined(STM32F0XX) */ | ||
22 | |||
23 | #elif defined(KL2x) || defined(K20x) /* STM32_BOOTLOADER_ADDRESS */ | ||
24 | /* Kinetis */ | ||
25 | |||
26 | #if defined(KIIBOHD_BOOTLOADER) | ||
27 | /* Kiibohd Bootloader (MCHCK and Infinity KB) */ | ||
28 | #define SCB_AIRCR_VECTKEY_WRITEMAGIC 0x05FA0000 | ||
29 | const uint8_t sys_reset_to_loader_magic[] = "\xff\x00\x7fRESET TO LOADER\x7f\x00\xff"; | ||
30 | void bootloader_jump(void) { | ||
31 | __builtin_memcpy((void *)VBAT, (const void *)sys_reset_to_loader_magic, sizeof(sys_reset_to_loader_magic)); | ||
32 | // request reset | ||
33 | SCB->AIRCR = SCB_AIRCR_VECTKEY_WRITEMAGIC | SCB_AIRCR_SYSRESETREQ_Msk; | ||
34 | } | ||
35 | |||
36 | #else /* defined(KIIBOHD_BOOTLOADER) */ | ||
37 | /* Default for Kinetis - expecting an ARM Teensy */ | ||
38 | void bootloader_jump(void) { | ||
39 | chThdSleepMilliseconds(100); | ||
40 | __BKPT(0); | ||
41 | } | ||
42 | #endif /* defined(KIIBOHD_BOOTLOADER) */ | ||
43 | |||
44 | #else /* neither STM32 nor KINETIS */ | ||
45 | __attribute__((weak)) | ||
46 | void bootloader_jump(void) {} | ||
47 | #endif \ No newline at end of file | ||
diff --git a/tmk_core/common/chibios/eeprom.c b/tmk_core/common/chibios/eeprom.c new file mode 100644 index 000000000..5ff8ee86f --- /dev/null +++ b/tmk_core/common/chibios/eeprom.c | |||
@@ -0,0 +1,588 @@ | |||
1 | #include "ch.h" | ||
2 | #include "hal.h" | ||
3 | |||
4 | #include "eeconfig.h" | ||
5 | |||
6 | /*************************************/ | ||
7 | /* Hardware backend */ | ||
8 | /* */ | ||
9 | /* Code from PJRC/Teensyduino */ | ||
10 | /*************************************/ | ||
11 | |||
12 | /* Teensyduino Core Library | ||
13 | * http://www.pjrc.com/teensy/ | ||
14 | * Copyright (c) 2013 PJRC.COM, LLC. | ||
15 | * | ||
16 | * Permission is hereby granted, free of charge, to any person obtaining | ||
17 | * a copy of this software and associated documentation files (the | ||
18 | * "Software"), to deal in the Software without restriction, including | ||
19 | * without limitation the rights to use, copy, modify, merge, publish, | ||
20 | * distribute, sublicense, and/or sell copies of the Software, and to | ||
21 | * permit persons to whom the Software is furnished to do so, subject to | ||
22 | * the following conditions: | ||
23 | * | ||
24 | * 1. The above copyright notice and this permission notice shall be | ||
25 | * included in all copies or substantial portions of the Software. | ||
26 | * | ||
27 | * 2. If the Software is incorporated into a build system that allows | ||
28 | * selection among a list of target devices, then similar target | ||
29 | * devices manufactured by PJRC.COM must be included in the list of | ||
30 | * target devices and selectable in the same manner. | ||
31 | * | ||
32 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
33 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
34 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
35 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
36 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
37 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
38 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
39 | * SOFTWARE. | ||
40 | */ | ||
41 | |||
42 | |||
43 | #if defined(K20x) /* chip selection */ | ||
44 | /* Teensy 3.0, 3.1, 3.2; mchck; infinity keyboard */ | ||
45 | |||
46 | // The EEPROM is really RAM with a hardware-based backup system to | ||
47 | // flash memory. Selecting a smaller size EEPROM allows more wear | ||
48 | // leveling, for higher write endurance. If you edit this file, | ||
49 | // set this to the smallest size your application can use. Also, | ||
50 | // due to Freescale's implementation, writing 16 or 32 bit words | ||
51 | // (aligned to 2 or 4 byte boundaries) has twice the endurance | ||
52 | // compared to writing 8 bit bytes. | ||
53 | // | ||
54 | #define EEPROM_SIZE 32 | ||
55 | |||
56 | // Writing unaligned 16 or 32 bit data is handled automatically when | ||
57 | // this is defined, but at a cost of extra code size. Without this, | ||
58 | // any unaligned write will cause a hard fault exception! If you're | ||
59 | // absolutely sure all 16 and 32 bit writes will be aligned, you can | ||
60 | // remove the extra unnecessary code. | ||
61 | // | ||
62 | #define HANDLE_UNALIGNED_WRITES | ||
63 | |||
64 | // Minimum EEPROM Endurance | ||
65 | // ------------------------ | ||
66 | #if (EEPROM_SIZE == 2048) // 35000 writes/byte or 70000 writes/word | ||
67 | #define EEESIZE 0x33 | ||
68 | #elif (EEPROM_SIZE == 1024) // 75000 writes/byte or 150000 writes/word | ||
69 | #define EEESIZE 0x34 | ||
70 | #elif (EEPROM_SIZE == 512) // 155000 writes/byte or 310000 writes/word | ||
71 | #define EEESIZE 0x35 | ||
72 | #elif (EEPROM_SIZE == 256) // 315000 writes/byte or 630000 writes/word | ||
73 | #define EEESIZE 0x36 | ||
74 | #elif (EEPROM_SIZE == 128) // 635000 writes/byte or 1270000 writes/word | ||
75 | #define EEESIZE 0x37 | ||
76 | #elif (EEPROM_SIZE == 64) // 1275000 writes/byte or 2550000 writes/word | ||
77 | #define EEESIZE 0x38 | ||
78 | #elif (EEPROM_SIZE == 32) // 2555000 writes/byte or 5110000 writes/word | ||
79 | #define EEESIZE 0x39 | ||
80 | #endif | ||
81 | |||
82 | void eeprom_initialize(void) | ||
83 | { | ||
84 | uint32_t count=0; | ||
85 | uint16_t do_flash_cmd[] = { | ||
86 | 0xf06f, 0x037f, 0x7003, 0x7803, | ||
87 | 0xf013, 0x0f80, 0xd0fb, 0x4770}; | ||
88 | uint8_t status; | ||
89 | |||
90 | if (FTFL->FCNFG & FTFL_FCNFG_RAMRDY) { | ||
91 | // FlexRAM is configured as traditional RAM | ||
92 | // We need to reconfigure for EEPROM usage | ||
93 | FTFL->FCCOB0 = 0x80; // PGMPART = Program Partition Command | ||
94 | FTFL->FCCOB4 = EEESIZE; // EEPROM Size | ||
95 | FTFL->FCCOB5 = 0x03; // 0K for Dataflash, 32K for EEPROM backup | ||
96 | __disable_irq(); | ||
97 | // do_flash_cmd() must execute from RAM. Luckily the C syntax is simple... | ||
98 | (*((void (*)(volatile uint8_t *))((uint32_t)do_flash_cmd | 1)))(&(FTFL->FSTAT)); | ||
99 | __enable_irq(); | ||
100 | status = FTFL->FSTAT; | ||
101 | if (status & (FTFL_FSTAT_RDCOLERR|FTFL_FSTAT_ACCERR|FTFL_FSTAT_FPVIOL)) { | ||
102 | FTFL->FSTAT = (status & (FTFL_FSTAT_RDCOLERR|FTFL_FSTAT_ACCERR|FTFL_FSTAT_FPVIOL)); | ||
103 | return; // error | ||
104 | } | ||
105 | } | ||
106 | // wait for eeprom to become ready (is this really necessary?) | ||
107 | while (!(FTFL->FCNFG & FTFL_FCNFG_EEERDY)) { | ||
108 | if (++count > 20000) break; | ||
109 | } | ||
110 | } | ||
111 | |||
112 | #define FlexRAM ((uint8_t *)0x14000000) | ||
113 | |||
114 | uint8_t eeprom_read_byte(const uint8_t *addr) | ||
115 | { | ||
116 | uint32_t offset = (uint32_t)addr; | ||
117 | if (offset >= EEPROM_SIZE) return 0; | ||
118 | if (!(FTFL->FCNFG & FTFL_FCNFG_EEERDY)) eeprom_initialize(); | ||
119 | return FlexRAM[offset]; | ||
120 | } | ||
121 | |||
122 | uint16_t eeprom_read_word(const uint16_t *addr) | ||
123 | { | ||
124 | uint32_t offset = (uint32_t)addr; | ||
125 | if (offset >= EEPROM_SIZE-1) return 0; | ||
126 | if (!(FTFL->FCNFG & FTFL_FCNFG_EEERDY)) eeprom_initialize(); | ||
127 | return *(uint16_t *)(&FlexRAM[offset]); | ||
128 | } | ||
129 | |||
130 | uint32_t eeprom_read_dword(const uint32_t *addr) | ||
131 | { | ||
132 | uint32_t offset = (uint32_t)addr; | ||
133 | if (offset >= EEPROM_SIZE-3) return 0; | ||
134 | if (!(FTFL->FCNFG & FTFL_FCNFG_EEERDY)) eeprom_initialize(); | ||
135 | return *(uint32_t *)(&FlexRAM[offset]); | ||
136 | } | ||
137 | |||
138 | void eeprom_read_block(void *buf, const void *addr, uint32_t len) | ||
139 | { | ||
140 | uint32_t offset = (uint32_t)addr; | ||
141 | uint8_t *dest = (uint8_t *)buf; | ||
142 | uint32_t end = offset + len; | ||
143 | |||
144 | if (!(FTFL->FCNFG & FTFL_FCNFG_EEERDY)) eeprom_initialize(); | ||
145 | if (end > EEPROM_SIZE) end = EEPROM_SIZE; | ||
146 | while (offset < end) { | ||
147 | *dest++ = FlexRAM[offset++]; | ||
148 | } | ||
149 | } | ||
150 | |||
151 | int eeprom_is_ready(void) | ||
152 | { | ||
153 | return (FTFL->FCNFG & FTFL_FCNFG_EEERDY) ? 1 : 0; | ||
154 | } | ||
155 | |||
156 | static void flexram_wait(void) | ||
157 | { | ||
158 | while (!(FTFL->FCNFG & FTFL_FCNFG_EEERDY)) { | ||
159 | // TODO: timeout | ||
160 | } | ||
161 | } | ||
162 | |||
163 | void eeprom_write_byte(uint8_t *addr, uint8_t value) | ||
164 | { | ||
165 | uint32_t offset = (uint32_t)addr; | ||
166 | |||
167 | if (offset >= EEPROM_SIZE) return; | ||
168 | if (!(FTFL->FCNFG & FTFL_FCNFG_EEERDY)) eeprom_initialize(); | ||
169 | if (FlexRAM[offset] != value) { | ||
170 | FlexRAM[offset] = value; | ||
171 | flexram_wait(); | ||
172 | } | ||
173 | } | ||
174 | |||
175 | void eeprom_write_word(uint16_t *addr, uint16_t value) | ||
176 | { | ||
177 | uint32_t offset = (uint32_t)addr; | ||
178 | |||
179 | if (offset >= EEPROM_SIZE-1) return; | ||
180 | if (!(FTFL->FCNFG & FTFL_FCNFG_EEERDY)) eeprom_initialize(); | ||
181 | #ifdef HANDLE_UNALIGNED_WRITES | ||
182 | if ((offset & 1) == 0) { | ||
183 | #endif | ||
184 | if (*(uint16_t *)(&FlexRAM[offset]) != value) { | ||
185 | *(uint16_t *)(&FlexRAM[offset]) = value; | ||
186 | flexram_wait(); | ||
187 | } | ||
188 | #ifdef HANDLE_UNALIGNED_WRITES | ||
189 | } else { | ||
190 | if (FlexRAM[offset] != value) { | ||
191 | FlexRAM[offset] = value; | ||
192 | flexram_wait(); | ||
193 | } | ||
194 | if (FlexRAM[offset + 1] != (value >> 8)) { | ||
195 | FlexRAM[offset + 1] = value >> 8; | ||
196 | flexram_wait(); | ||
197 | } | ||
198 | } | ||
199 | #endif | ||
200 | } | ||
201 | |||
202 | void eeprom_write_dword(uint32_t *addr, uint32_t value) | ||
203 | { | ||
204 | uint32_t offset = (uint32_t)addr; | ||
205 | |||
206 | if (offset >= EEPROM_SIZE-3) return; | ||
207 | if (!(FTFL->FCNFG & FTFL_FCNFG_EEERDY)) eeprom_initialize(); | ||
208 | #ifdef HANDLE_UNALIGNED_WRITES | ||
209 | switch (offset & 3) { | ||
210 | case 0: | ||
211 | #endif | ||
212 | if (*(uint32_t *)(&FlexRAM[offset]) != value) { | ||
213 | *(uint32_t *)(&FlexRAM[offset]) = value; | ||
214 | flexram_wait(); | ||
215 | } | ||
216 | return; | ||
217 | #ifdef HANDLE_UNALIGNED_WRITES | ||
218 | case 2: | ||
219 | if (*(uint16_t *)(&FlexRAM[offset]) != value) { | ||
220 | *(uint16_t *)(&FlexRAM[offset]) = value; | ||
221 | flexram_wait(); | ||
222 | } | ||
223 | if (*(uint16_t *)(&FlexRAM[offset + 2]) != (value >> 16)) { | ||
224 | *(uint16_t *)(&FlexRAM[offset + 2]) = value >> 16; | ||
225 | flexram_wait(); | ||
226 | } | ||
227 | return; | ||
228 | default: | ||
229 | if (FlexRAM[offset] != value) { | ||
230 | FlexRAM[offset] = value; | ||
231 | flexram_wait(); | ||
232 | } | ||
233 | if (*(uint16_t *)(&FlexRAM[offset + 1]) != (value >> 8)) { | ||
234 | *(uint16_t *)(&FlexRAM[offset + 1]) = value >> 8; | ||
235 | flexram_wait(); | ||
236 | } | ||
237 | if (FlexRAM[offset + 3] != (value >> 24)) { | ||
238 | FlexRAM[offset + 3] = value >> 24; | ||
239 | flexram_wait(); | ||
240 | } | ||
241 | } | ||
242 | #endif | ||
243 | } | ||
244 | |||
245 | void eeprom_write_block(const void *buf, void *addr, uint32_t len) | ||
246 | { | ||
247 | uint32_t offset = (uint32_t)addr; | ||
248 | const uint8_t *src = (const uint8_t *)buf; | ||
249 | |||
250 | if (offset >= EEPROM_SIZE) return; | ||
251 | if (!(FTFL->FCNFG & FTFL_FCNFG_EEERDY)) eeprom_initialize(); | ||
252 | if (len >= EEPROM_SIZE) len = EEPROM_SIZE; | ||
253 | if (offset + len >= EEPROM_SIZE) len = EEPROM_SIZE - offset; | ||
254 | while (len > 0) { | ||
255 | uint32_t lsb = offset & 3; | ||
256 | if (lsb == 0 && len >= 4) { | ||
257 | // write aligned 32 bits | ||
258 | uint32_t val32; | ||
259 | val32 = *src++; | ||
260 | val32 |= (*src++ << 8); | ||
261 | val32 |= (*src++ << 16); | ||
262 | val32 |= (*src++ << 24); | ||
263 | if (*(uint32_t *)(&FlexRAM[offset]) != val32) { | ||
264 | *(uint32_t *)(&FlexRAM[offset]) = val32; | ||
265 | flexram_wait(); | ||
266 | } | ||
267 | offset += 4; | ||
268 | len -= 4; | ||
269 | } else if ((lsb == 0 || lsb == 2) && len >= 2) { | ||
270 | // write aligned 16 bits | ||
271 | uint16_t val16; | ||
272 | val16 = *src++; | ||
273 | val16 |= (*src++ << 8); | ||
274 | if (*(uint16_t *)(&FlexRAM[offset]) != val16) { | ||
275 | *(uint16_t *)(&FlexRAM[offset]) = val16; | ||
276 | flexram_wait(); | ||
277 | } | ||
278 | offset += 2; | ||
279 | len -= 2; | ||
280 | } else { | ||
281 | // write 8 bits | ||
282 | uint8_t val8 = *src++; | ||
283 | if (FlexRAM[offset] != val8) { | ||
284 | FlexRAM[offset] = val8; | ||
285 | flexram_wait(); | ||
286 | } | ||
287 | offset++; | ||
288 | len--; | ||
289 | } | ||
290 | } | ||
291 | } | ||
292 | |||
293 | /* | ||
294 | void do_flash_cmd(volatile uint8_t *fstat) | ||
295 | { | ||
296 | *fstat = 0x80; | ||
297 | while ((*fstat & 0x80) == 0) ; // wait | ||
298 | } | ||
299 | 00000000 <do_flash_cmd>: | ||
300 | 0: f06f 037f mvn.w r3, #127 ; 0x7f | ||
301 | 4: 7003 strb r3, [r0, #0] | ||
302 | 6: 7803 ldrb r3, [r0, #0] | ||
303 | 8: f013 0f80 tst.w r3, #128 ; 0x80 | ||
304 | c: d0fb beq.n 6 <do_flash_cmd+0x6> | ||
305 | e: 4770 bx lr | ||
306 | */ | ||
307 | |||
308 | #elif defined(KL2x) /* chip selection */ | ||
309 | /* Teensy LC (emulated) */ | ||
310 | |||
311 | #define SYMVAL(sym) (uint32_t)(((uint8_t *)&(sym)) - ((uint8_t *)0)) | ||
312 | |||
313 | extern uint32_t __eeprom_workarea_start__; | ||
314 | extern uint32_t __eeprom_workarea_end__; | ||
315 | |||
316 | #define EEPROM_SIZE 128 | ||
317 | |||
318 | static uint32_t flashend = 0; | ||
319 | |||
320 | void eeprom_initialize(void) | ||
321 | { | ||
322 | const uint16_t *p = (uint16_t *)SYMVAL(__eeprom_workarea_start__); | ||
323 | |||
324 | do { | ||
325 | if (*p++ == 0xFFFF) { | ||
326 | flashend = (uint32_t)(p - 2); | ||
327 | return; | ||
328 | } | ||
329 | } while (p < (uint16_t *)SYMVAL(__eeprom_workarea_end__)); | ||
330 | flashend = (uint32_t)((uint16_t *)SYMVAL(__eeprom_workarea_end__) - 1); | ||
331 | } | ||
332 | |||
333 | uint8_t eeprom_read_byte(const uint8_t *addr) | ||
334 | { | ||
335 | uint32_t offset = (uint32_t)addr; | ||
336 | const uint16_t *p = (uint16_t *)SYMVAL(__eeprom_workarea_start__); | ||
337 | const uint16_t *end = (const uint16_t *)((uint32_t)flashend); | ||
338 | uint16_t val; | ||
339 | uint8_t data=0xFF; | ||
340 | |||
341 | if (!end) { | ||
342 | eeprom_initialize(); | ||
343 | end = (const uint16_t *)((uint32_t)flashend); | ||
344 | } | ||
345 | if (offset < EEPROM_SIZE) { | ||
346 | while (p <= end) { | ||
347 | val = *p++; | ||
348 | if ((val & 255) == offset) data = val >> 8; | ||
349 | } | ||
350 | } | ||
351 | return data; | ||
352 | } | ||
353 | |||
354 | static void flash_write(const uint16_t *code, uint32_t addr, uint32_t data) | ||
355 | { | ||
356 | // with great power comes great responsibility.... | ||
357 | uint32_t stat; | ||
358 | *(uint32_t *)&(FTFA->FCCOB3) = 0x06000000 | (addr & 0x00FFFFFC); | ||
359 | *(uint32_t *)&(FTFA->FCCOB7) = data; | ||
360 | __disable_irq(); | ||
361 | (*((void (*)(volatile uint8_t *))((uint32_t)code | 1)))(&(FTFA->FSTAT)); | ||
362 | __enable_irq(); | ||
363 | stat = FTFA->FSTAT & (FTFA_FSTAT_RDCOLERR|FTFA_FSTAT_ACCERR|FTFA_FSTAT_FPVIOL); | ||
364 | if (stat) { | ||
365 | FTFA->FSTAT = stat; | ||
366 | } | ||
367 | MCM->PLACR |= MCM_PLACR_CFCC; | ||
368 | } | ||
369 | |||
370 | void eeprom_write_byte(uint8_t *addr, uint8_t data) | ||
371 | { | ||
372 | uint32_t offset = (uint32_t)addr; | ||
373 | const uint16_t *p, *end = (const uint16_t *)((uint32_t)flashend); | ||
374 | uint32_t i, val, flashaddr; | ||
375 | uint16_t do_flash_cmd[] = { | ||
376 | 0x2380, 0x7003, 0x7803, 0xb25b, 0x2b00, 0xdafb, 0x4770}; | ||
377 | uint8_t buf[EEPROM_SIZE]; | ||
378 | |||
379 | if (offset >= EEPROM_SIZE) return; | ||
380 | if (!end) { | ||
381 | eeprom_initialize(); | ||
382 | end = (const uint16_t *)((uint32_t)flashend); | ||
383 | } | ||
384 | if (++end < (uint16_t *)SYMVAL(__eeprom_workarea_end__)) { | ||
385 | val = (data << 8) | offset; | ||
386 | flashaddr = (uint32_t)end; | ||
387 | flashend = flashaddr; | ||
388 | if ((flashaddr & 2) == 0) { | ||
389 | val |= 0xFFFF0000; | ||
390 | } else { | ||
391 | val <<= 16; | ||
392 | val |= 0x0000FFFF; | ||
393 | } | ||
394 | flash_write(do_flash_cmd, flashaddr, val); | ||
395 | } else { | ||
396 | for (i=0; i < EEPROM_SIZE; i++) { | ||
397 | buf[i] = 0xFF; | ||
398 | } | ||
399 | val = 0; | ||
400 | for (p = (uint16_t *)SYMVAL(__eeprom_workarea_start__); p < (uint16_t *)SYMVAL(__eeprom_workarea_end__); p++) { | ||
401 | val = *p; | ||
402 | if ((val & 255) < EEPROM_SIZE) { | ||
403 | buf[val & 255] = val >> 8; | ||
404 | } | ||
405 | } | ||
406 | buf[offset] = data; | ||
407 | for (flashaddr=(uint32_t)(uint16_t *)SYMVAL(__eeprom_workarea_start__); flashaddr < (uint32_t)(uint16_t *)SYMVAL(__eeprom_workarea_end__); flashaddr += 1024) { | ||
408 | *(uint32_t *)&(FTFA->FCCOB3) = 0x09000000 | flashaddr; | ||
409 | __disable_irq(); | ||
410 | (*((void (*)(volatile uint8_t *))((uint32_t)do_flash_cmd | 1)))(&(FTFA->FSTAT)); | ||
411 | __enable_irq(); | ||
412 | val = FTFA->FSTAT & (FTFA_FSTAT_RDCOLERR|FTFA_FSTAT_ACCERR|FTFA_FSTAT_FPVIOL);; | ||
413 | if (val) FTFA->FSTAT = val; | ||
414 | MCM->PLACR |= MCM_PLACR_CFCC; | ||
415 | } | ||
416 | flashaddr=(uint32_t)(uint16_t *)SYMVAL(__eeprom_workarea_start__); | ||
417 | for (i=0; i < EEPROM_SIZE; i++) { | ||
418 | if (buf[i] == 0xFF) continue; | ||
419 | if ((flashaddr & 2) == 0) { | ||
420 | val = (buf[i] << 8) | i; | ||
421 | } else { | ||
422 | val = val | (buf[i] << 24) | (i << 16); | ||
423 | flash_write(do_flash_cmd, flashaddr, val); | ||
424 | } | ||
425 | flashaddr += 2; | ||
426 | } | ||
427 | flashend = flashaddr; | ||
428 | if ((flashaddr & 2)) { | ||
429 | val |= 0xFFFF0000; | ||
430 | flash_write(do_flash_cmd, flashaddr, val); | ||
431 | } | ||
432 | } | ||
433 | } | ||
434 | |||
435 | /* | ||
436 | void do_flash_cmd(volatile uint8_t *fstat) | ||
437 | { | ||
438 | *fstat = 0x80; | ||
439 | while ((*fstat & 0x80) == 0) ; // wait | ||
440 | } | ||
441 | 00000000 <do_flash_cmd>: | ||
442 | 0: 2380 movs r3, #128 ; 0x80 | ||
443 | 2: 7003 strb r3, [r0, #0] | ||
444 | 4: 7803 ldrb r3, [r0, #0] | ||
445 | 6: b25b sxtb r3, r3 | ||
446 | 8: 2b00 cmp r3, #0 | ||
447 | a: dafb bge.n 4 <do_flash_cmd+0x4> | ||
448 | c: 4770 bx lr | ||
449 | */ | ||
450 | |||
451 | |||
452 | uint16_t eeprom_read_word(const uint16_t *addr) | ||
453 | { | ||
454 | const uint8_t *p = (const uint8_t *)addr; | ||
455 | return eeprom_read_byte(p) | (eeprom_read_byte(p+1) << 8); | ||
456 | } | ||
457 | |||
458 | uint32_t eeprom_read_dword(const uint32_t *addr) | ||
459 | { | ||
460 | const uint8_t *p = (const uint8_t *)addr; | ||
461 | return eeprom_read_byte(p) | (eeprom_read_byte(p+1) << 8) | ||
462 | | (eeprom_read_byte(p+2) << 16) | (eeprom_read_byte(p+3) << 24); | ||
463 | } | ||
464 | |||
465 | void eeprom_read_block(void *buf, const void *addr, uint32_t len) | ||
466 | { | ||
467 | const uint8_t *p = (const uint8_t *)addr; | ||
468 | uint8_t *dest = (uint8_t *)buf; | ||
469 | while (len--) { | ||
470 | *dest++ = eeprom_read_byte(p++); | ||
471 | } | ||
472 | } | ||
473 | |||
474 | int eeprom_is_ready(void) | ||
475 | { | ||
476 | return 1; | ||
477 | } | ||
478 | |||
479 | void eeprom_write_word(uint16_t *addr, uint16_t value) | ||
480 | { | ||
481 | uint8_t *p = (uint8_t *)addr; | ||
482 | eeprom_write_byte(p++, value); | ||
483 | eeprom_write_byte(p, value >> 8); | ||
484 | } | ||
485 | |||
486 | void eeprom_write_dword(uint32_t *addr, uint32_t value) | ||
487 | { | ||
488 | uint8_t *p = (uint8_t *)addr; | ||
489 | eeprom_write_byte(p++, value); | ||
490 | eeprom_write_byte(p++, value >> 8); | ||
491 | eeprom_write_byte(p++, value >> 16); | ||
492 | eeprom_write_byte(p, value >> 24); | ||
493 | } | ||
494 | |||
495 | void eeprom_write_block(const void *buf, void *addr, uint32_t len) | ||
496 | { | ||
497 | uint8_t *p = (uint8_t *)addr; | ||
498 | const uint8_t *src = (const uint8_t *)buf; | ||
499 | while (len--) { | ||
500 | eeprom_write_byte(p++, *src++); | ||
501 | } | ||
502 | } | ||
503 | |||
504 | #else | ||
505 | // No EEPROM supported, so emulate it | ||
506 | |||
507 | #define EEPROM_SIZE 32 | ||
508 | static uint8_t buffer[EEPROM_SIZE]; | ||
509 | |||
510 | uint8_t eeprom_read_byte(const uint8_t *addr) { | ||
511 | uint32_t offset = (uint32_t)addr; | ||
512 | return buffer[offset]; | ||
513 | } | ||
514 | |||
515 | void eeprom_write_byte(uint8_t *addr, uint8_t value) { | ||
516 | uint32_t offset = (uint32_t)addr; | ||
517 | buffer[offset] = value; | ||
518 | } | ||
519 | |||
520 | uint16_t eeprom_read_word(const uint16_t *addr) { | ||
521 | const uint8_t *p = (const uint8_t *)addr; | ||
522 | return eeprom_read_byte(p) | (eeprom_read_byte(p+1) << 8); | ||
523 | } | ||
524 | |||
525 | uint32_t eeprom_read_dword(const uint32_t *addr) { | ||
526 | const uint8_t *p = (const uint8_t *)addr; | ||
527 | return eeprom_read_byte(p) | (eeprom_read_byte(p+1) << 8) | ||
528 | | (eeprom_read_byte(p+2) << 16) | (eeprom_read_byte(p+3) << 24); | ||
529 | } | ||
530 | |||
531 | void eeprom_read_block(void *buf, const void *addr, uint32_t len) { | ||
532 | const uint8_t *p = (const uint8_t *)addr; | ||
533 | uint8_t *dest = (uint8_t *)buf; | ||
534 | while (len--) { | ||
535 | *dest++ = eeprom_read_byte(p++); | ||
536 | } | ||
537 | } | ||
538 | |||
539 | void eeprom_write_word(uint16_t *addr, uint16_t value) { | ||
540 | uint8_t *p = (uint8_t *)addr; | ||
541 | eeprom_write_byte(p++, value); | ||
542 | eeprom_write_byte(p, value >> 8); | ||
543 | } | ||
544 | |||
545 | void eeprom_write_dword(uint32_t *addr, uint32_t value) { | ||
546 | uint8_t *p = (uint8_t *)addr; | ||
547 | eeprom_write_byte(p++, value); | ||
548 | eeprom_write_byte(p++, value >> 8); | ||
549 | eeprom_write_byte(p++, value >> 16); | ||
550 | eeprom_write_byte(p, value >> 24); | ||
551 | } | ||
552 | |||
553 | void eeprom_write_block(const void *buf, void *addr, uint32_t len) { | ||
554 | uint8_t *p = (uint8_t *)addr; | ||
555 | const uint8_t *src = (const uint8_t *)buf; | ||
556 | while (len--) { | ||
557 | eeprom_write_byte(p++, *src++); | ||
558 | } | ||
559 | } | ||
560 | |||
561 | #endif /* chip selection */ | ||
562 | // The update functions just calls write for now, but could probably be optimized | ||
563 | |||
564 | void eeprom_update_byte(uint8_t *addr, uint8_t value) { | ||
565 | eeprom_write_byte(addr, value); | ||
566 | } | ||
567 | |||
568 | void eeprom_update_word(uint16_t *addr, uint16_t value) { | ||
569 | uint8_t *p = (uint8_t *)addr; | ||
570 | eeprom_write_byte(p++, value); | ||
571 | eeprom_write_byte(p, value >> 8); | ||
572 | } | ||
573 | |||
574 | void eeprom_update_dword(uint32_t *addr, uint32_t value) { | ||
575 | uint8_t *p = (uint8_t *)addr; | ||
576 | eeprom_write_byte(p++, value); | ||
577 | eeprom_write_byte(p++, value >> 8); | ||
578 | eeprom_write_byte(p++, value >> 16); | ||
579 | eeprom_write_byte(p, value >> 24); | ||
580 | } | ||
581 | |||
582 | void eeprom_update_block(const void *buf, void *addr, uint32_t len) { | ||
583 | uint8_t *p = (uint8_t *)addr; | ||
584 | const uint8_t *src = (const uint8_t *)buf; | ||
585 | while (len--) { | ||
586 | eeprom_write_byte(p++, *src++); | ||
587 | } | ||
588 | } | ||
diff --git a/tmk_core/common/chibios/printf.c b/tmk_core/common/chibios/printf.c new file mode 100644 index 000000000..72e3d4f8c --- /dev/null +++ b/tmk_core/common/chibios/printf.c | |||
@@ -0,0 +1,240 @@ | |||
1 | /* | ||
2 | * found at: http://www.sparetimelabs.com/tinyprintf/tinyprintf.php | ||
3 | * and: http://www.sparetimelabs.com/printfrevisited/printfrevisited.php | ||
4 | */ | ||
5 | |||
6 | /* | ||
7 | File: printf.c | ||
8 | |||
9 | Copyright (C) 2004 Kustaa Nyholm | ||
10 | |||
11 | This library is free software; you can redistribute it and/or | ||
12 | modify it under the terms of the GNU Lesser General Public | ||
13 | License as published by the Free Software Foundation; either | ||
14 | version 2.1 of the License, or (at your option) any later version. | ||
15 | |||
16 | This library is distributed in the hope that it will be useful, | ||
17 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
18 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
19 | Lesser General Public License for more details. | ||
20 | |||
21 | You should have received a copy of the GNU Lesser General Public | ||
22 | License along with this library; if not, write to the Free Software | ||
23 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
24 | |||
25 | */ | ||
26 | |||
27 | #include "printf.h" | ||
28 | |||
29 | typedef void (*putcf) (void*,char); | ||
30 | static putcf stdout_putf; | ||
31 | static void* stdout_putp; | ||
32 | |||
33 | // this adds cca 400 bytes | ||
34 | #define PRINTF_LONG_SUPPORT | ||
35 | |||
36 | #ifdef PRINTF_LONG_SUPPORT | ||
37 | |||
38 | static void uli2a(unsigned long int num, unsigned int base, int uc,char * bf) | ||
39 | { | ||
40 | int n=0; | ||
41 | unsigned int d=1; | ||
42 | while (num/d >= base) | ||
43 | d*=base; | ||
44 | while (d!=0) { | ||
45 | int dgt = num / d; | ||
46 | num%=d; | ||
47 | d/=base; | ||
48 | if (n || dgt>0|| d==0) { | ||
49 | *bf++ = dgt+(dgt<10 ? '0' : (uc ? 'A' : 'a')-10); | ||
50 | ++n; | ||
51 | } | ||
52 | } | ||
53 | *bf=0; | ||
54 | } | ||
55 | |||
56 | static void li2a (long num, char * bf) | ||
57 | { | ||
58 | if (num<0) { | ||
59 | num=-num; | ||
60 | *bf++ = '-'; | ||
61 | } | ||
62 | uli2a(num,10,0,bf); | ||
63 | } | ||
64 | |||
65 | #endif | ||
66 | |||
67 | static void ui2a(unsigned int num, unsigned int base, int uc,char * bf) | ||
68 | { | ||
69 | int n=0; | ||
70 | unsigned int d=1; | ||
71 | while (num/d >= base) | ||
72 | d*=base; | ||
73 | while (d!=0) { | ||
74 | int dgt = num / d; | ||
75 | num%= d; | ||
76 | d/=base; | ||
77 | if (n || dgt>0 || d==0) { | ||
78 | *bf++ = dgt+(dgt<10 ? '0' : (uc ? 'A' : 'a')-10); | ||
79 | ++n; | ||
80 | } | ||
81 | } | ||
82 | *bf=0; | ||
83 | } | ||
84 | |||
85 | static void i2a (int num, char * bf) | ||
86 | { | ||
87 | if (num<0) { | ||
88 | num=-num; | ||
89 | *bf++ = '-'; | ||
90 | } | ||
91 | ui2a(num,10,0,bf); | ||
92 | } | ||
93 | |||
94 | static int a2d(char ch) | ||
95 | { | ||
96 | if (ch>='0' && ch<='9') | ||
97 | return ch-'0'; | ||
98 | else if (ch>='a' && ch<='f') | ||
99 | return ch-'a'+10; | ||
100 | else if (ch>='A' && ch<='F') | ||
101 | return ch-'A'+10; | ||
102 | else return -1; | ||
103 | } | ||
104 | |||
105 | static char a2i(char ch, char** src,int base,int* nump) | ||
106 | { | ||
107 | char* p= *src; | ||
108 | int num=0; | ||
109 | int digit; | ||
110 | while ((digit=a2d(ch))>=0) { | ||
111 | if (digit>base) break; | ||
112 | num=num*base+digit; | ||
113 | ch=*p++; | ||
114 | } | ||
115 | *src=p; | ||
116 | *nump=num; | ||
117 | return ch; | ||
118 | } | ||
119 | |||
120 | static void putchw(void* putp,putcf putf,int n, char z, char* bf) | ||
121 | { | ||
122 | char fc=z? '0' : ' '; | ||
123 | char ch; | ||
124 | char* p=bf; | ||
125 | while (*p++ && n > 0) | ||
126 | n--; | ||
127 | while (n-- > 0) | ||
128 | putf(putp,fc); | ||
129 | while ((ch= *bf++)) | ||
130 | putf(putp,ch); | ||
131 | } | ||
132 | |||
133 | void tfp_format(void* putp,putcf putf,char *fmt, va_list va) | ||
134 | { | ||
135 | char bf[12]; | ||
136 | |||
137 | char ch; | ||
138 | |||
139 | |||
140 | while ((ch=*(fmt++))) { | ||
141 | if (ch!='%') | ||
142 | putf(putp,ch); | ||
143 | else { | ||
144 | char lz=0; | ||
145 | #ifdef PRINTF_LONG_SUPPORT | ||
146 | char lng=0; | ||
147 | #endif | ||
148 | int w=0; | ||
149 | ch=*(fmt++); | ||
150 | if (ch=='0') { | ||
151 | ch=*(fmt++); | ||
152 | lz=1; | ||
153 | } | ||
154 | if (ch>='0' && ch<='9') { | ||
155 | ch=a2i(ch,&fmt,10,&w); | ||
156 | } | ||
157 | #ifdef PRINTF_LONG_SUPPORT | ||
158 | if (ch=='l') { | ||
159 | ch=*(fmt++); | ||
160 | lng=1; | ||
161 | } | ||
162 | #endif | ||
163 | switch (ch) { | ||
164 | case 0: | ||
165 | goto abort; | ||
166 | case 'u' : { | ||
167 | #ifdef PRINTF_LONG_SUPPORT | ||
168 | if (lng) | ||
169 | uli2a(va_arg(va, unsigned long int),10,0,bf); | ||
170 | else | ||
171 | #endif | ||
172 | ui2a(va_arg(va, unsigned int),10,0,bf); | ||
173 | putchw(putp,putf,w,lz,bf); | ||
174 | break; | ||
175 | } | ||
176 | case 'd' : { | ||
177 | #ifdef PRINTF_LONG_SUPPORT | ||
178 | if (lng) | ||
179 | li2a(va_arg(va, unsigned long int),bf); | ||
180 | else | ||
181 | #endif | ||
182 | i2a(va_arg(va, int),bf); | ||
183 | putchw(putp,putf,w,lz,bf); | ||
184 | break; | ||
185 | } | ||
186 | case 'x': case 'X' : | ||
187 | #ifdef PRINTF_LONG_SUPPORT | ||
188 | if (lng) | ||
189 | uli2a(va_arg(va, unsigned long int),16,(ch=='X'),bf); | ||
190 | else | ||
191 | #endif | ||
192 | ui2a(va_arg(va, unsigned int),16,(ch=='X'),bf); | ||
193 | putchw(putp,putf,w,lz,bf); | ||
194 | break; | ||
195 | case 'c' : | ||
196 | putf(putp,(char)(va_arg(va, int))); | ||
197 | break; | ||
198 | case 's' : | ||
199 | putchw(putp,putf,w,0,va_arg(va, char*)); | ||
200 | break; | ||
201 | case '%' : | ||
202 | putf(putp,ch); | ||
203 | default: | ||
204 | break; | ||
205 | } | ||
206 | } | ||
207 | } | ||
208 | abort:; | ||
209 | } | ||
210 | |||
211 | |||
212 | void init_printf(void* putp,void (*putf) (void*,char)) | ||
213 | { | ||
214 | stdout_putf=putf; | ||
215 | stdout_putp=putp; | ||
216 | } | ||
217 | |||
218 | void tfp_printf(char *fmt, ...) | ||
219 | { | ||
220 | va_list va; | ||
221 | va_start(va,fmt); | ||
222 | tfp_format(stdout_putp,stdout_putf,fmt,va); | ||
223 | va_end(va); | ||
224 | } | ||
225 | |||
226 | static void putcp(void* p,char c) | ||
227 | { | ||
228 | *(*((char**)p))++ = c; | ||
229 | } | ||
230 | |||
231 | |||
232 | |||
233 | void tfp_sprintf(char* s,char *fmt, ...) | ||
234 | { | ||
235 | va_list va; | ||
236 | va_start(va,fmt); | ||
237 | tfp_format(&s,putcp,fmt,va); | ||
238 | putcp(&s,0); | ||
239 | va_end(va); | ||
240 | } | ||
diff --git a/tmk_core/common/chibios/printf.h b/tmk_core/common/chibios/printf.h new file mode 100644 index 000000000..678a100c6 --- /dev/null +++ b/tmk_core/common/chibios/printf.h | |||
@@ -0,0 +1,111 @@ | |||
1 | /* | ||
2 | * found at: http://www.sparetimelabs.com/tinyprintf/tinyprintf.php | ||
3 | * and: http://www.sparetimelabs.com/printfrevisited/printfrevisited.php | ||
4 | */ | ||
5 | |||
6 | /* | ||
7 | File: printf.h | ||
8 | |||
9 | Copyright (C) 2004 Kustaa Nyholm | ||
10 | |||
11 | This library is free software; you can redistribute it and/or | ||
12 | modify it under the terms of the GNU Lesser General Public | ||
13 | License as published by the Free Software Foundation; either | ||
14 | version 2.1 of the License, or (at your option) any later version. | ||
15 | |||
16 | This library is distributed in the hope that it will be useful, | ||
17 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
18 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | ||
19 | See the GNU Lesser General Public License for more details. | ||
20 | |||
21 | You should have received a copy of the GNU Lesser General Public | ||
22 | License along with this library; if not, write to the Free Software | ||
23 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
24 | |||
25 | This library is realy just two files: 'printf.h' and 'printf.c'. | ||
26 | |||
27 | They provide a simple and small (+200 loc) printf functionality to | ||
28 | be used in embedded systems. | ||
29 | |||
30 | I've found them so usefull in debugging that I do not bother with a | ||
31 | debugger at all. | ||
32 | |||
33 | They are distributed in source form, so to use them, just compile them | ||
34 | into your project. | ||
35 | |||
36 | Two printf variants are provided: printf and sprintf. | ||
37 | |||
38 | The formats supported by this implementation are: 'd' 'u' 'c' 's' 'x' 'X'. | ||
39 | |||
40 | Zero padding and field width are also supported. | ||
41 | |||
42 | If the library is compiled with 'PRINTF_SUPPORT_LONG' defined then the | ||
43 | long specifier is also | ||
44 | supported. Note that this will pull in some long math routines (pun intended!) | ||
45 | and thus make your executable noticably longer. | ||
46 | |||
47 | The memory foot print of course depends on the target cpu, compiler and | ||
48 | compiler options, but a rough guestimate (based on a H8S target) is about | ||
49 | 1.4 kB for code and some twenty 'int's and 'char's, say 60 bytes of stack space. | ||
50 | Not too bad. Your milage may vary. By hacking the source code you can | ||
51 | get rid of some hunred bytes, I'm sure, but personally I feel the balance of | ||
52 | functionality and flexibility versus code size is close to optimal for | ||
53 | many embedded systems. | ||
54 | |||
55 | To use the printf you need to supply your own character output function, | ||
56 | something like : | ||
57 | |||
58 | void putc ( void* p, char c) | ||
59 | { | ||
60 | while (!SERIAL_PORT_EMPTY) ; | ||
61 | SERIAL_PORT_TX_REGISTER = c; | ||
62 | } | ||
63 | |||
64 | Before you can call printf you need to initialize it to use your | ||
65 | character output function with something like: | ||
66 | |||
67 | init_printf(NULL,putc); | ||
68 | |||
69 | Notice the 'NULL' in 'init_printf' and the parameter 'void* p' in 'putc', | ||
70 | the NULL (or any pointer) you pass into the 'init_printf' will eventually be | ||
71 | passed to your 'putc' routine. This allows you to pass some storage space (or | ||
72 | anything realy) to the character output function, if necessary. | ||
73 | This is not often needed but it was implemented like that because it made | ||
74 | implementing the sprintf function so neat (look at the source code). | ||
75 | |||
76 | The code is re-entrant, except for the 'init_printf' function, so it | ||
77 | is safe to call it from interupts too, although this may result in mixed output. | ||
78 | If you rely on re-entrancy, take care that your 'putc' function is re-entrant! | ||
79 | |||
80 | The printf and sprintf functions are actually macros that translate to | ||
81 | 'tfp_printf' and 'tfp_sprintf'. This makes it possible | ||
82 | to use them along with 'stdio.h' printf's in a single source file. | ||
83 | You just need to undef the names before you include the 'stdio.h'. | ||
84 | Note that these are not function like macros, so if you have variables | ||
85 | or struct members with these names, things will explode in your face. | ||
86 | Without variadic macros this is the best we can do to wrap these | ||
87 | fucnction. If it is a problem just give up the macros and use the | ||
88 | functions directly or rename them. | ||
89 | |||
90 | For further details see source code. | ||
91 | |||
92 | regs Kusti, 23.10.2004 | ||
93 | */ | ||
94 | |||
95 | |||
96 | #ifndef __TFP_PRINTF__ | ||
97 | #define __TFP_PRINTF__ | ||
98 | |||
99 | #include <stdarg.h> | ||
100 | |||
101 | void init_printf(void* putp,void (*putf) (void*,char)); | ||
102 | |||
103 | void tfp_printf(char *fmt, ...); | ||
104 | void tfp_sprintf(char* s,char *fmt, ...); | ||
105 | |||
106 | void tfp_format(void* putp,void (*putf) (void*,char),char *fmt, va_list va); | ||
107 | |||
108 | #define printf tfp_printf | ||
109 | #define sprintf tfp_sprintf | ||
110 | |||
111 | #endif | ||
diff --git a/tmk_core/common/chibios/sleep_led.c b/tmk_core/common/chibios/sleep_led.c new file mode 100644 index 000000000..4c35cfcba --- /dev/null +++ b/tmk_core/common/chibios/sleep_led.c | |||
@@ -0,0 +1,226 @@ | |||
1 | #include "ch.h" | ||
2 | #include "hal.h" | ||
3 | |||
4 | #include "led.h" | ||
5 | #include "sleep_led.h" | ||
6 | |||
7 | /* All right, we go the "software" way: timer, toggle LED in interrupt. | ||
8 | * Based on hasu's code for AVRs. | ||
9 | * Use LP timer on Kinetises, TIM14 on STM32F0. | ||
10 | */ | ||
11 | |||
12 | #if defined(KL2x) || defined(K20x) | ||
13 | |||
14 | /* Use Low Power Timer (LPTMR) */ | ||
15 | #define TIMER_INTERRUPT_VECTOR KINETIS_LPTMR0_IRQ_VECTOR | ||
16 | #define RESET_COUNTER LPTMR0->CSR |= LPTMRx_CSR_TCF | ||
17 | |||
18 | #elif defined(STM32F0XX) | ||
19 | |||
20 | /* Use TIM14 manually */ | ||
21 | #define TIMER_INTERRUPT_VECTOR STM32_TIM14_HANDLER | ||
22 | #define RESET_COUNTER STM32_TIM14->SR &= ~STM32_TIM_SR_UIF | ||
23 | |||
24 | #endif | ||
25 | |||
26 | #if defined(KL2x) || defined(K20x) || defined(STM32F0XX) /* common parts for timers/interrupts */ | ||
27 | |||
28 | /* Breathing Sleep LED brighness(PWM On period) table | ||
29 | * (64[steps] * 4[duration]) / 64[PWM periods/s] = 4 second breath cycle | ||
30 | * | ||
31 | * http://www.wolframalpha.com/input/?i=%28sin%28+x%2F64*pi%29**8+*+255%2C+x%3D0+to+63 | ||
32 | * (0..63).each {|x| p ((sin(x/64.0*PI)**8)*255).to_i } | ||
33 | */ | ||
34 | static const uint8_t breathing_table[64] = { | ||
35 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 4, 6, 10, | ||
36 | 15, 23, 32, 44, 58, 74, 93, 113, 135, 157, 179, 199, 218, 233, 245, 252, | ||
37 | 255, 252, 245, 233, 218, 199, 179, 157, 135, 113, 93, 74, 58, 44, 32, 23, | ||
38 | 15, 10, 6, 4, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 | ||
39 | }; | ||
40 | |||
41 | /* interrupt handler */ | ||
42 | OSAL_IRQ_HANDLER(TIMER_INTERRUPT_VECTOR) { | ||
43 | OSAL_IRQ_PROLOGUE(); | ||
44 | |||
45 | /* Software PWM | ||
46 | * timer:1111 1111 1111 1111 | ||
47 | * \_____/\/ \_______/____ count(0-255) | ||
48 | * \ \______________ duration of step(4) | ||
49 | * \__________________ index of step table(0-63) | ||
50 | */ | ||
51 | |||
52 | // this works for cca 65536 irqs/sec | ||
53 | static union { | ||
54 | uint16_t row; | ||
55 | struct { | ||
56 | uint8_t count:8; | ||
57 | uint8_t duration:2; | ||
58 | uint8_t index:6; | ||
59 | } pwm; | ||
60 | } timer = { .row = 0 }; | ||
61 | |||
62 | timer.row++; | ||
63 | |||
64 | // LED on | ||
65 | if (timer.pwm.count == 0) { | ||
66 | led_set(1<<USB_LED_CAPS_LOCK); | ||
67 | } | ||
68 | // LED off | ||
69 | if (timer.pwm.count == breathing_table[timer.pwm.index]) { | ||
70 | led_set(0); | ||
71 | } | ||
72 | |||
73 | /* Reset the counter */ | ||
74 | RESET_COUNTER; | ||
75 | |||
76 | OSAL_IRQ_EPILOGUE(); | ||
77 | } | ||
78 | |||
79 | #endif /* common parts for known platforms */ | ||
80 | |||
81 | |||
82 | #if defined(KL2x) || defined(K20x) /* platform selection: familiar Kinetis chips */ | ||
83 | |||
84 | /* LPTMR clock options */ | ||
85 | #define LPTMR_CLOCK_MCGIRCLK 0 /* 4MHz clock */ | ||
86 | #define LPTMR_CLOCK_LPO 1 /* 1kHz clock */ | ||
87 | #define LPTMR_CLOCK_ERCLK32K 2 /* external 32kHz crystal */ | ||
88 | #define LPTMR_CLOCK_OSCERCLK 3 /* output from OSC */ | ||
89 | |||
90 | /* Work around inconsistencies in Freescale naming */ | ||
91 | #if !defined(SIM_SCGC5_LPTMR) | ||
92 | #define SIM_SCGC5_LPTMR SIM_SCGC5_LPTIMER | ||
93 | #endif | ||
94 | |||
95 | /* Initialise the timer */ | ||
96 | void sleep_led_init(void) { | ||
97 | /* Make sure the clock to the LPTMR is enabled */ | ||
98 | SIM->SCGC5 |= SIM_SCGC5_LPTMR; | ||
99 | /* Reset LPTMR settings */ | ||
100 | LPTMR0->CSR = 0; | ||
101 | /* Set the compare value */ | ||
102 | LPTMR0->CMR = 0; // trigger on counter value (i.e. every time) | ||
103 | |||
104 | /* Set up clock source and prescaler */ | ||
105 | /* Software PWM | ||
106 | * ______ ______ __ | ||
107 | * | ON |___OFF___| ON |___OFF___| .... | ||
108 | * |<-------------->|<-------------->|<- .... | ||
109 | * PWM period PWM period | ||
110 | * | ||
111 | * R interrupts/period[resolution] | ||
112 | * F periods/second[frequency] | ||
113 | * R * F interrupts/second | ||
114 | */ | ||
115 | |||
116 | /* === OPTION 1 === */ | ||
117 | #if 0 | ||
118 | // 1kHz LPO | ||
119 | // No prescaler => 1024 irqs/sec | ||
120 | // Note: this is too slow for a smooth breathe | ||
121 | LPTMR0->PSR = LPTMRx_PSR_PCS(LPTMR_CLOCK_LPO)|LPTMRx_PSR_PBYP; | ||
122 | #endif /* OPTION 1 */ | ||
123 | |||
124 | /* === OPTION 2 === */ | ||
125 | #if 1 | ||
126 | // nMHz IRC (n=4 on KL25Z, KL26Z and K20x; n=2 or 8 on KL27Z) | ||
127 | MCG->C2 |= MCG_C2_IRCS; // fast (4MHz) internal ref clock | ||
128 | #if defined(KL27) // divide the 8MHz IRC by 2, to have the same MCGIRCLK speed as others | ||
129 | MCG->MC |= MCG_MC_LIRC_DIV2_DIV2; | ||
130 | #endif /* KL27 */ | ||
131 | MCG->C1 |= MCG_C1_IRCLKEN; // enable internal ref clock | ||
132 | // to work in stop mode, also MCG_C1_IREFSTEN | ||
133 | // Divide 4MHz by 2^N (N=6) => 62500 irqs/sec => | ||
134 | // => approx F=61, R=256, duration = 4 | ||
135 | LPTMR0->PSR = LPTMRx_PSR_PCS(LPTMR_CLOCK_MCGIRCLK)|LPTMRx_PSR_PRESCALE(6); | ||
136 | #endif /* OPTION 2 */ | ||
137 | |||
138 | /* === OPTION 3 === */ | ||
139 | #if 0 | ||
140 | // OSC output (external crystal), usually 8MHz or 16MHz | ||
141 | OSC0->CR |= OSC_CR_ERCLKEN; // enable ext ref clock | ||
142 | // to work in stop mode, also OSC_CR_EREFSTEN | ||
143 | // Divide by 2^N | ||
144 | LPTMR0->PSR = LPTMRx_PSR_PCS(LPTMR_CLOCK_OSCERCLK)|LPTMRx_PSR_PRESCALE(7); | ||
145 | #endif /* OPTION 3 */ | ||
146 | /* === END OPTIONS === */ | ||
147 | |||
148 | /* Interrupt on TCF set (compare flag) */ | ||
149 | nvicEnableVector(LPTMR0_IRQn, 2); // vector, priority | ||
150 | LPTMR0->CSR |= LPTMRx_CSR_TIE; | ||
151 | } | ||
152 | |||
153 | void sleep_led_enable(void) { | ||
154 | /* Enable the timer */ | ||
155 | LPTMR0->CSR |= LPTMRx_CSR_TEN; | ||
156 | } | ||
157 | |||
158 | void sleep_led_disable(void) { | ||
159 | /* Disable the timer */ | ||
160 | LPTMR0->CSR &= ~LPTMRx_CSR_TEN; | ||
161 | } | ||
162 | |||
163 | void sleep_led_toggle(void) { | ||
164 | /* Toggle the timer */ | ||
165 | LPTMR0->CSR ^= LPTMRx_CSR_TEN; | ||
166 | } | ||
167 | |||
168 | #elif defined(STM32F0XX) /* platform selection: STM32F0XX */ | ||
169 | |||
170 | /* Initialise the timer */ | ||
171 | void sleep_led_init(void) { | ||
172 | /* enable clock */ | ||
173 | rccEnableTIM14(FALSE); /* low power enable = FALSE */ | ||
174 | rccResetTIM14(); | ||
175 | |||
176 | /* prescale */ | ||
177 | /* Assuming 48MHz internal clock */ | ||
178 | /* getting cca 65484 irqs/sec */ | ||
179 | STM32_TIM14->PSC = 733; | ||
180 | |||
181 | /* auto-reload */ | ||
182 | /* 0 => interrupt every time */ | ||
183 | STM32_TIM14->ARR = 3; | ||
184 | |||
185 | /* enable counter update event interrupt */ | ||
186 | STM32_TIM14->DIER |= STM32_TIM_DIER_UIE; | ||
187 | |||
188 | /* register interrupt vector */ | ||
189 | nvicEnableVector(STM32_TIM14_NUMBER, 2); /* vector, priority */ | ||
190 | } | ||
191 | |||
192 | void sleep_led_enable(void) { | ||
193 | /* Enable the timer */ | ||
194 | STM32_TIM14->CR1 = STM32_TIM_CR1_CEN | STM32_TIM_CR1_URS; | ||
195 | /* URS => update event only on overflow; setting UG bit disabled */ | ||
196 | } | ||
197 | |||
198 | void sleep_led_disable(void) { | ||
199 | /* Disable the timer */ | ||
200 | STM32_TIM14->CR1 = 0; | ||
201 | } | ||
202 | |||
203 | void sleep_led_toggle(void) { | ||
204 | /* Toggle the timer */ | ||
205 | STM32_TIM14->CR1 ^= STM32_TIM_CR1_CEN; | ||
206 | } | ||
207 | |||
208 | |||
209 | #else /* platform selection: not on familiar chips */ | ||
210 | |||
211 | void sleep_led_init(void) { | ||
212 | } | ||
213 | |||
214 | void sleep_led_enable(void) { | ||
215 | led_set(1<<USB_LED_CAPS_LOCK); | ||
216 | } | ||
217 | |||
218 | void sleep_led_disable(void) { | ||
219 | led_set(0); | ||
220 | } | ||
221 | |||
222 | void sleep_led_toggle(void) { | ||
223 | // not implemented | ||
224 | } | ||
225 | |||
226 | #endif /* platform selection */ \ No newline at end of file | ||
diff --git a/tmk_core/common/chibios/suspend.c b/tmk_core/common/chibios/suspend.c new file mode 100644 index 000000000..6ca16034f --- /dev/null +++ b/tmk_core/common/chibios/suspend.c | |||
@@ -0,0 +1,65 @@ | |||
1 | /* TODO */ | ||
2 | |||
3 | #include "ch.h" | ||
4 | #include "hal.h" | ||
5 | |||
6 | #include "matrix.h" | ||
7 | #include "action.h" | ||
8 | #include "action_util.h" | ||
9 | #include "mousekey.h" | ||
10 | #include "host.h" | ||
11 | #include "backlight.h" | ||
12 | #include "suspend.h" | ||
13 | |||
14 | void suspend_idle(uint8_t time) { | ||
15 | // TODO: this is not used anywhere - what units is 'time' in? | ||
16 | chThdSleepMilliseconds(time); | ||
17 | } | ||
18 | |||
19 | void suspend_power_down(void) { | ||
20 | // TODO: figure out what to power down and how | ||
21 | // shouldn't power down TPM/FTM if we want a breathing LED | ||
22 | // also shouldn't power down USB | ||
23 | |||
24 | // on AVR, this enables the watchdog for 15ms (max), and goes to | ||
25 | // SLEEP_MODE_PWR_DOWN | ||
26 | |||
27 | chThdSleepMilliseconds(17); | ||
28 | } | ||
29 | |||
30 | __attribute__ ((weak)) void matrix_power_up(void) {} | ||
31 | __attribute__ ((weak)) void matrix_power_down(void) {} | ||
32 | bool suspend_wakeup_condition(void) | ||
33 | { | ||
34 | matrix_power_up(); | ||
35 | matrix_scan(); | ||
36 | matrix_power_down(); | ||
37 | for (uint8_t r = 0; r < MATRIX_ROWS; r++) { | ||
38 | if (matrix_get_row(r)) return true; | ||
39 | } | ||
40 | return false; | ||
41 | } | ||
42 | |||
43 | // run immediately after wakeup | ||
44 | void suspend_wakeup_init(void) | ||
45 | { | ||
46 | // clear keyboard state | ||
47 | // need to do it manually, because we're running from ISR | ||
48 | // and clear_keyboard() calls print | ||
49 | // so only clear the variables in memory | ||
50 | // the reports will be sent from main.c afterwards | ||
51 | // or if the PC asks for GET_REPORT | ||
52 | clear_mods(); | ||
53 | clear_weak_mods(); | ||
54 | clear_keys(); | ||
55 | #ifdef MOUSEKEY_ENABLE | ||
56 | mousekey_clear(); | ||
57 | #endif /* MOUSEKEY_ENABLE */ | ||
58 | #ifdef EXTRAKEY_ENABLE | ||
59 | host_system_send(0); | ||
60 | host_consumer_send(0); | ||
61 | #endif /* EXTRAKEY_ENABLE */ | ||
62 | #ifdef BACKLIGHT_ENABLE | ||
63 | backlight_init(); | ||
64 | #endif /* BACKLIGHT_ENABLE */ | ||
65 | } | ||
diff --git a/tmk_core/common/chibios/timer.c b/tmk_core/common/chibios/timer.c new file mode 100644 index 000000000..3de4cc368 --- /dev/null +++ b/tmk_core/common/chibios/timer.c | |||
@@ -0,0 +1,27 @@ | |||
1 | #include "ch.h" | ||
2 | |||
3 | #include "timer.h" | ||
4 | |||
5 | void timer_init(void) {} | ||
6 | |||
7 | void timer_clear(void) {} | ||
8 | |||
9 | uint16_t timer_read(void) | ||
10 | { | ||
11 | return (uint16_t)ST2MS(chVTGetSystemTime()); | ||
12 | } | ||
13 | |||
14 | uint32_t timer_read32(void) | ||
15 | { | ||
16 | return ST2MS(chVTGetSystemTime()); | ||
17 | } | ||
18 | |||
19 | uint16_t timer_elapsed(uint16_t last) | ||
20 | { | ||
21 | return (uint16_t)(ST2MS(chVTTimeElapsedSinceX(MS2ST(last)))); | ||
22 | } | ||
23 | |||
24 | uint32_t timer_elapsed32(uint32_t last) | ||
25 | { | ||
26 | return ST2MS(chVTTimeElapsedSinceX(MS2ST(last))); | ||
27 | } | ||
diff --git a/tmk_core/common/command.c b/tmk_core/common/command.c index 187a2b949..084c9fe15 100644 --- a/tmk_core/common/command.c +++ b/tmk_core/common/command.c | |||
@@ -16,7 +16,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
16 | */ | 16 | */ |
17 | #include <stdint.h> | 17 | #include <stdint.h> |
18 | #include <stdbool.h> | 18 | #include <stdbool.h> |
19 | #include <util/delay.h> | 19 | #include "wait.h" |
20 | #include "keycode.h" | 20 | #include "keycode.h" |
21 | #include "host.h" | 21 | #include "host.h" |
22 | #include "keymap.h" | 22 | #include "keymap.h" |
@@ -103,12 +103,14 @@ bool command_proc(uint8_t code) | |||
103 | bool command_extra(uint8_t code) __attribute__ ((weak)); | 103 | bool command_extra(uint8_t code) __attribute__ ((weak)); |
104 | bool command_extra(uint8_t code) | 104 | bool command_extra(uint8_t code) |
105 | { | 105 | { |
106 | (void)code; | ||
106 | return false; | 107 | return false; |
107 | } | 108 | } |
108 | 109 | ||
109 | bool command_console_extra(uint8_t code) __attribute__ ((weak)); | 110 | bool command_console_extra(uint8_t code) __attribute__ ((weak)); |
110 | bool command_console_extra(uint8_t code) | 111 | bool command_console_extra(uint8_t code) |
111 | { | 112 | { |
113 | (void)code; | ||
112 | return false; | 114 | return false; |
113 | } | 115 | } |
114 | 116 | ||
@@ -217,8 +219,11 @@ static void print_version(void) | |||
217 | " " STR(BOOTLOADER_SIZE) "\n"); | 219 | " " STR(BOOTLOADER_SIZE) "\n"); |
218 | 220 | ||
219 | print("GCC: " STR(__GNUC__) "." STR(__GNUC_MINOR__) "." STR(__GNUC_PATCHLEVEL__) | 221 | print("GCC: " STR(__GNUC__) "." STR(__GNUC_MINOR__) "." STR(__GNUC_PATCHLEVEL__) |
222 | #if defined(__AVR__) | ||
220 | " AVR-LIBC: " __AVR_LIBC_VERSION_STRING__ | 223 | " AVR-LIBC: " __AVR_LIBC_VERSION_STRING__ |
221 | " AVR_ARCH: avr" STR(__AVR_ARCH__) "\n"); | 224 | " AVR_ARCH: avr" STR(__AVR_ARCH__) |
225 | #endif | ||
226 | "\n"); | ||
222 | 227 | ||
223 | return; | 228 | return; |
224 | } | 229 | } |
@@ -234,7 +239,7 @@ static void print_status(void) | |||
234 | #ifdef NKRO_ENABLE | 239 | #ifdef NKRO_ENABLE |
235 | print_val_hex8(keyboard_nkro); | 240 | print_val_hex8(keyboard_nkro); |
236 | #endif | 241 | #endif |
237 | print_val_hex32(timer_count); | 242 | print_val_hex32(timer_read32()); |
238 | 243 | ||
239 | #ifdef PROTOCOL_PJRC | 244 | #ifdef PROTOCOL_PJRC |
240 | print_val_hex8(UDCON); | 245 | print_val_hex8(UDCON); |
@@ -360,7 +365,7 @@ static bool command_common(uint8_t code) | |||
360 | stop_all_notes(); | 365 | stop_all_notes(); |
361 | shutdown_user(); | 366 | shutdown_user(); |
362 | #else | 367 | #else |
363 | _delay_ms(1000); | 368 | wait_ms(1000); |
364 | #endif | 369 | #endif |
365 | bootloader_jump(); // not return | 370 | bootloader_jump(); // not return |
366 | break; | 371 | break; |
@@ -430,10 +435,11 @@ static bool command_common(uint8_t code) | |||
430 | case MAGIC_KC(MAGIC_KEY_NKRO): | 435 | case MAGIC_KC(MAGIC_KEY_NKRO): |
431 | clear_keyboard(); // clear to prevent stuck keys | 436 | clear_keyboard(); // clear to prevent stuck keys |
432 | keyboard_nkro = !keyboard_nkro; | 437 | keyboard_nkro = !keyboard_nkro; |
433 | if (keyboard_nkro) | 438 | if (keyboard_nkro) { |
434 | print("NKRO: on\n"); | 439 | print("NKRO: on\n"); |
435 | else | 440 | } else { |
436 | print("NKRO: off\n"); | 441 | print("NKRO: off\n"); |
442 | } | ||
437 | break; | 443 | break; |
438 | #endif | 444 | #endif |
439 | 445 | ||
@@ -750,10 +756,11 @@ static bool mousekey_console(uint8_t code) | |||
750 | print("?"); | 756 | print("?"); |
751 | return false; | 757 | return false; |
752 | } | 758 | } |
753 | if (mousekey_param) | 759 | if (mousekey_param) { |
754 | xprintf("M%d> ", mousekey_param); | 760 | xprintf("M%d> ", mousekey_param); |
755 | else | 761 | } else { |
756 | print("M>" ); | 762 | print("M>" ); |
763 | } | ||
757 | return true; | 764 | return true; |
758 | } | 765 | } |
759 | #endif | 766 | #endif |
diff --git a/tmk_core/common/avr/eeconfig.c b/tmk_core/common/eeconfig.c index 656938fb3..140d2b85b 100644 --- a/tmk_core/common/avr/eeconfig.c +++ b/tmk_core/common/eeconfig.c | |||
@@ -1,6 +1,6 @@ | |||
1 | #include <stdint.h> | 1 | #include <stdint.h> |
2 | #include <stdbool.h> | 2 | #include <stdbool.h> |
3 | #include <avr/eeprom.h> | 3 | #include "eeprom.h" |
4 | #include "eeconfig.h" | 4 | #include "eeconfig.h" |
5 | 5 | ||
6 | void eeconfig_init(void) | 6 | void eeconfig_init(void) |
diff --git a/tmk_core/common/eeprom.h b/tmk_core/common/eeprom.h new file mode 100644 index 000000000..2cc2ccee3 --- /dev/null +++ b/tmk_core/common/eeprom.h | |||
@@ -0,0 +1,22 @@ | |||
1 | #ifndef TMK_CORE_COMMON_EEPROM_H_ | ||
2 | #define TMK_CORE_COMMON_EEPROM_H_ | ||
3 | |||
4 | #if defined(__AVR__) | ||
5 | #include <avr/eeprom.h> | ||
6 | #else | ||
7 | uint8_t eeprom_read_byte (const uint8_t *__p); | ||
8 | uint16_t eeprom_read_word (const uint16_t *__p); | ||
9 | uint32_t eeprom_read_dword (const uint32_t *__p); | ||
10 | void eeprom_read_block (void *__dst, const void *__src, uint32_t __n); | ||
11 | void eeprom_write_byte (uint8_t *__p, uint8_t __value); | ||
12 | void eeprom_write_word (uint16_t *__p, uint16_t __value); | ||
13 | void eeprom_write_dword (uint32_t *__p, uint32_t __value); | ||
14 | void eeprom_write_block (const void *__src, void *__dst, uint32_t __n); | ||
15 | void eeprom_update_byte (uint8_t *__p, uint8_t __value); | ||
16 | void eeprom_update_word (uint16_t *__p, uint16_t __value); | ||
17 | void eeprom_update_dword (uint32_t *__p, uint32_t __value); | ||
18 | void eeprom_update_block (const void *__src, void *__dst, uint32_t __n); | ||
19 | #endif | ||
20 | |||
21 | |||
22 | #endif /* TMK_CORE_COMMON_EEPROM_H_ */ | ||
diff --git a/tmk_core/common/magic.c b/tmk_core/common/magic.c index f21d1346c..194e4cc02 100644 --- a/tmk_core/common/magic.c +++ b/tmk_core/common/magic.c | |||
@@ -1,6 +1,8 @@ | |||
1 | #include <stdint.h> | 1 | #include <stdint.h> |
2 | #include <stdbool.h> | 2 | #include <stdbool.h> |
3 | #if defined(__AVR__) | ||
3 | #include <util/delay.h> | 4 | #include <util/delay.h> |
5 | #endif | ||
4 | #include "matrix.h" | 6 | #include "matrix.h" |
5 | #include "bootloader.h" | 7 | #include "bootloader.h" |
6 | #include "debug.h" | 8 | #include "debug.h" |
@@ -33,4 +35,4 @@ void magic(void) | |||
33 | default_layer = eeconfig_read_default_layer(); | 35 | default_layer = eeconfig_read_default_layer(); |
34 | default_layer_set((uint32_t)default_layer); | 36 | default_layer_set((uint32_t)default_layer); |
35 | 37 | ||
36 | } \ No newline at end of file | 38 | } |
diff --git a/tmk_core/common/print.c b/tmk_core/common/print.c index ca94e1e5d..00489557f 100644 --- a/tmk_core/common/print.c +++ b/tmk_core/common/print.c | |||
@@ -38,11 +38,15 @@ void print_set_sendchar(int8_t (*sendchar_func)(uint8_t)) | |||
38 | xdev_out(sendchar_func); | 38 | xdev_out(sendchar_func); |
39 | } | 39 | } |
40 | 40 | ||
41 | #elif defined(__arm__) | 41 | #elif defined(PROTOCOL_CHIBIOS) /* __AVR__ */ |
42 | |||
43 | // don't need anything extra | ||
44 | |||
45 | #elif defined(__arm__) /* __AVR__ */ | ||
42 | 46 | ||
43 | // TODO | 47 | // TODO |
44 | //void print_set_sendchar(int8_t (*sendchar_func)(uint8_t)) { } | 48 | //void print_set_sendchar(int8_t (*sendchar_func)(uint8_t)) { } |
45 | 49 | ||
46 | #endif | 50 | #endif /* __AVR__ */ |
47 | 51 | ||
48 | #endif | 52 | #endif |
diff --git a/tmk_core/common/print.h b/tmk_core/common/print.h index 4f3dde65a..0368bcd4a 100644 --- a/tmk_core/common/print.h +++ b/tmk_core/common/print.h | |||
@@ -47,7 +47,15 @@ extern "C" | |||
47 | /* function pointer of sendchar to be used by print utility */ | 47 | /* function pointer of sendchar to be used by print utility */ |
48 | void print_set_sendchar(int8_t (*print_sendchar_func)(uint8_t)); | 48 | void print_set_sendchar(int8_t (*print_sendchar_func)(uint8_t)); |
49 | 49 | ||
50 | #elif defined(__arm__) | 50 | #elif defined(PROTOCOL_CHIBIOS) /* __AVR__ */ |
51 | |||
52 | #include "chibios/printf.h" | ||
53 | |||
54 | #define print(s) printf(s) | ||
55 | #define println(s) printf(s "\r\n") | ||
56 | #define xprintf printf | ||
57 | |||
58 | #elif defined(__arm__) /* __AVR__ */ | ||
51 | 59 | ||
52 | #include "mbed/xprintf.h" | 60 | #include "mbed/xprintf.h" |
53 | 61 | ||
diff --git a/tmk_core/common/progmem.h b/tmk_core/common/progmem.h index 199b1bedf..5b2765625 100644 --- a/tmk_core/common/progmem.h +++ b/tmk_core/common/progmem.h | |||
@@ -5,8 +5,8 @@ | |||
5 | # include <avr/pgmspace.h> | 5 | # include <avr/pgmspace.h> |
6 | #elif defined(__arm__) | 6 | #elif defined(__arm__) |
7 | # define PROGMEM | 7 | # define PROGMEM |
8 | # define pgm_read_byte(p) *(p) | 8 | # define pgm_read_byte(p) *((unsigned char*)p) |
9 | # define pgm_read_word(p) *(p) | 9 | # define pgm_read_word(p) *((uint16_t*)p) |
10 | #endif | 10 | #endif |
11 | 11 | ||
12 | #endif | 12 | #endif |
diff --git a/tmk_core/common/report.h b/tmk_core/common/report.h index f6c0a315d..0c799eca3 100644 --- a/tmk_core/common/report.h +++ b/tmk_core/common/report.h | |||
@@ -84,6 +84,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
84 | # define KEYBOARD_REPORT_SIZE NKRO_EPSIZE | 84 | # define KEYBOARD_REPORT_SIZE NKRO_EPSIZE |
85 | # define KEYBOARD_REPORT_KEYS (NKRO_EPSIZE - 2) | 85 | # define KEYBOARD_REPORT_KEYS (NKRO_EPSIZE - 2) |
86 | # define KEYBOARD_REPORT_BITS (NKRO_EPSIZE - 1) | 86 | # define KEYBOARD_REPORT_BITS (NKRO_EPSIZE - 1) |
87 | #elif defined(PROTOCOL_CHIBIOS) && defined(NKRO_ENABLE) | ||
88 | # include "protocol/chibios/usb_main.h" | ||
89 | # define KEYBOARD_REPORT_SIZE NKRO_EPSIZE | ||
90 | # define KEYBOARD_REPORT_KEYS (NKRO_EPSIZE - 2) | ||
91 | # define KEYBOARD_REPORT_BITS (NKRO_EPSIZE - 1) | ||
87 | 92 | ||
88 | #else | 93 | #else |
89 | # define KEYBOARD_REPORT_SIZE 8 | 94 | # define KEYBOARD_REPORT_SIZE 8 |
diff --git a/tmk_core/common/wait.h b/tmk_core/common/wait.h index 40d00b0c7..82727be01 100644 --- a/tmk_core/common/wait.h +++ b/tmk_core/common/wait.h | |||
@@ -9,9 +9,13 @@ extern "C" { | |||
9 | # include <util/delay.h> | 9 | # include <util/delay.h> |
10 | # define wait_ms(ms) _delay_ms(ms) | 10 | # define wait_ms(ms) _delay_ms(ms) |
11 | # define wait_us(us) _delay_us(us) | 11 | # define wait_us(us) _delay_us(us) |
12 | #elif defined(__arm__) | 12 | #elif defined(PROTOCOL_CHIBIOS) /* __AVR__ */ |
13 | # include "ch.h" | ||
14 | # define wait_ms(ms) chThdSleepMilliseconds(ms) | ||
15 | # define wait_us(us) chThdSleepMicroseconds(us) | ||
16 | #elif defined(__arm__) /* __AVR__ */ | ||
13 | # include "wait_api.h" | 17 | # include "wait_api.h" |
14 | #endif | 18 | #endif /* __AVR__ */ |
15 | 19 | ||
16 | #ifdef __cplusplus | 20 | #ifdef __cplusplus |
17 | } | 21 | } |