aboutsummaryrefslogtreecommitdiff
path: root/tmk_core
diff options
context:
space:
mode:
authorAlex Ong <the.onga@gmail.com>2019-01-26 11:36:28 +1100
committerAlex Ong <the.onga@gmail.com>2019-01-26 11:36:28 +1100
commitd977daa8dc9136746425f9e1414e1f93cb161877 (patch)
tree209ab8082580e5fdf37f1a8b7c1169250b7548c0 /tmk_core
parent47c91fc7f75ae0a477e55b687aa0fc30da0a283c (diff)
parent0306e487e2cd6a77ad840d0a441b478747b7ccd0 (diff)
downloadqmk_firmware-d977daa8dc9136746425f9e1414e1f93cb161877.tar.gz
qmk_firmware-d977daa8dc9136746425f9e1414e1f93cb161877.zip
Merge branch 'master' of https://github.com/qmk/qmk_firmware
Diffstat (limited to 'tmk_core')
-rw-r--r--tmk_core/common/action.c10
-rw-r--r--tmk_core/common/action.h1
-rw-r--r--tmk_core/common/action_layer.c303
-rw-r--r--tmk_core/common/action_util.c4
-rw-r--r--tmk_core/common/arm_atsam/timer.c20
-rwxr-xr-xtmk_core/common/chibios/eeprom_stm32.c710
-rwxr-xr-xtmk_core/common/chibios/eeprom_stm32.h68
-rwxr-xr-xtmk_core/common/chibios/flash_stm32.c15
-rwxr-xr-xtmk_core/common/chibios/flash_stm32.h1
-rw-r--r--tmk_core/common/eeconfig.c4
-rw-r--r--tmk_core/common/eeconfig.h21
-rw-r--r--tmk_core/common/eeprom.h1
-rw-r--r--tmk_core/common/host.h11
-rw-r--r--tmk_core/common/keyboard.h2
-rw-r--r--tmk_core/common/keycode.h20
-rw-r--r--tmk_core/common/progmem.h6
-rw-r--r--tmk_core/common/report.h8
-rw-r--r--tmk_core/common/wait.h4
-rw-r--r--tmk_core/protocol/arm_atsam/arm_atsam_protocol.h2
-rw-r--r--tmk_core/protocol/arm_atsam/clks.c90
-rw-r--r--tmk_core/protocol/arm_atsam/clks.h5
-rw-r--r--tmk_core/protocol/arm_atsam/i2c_master.c4
-rw-r--r--tmk_core/protocol/arm_atsam/led_matrix.c26
-rw-r--r--tmk_core/protocol/arm_atsam/led_matrix.h2
-rw-r--r--tmk_core/protocol/arm_atsam/main_arm_atsam.c18
-rw-r--r--tmk_core/protocol/arm_atsam/usb/compiler.h4
-rw-r--r--tmk_core/protocol/arm_atsam/usb/udi_cdc.c8
-rw-r--r--tmk_core/protocol/arm_atsam/usb/usb2422.c15
-rw-r--r--tmk_core/protocol/chibios/main.c2
-rw-r--r--tmk_core/protocol/lufa/lufa.c17
30 files changed, 450 insertions, 952 deletions
diff --git a/tmk_core/common/action.c b/tmk_core/common/action.c
index b99c2acaa..ec8d6ed7b 100644
--- a/tmk_core/common/action.c
+++ b/tmk_core/common/action.c
@@ -653,7 +653,7 @@ void process_action(keyrecord_t *record, action_t action)
653 653
654#ifndef NO_ACTION_TAPPING 654#ifndef NO_ACTION_TAPPING
655 #ifdef RETRO_TAPPING 655 #ifdef RETRO_TAPPING
656 if (!is_tap_key(record->event.key)) { 656 if (!is_tap_action(action)) {
657 retro_tapping_counter = 0; 657 retro_tapping_counter = 0;
658 } else { 658 } else {
659 if (event.pressed) { 659 if (event.pressed) {
@@ -929,7 +929,15 @@ void clear_keyboard_but_mods_and_keys()
929bool is_tap_key(keypos_t key) 929bool is_tap_key(keypos_t key)
930{ 930{
931 action_t action = layer_switch_get_action(key); 931 action_t action = layer_switch_get_action(key);
932 return is_tap_action(action);
933}
932 934
935/** \brief Utilities for actions. (FIXME: Needs better description)
936 *
937 * FIXME: Needs documentation.
938 */
939bool is_tap_action(action_t action)
940{
933 switch (action.kind.id) { 941 switch (action.kind.id) {
934 case ACT_LMODS_TAP: 942 case ACT_LMODS_TAP:
935 case ACT_RMODS_TAP: 943 case ACT_RMODS_TAP:
diff --git a/tmk_core/common/action.h b/tmk_core/common/action.h
index 8e47e5339..799e3bb0e 100644
--- a/tmk_core/common/action.h
+++ b/tmk_core/common/action.h
@@ -97,6 +97,7 @@ void clear_keyboard_but_mods(void);
97void clear_keyboard_but_mods_and_keys(void); 97void clear_keyboard_but_mods_and_keys(void);
98void layer_switch(uint8_t new_layer); 98void layer_switch(uint8_t new_layer);
99bool is_tap_key(keypos_t key); 99bool is_tap_key(keypos_t key);
100bool is_tap_action(action_t action);
100 101
101#ifndef NO_ACTION_TAPPING 102#ifndef NO_ACTION_TAPPING
102void process_record_tap_hint(keyrecord_t *record); 103void process_record_tap_hint(keyrecord_t *record);
diff --git a/tmk_core/common/action_layer.c b/tmk_core/common/action_layer.c
index 120ce3f51..6ff8c5549 100644
--- a/tmk_core/common/action_layer.c
+++ b/tmk_core/common/action_layer.c
@@ -17,82 +17,76 @@ uint32_t default_layer_state = 0;
17 17
18/** \brief Default Layer State Set At user Level 18/** \brief Default Layer State Set At user Level
19 * 19 *
20 * FIXME: Needs docs 20 * Run user code on default layer state change
21 */ 21 */
22__attribute__((weak)) 22__attribute__((weak))
23uint32_t default_layer_state_set_user(uint32_t state) { 23uint32_t default_layer_state_set_user(uint32_t state) {
24 return state; 24 return state;
25} 25}
26 26
27/** \brief Default Layer State Set At Keyboard Level 27/** \brief Default Layer State Set At Keyboard Level
28 * 28 *
29 * FIXME: Needs docs 29 * Run keyboard code on default layer state change
30 */ 30 */
31__attribute__((weak)) 31__attribute__((weak))
32uint32_t default_layer_state_set_kb(uint32_t state) { 32uint32_t default_layer_state_set_kb(uint32_t state) {
33 return default_layer_state_set_user(state); 33 return default_layer_state_set_user(state);
34} 34}
35 35
36/** \brief Default Layer State Set 36/** \brief Default Layer State Set
37 * 37 *
38 * FIXME: Needs docs 38 * Static function to set the default layer state, prints debug info and clears keys
39 */ 39 */
40static void default_layer_state_set(uint32_t state) 40static void default_layer_state_set(uint32_t state) {
41{ 41 state = default_layer_state_set_kb(state);
42 state = default_layer_state_set_kb(state); 42 debug("default_layer_state: ");
43 debug("default_layer_state: "); 43 default_layer_debug(); debug(" to ");
44 default_layer_debug(); debug(" to "); 44 default_layer_state = state;
45 default_layer_state = state; 45 default_layer_debug(); debug("\n");
46 default_layer_debug(); debug("\n");
47#ifdef STRICT_LAYER_RELEASE 46#ifdef STRICT_LAYER_RELEASE
48 clear_keyboard_but_mods(); // To avoid stuck keys 47 clear_keyboard_but_mods(); // To avoid stuck keys
49#else 48#else
50 clear_keyboard_but_mods_and_keys(); // Don't reset held keys 49 clear_keyboard_but_mods_and_keys(); // Don't reset held keys
51#endif 50#endif
52} 51}
53 52
54/** \brief Default Layer Print 53/** \brief Default Layer Print
55 * 54 *
56 * FIXME: Needs docs 55 * Print out the hex value of the 32-bit default layer state, as well as the value of the highest bit.
57 */ 56 */
58void default_layer_debug(void) 57void default_layer_debug(void) {
59{ 58 dprintf("%08lX(%u)", default_layer_state, biton32(default_layer_state));
60 dprintf("%08lX(%u)", default_layer_state, biton32(default_layer_state));
61} 59}
62 60
63/** \brief Default Layer Set 61/** \brief Default Layer Set
64 * 62 *
65 * FIXME: Needs docs 63 * Sets the default layer state.
66 */ 64 */
67void default_layer_set(uint32_t state) 65void default_layer_set(uint32_t state) {
68{ 66 default_layer_state_set(state);
69 default_layer_state_set(state);
70} 67}
71 68
72#ifndef NO_ACTION_LAYER 69#ifndef NO_ACTION_LAYER
73/** \brief Default Layer Or 70/** \brief Default Layer Or
74 * 71 *
75 * FIXME: Needs docs 72 * Turns on the default layer based on matching bits between specifed layer and existing layer state
76 */ 73 */
77void default_layer_or(uint32_t state) 74void default_layer_or(uint32_t state) {
78{ 75 default_layer_state_set(default_layer_state | state);
79 default_layer_state_set(default_layer_state | state);
80} 76}
81/** \brief Default Layer And 77/** \brief Default Layer And
82 * 78 *
83 * FIXME: Needs docs 79 * Turns on default layer based on matching enabled bits between specifed layer and existing layer state
84 */ 80 */
85void default_layer_and(uint32_t state) 81void default_layer_and(uint32_t state) {
86{ 82 default_layer_state_set(default_layer_state & state);
87 default_layer_state_set(default_layer_state & state);
88} 83}
89/** \brief Default Layer Xor 84/** \brief Default Layer Xor
90 * 85 *
91 * FIXME: Needs docs 86 * Turns on default layer based on non-matching bits between specifed layer and existing layer state
92 */ 87 */
93void default_layer_xor(uint32_t state) 88void default_layer_xor(uint32_t state) {
94{ 89 default_layer_state_set(default_layer_state ^ state);
95 default_layer_state_set(default_layer_state ^ state);
96} 90}
97#endif 91#endif
98 92
@@ -104,170 +98,168 @@ uint32_t layer_state = 0;
104 98
105/** \brief Layer state set user 99/** \brief Layer state set user
106 * 100 *
107 * FIXME: Needs docs 101 * Runs user code on layer state change
108 */ 102 */
109__attribute__((weak)) 103__attribute__((weak))
110uint32_t layer_state_set_user(uint32_t state) { 104uint32_t layer_state_set_user(uint32_t state) {
111 return state; 105 return state;
112} 106}
113 107
114/** \brief Layer state set keyboard 108/** \brief Layer state set keyboard
115 * 109 *
116 * FIXME: Needs docs 110 * Runs keyboard code on layer state change
117 */ 111 */
118__attribute__((weak)) 112__attribute__((weak))
119uint32_t layer_state_set_kb(uint32_t state) { 113uint32_t layer_state_set_kb(uint32_t state) {
120 return layer_state_set_user(state); 114 return layer_state_set_user(state);
121} 115}
122 116
123/** \brief Layer state set 117/** \brief Layer state set
124 * 118 *
125 * FIXME: Needs docs 119 * Sets the layer to match the specifed state (a bitmask)
126 */ 120 */
127void layer_state_set(uint32_t state) 121void layer_state_set(uint32_t state) {
128{ 122 state = layer_state_set_kb(state);
129 state = layer_state_set_kb(state); 123 dprint("layer_state: ");
130 dprint("layer_state: "); 124 layer_debug(); dprint(" to ");
131 layer_debug(); dprint(" to "); 125 layer_state = state;
132 layer_state = state; 126 layer_debug(); dprintln();
133 layer_debug(); dprintln();
134#ifdef STRICT_LAYER_RELEASE 127#ifdef STRICT_LAYER_RELEASE
135 clear_keyboard_but_mods(); // To avoid stuck keys 128 clear_keyboard_but_mods(); // To avoid stuck keys
136#else 129#else
137 clear_keyboard_but_mods_and_keys(); // Don't reset held keys 130 clear_keyboard_but_mods_and_keys(); // Don't reset held keys
138#endif 131#endif
139} 132}
140 133
141/** \brief Layer clear 134/** \brief Layer clear
142 * 135 *
143 * FIXME: Needs docs 136 * Turn off all layers
144 */ 137 */
145void layer_clear(void) 138void layer_clear(void) {
146{ 139 layer_state_set(0);
147 layer_state_set(0);
148} 140}
149 141
150/** \brief Layer state is 142/** \brief Layer state is
151 * 143 *
152 * FIXME: Needs docs 144 * Return whether the given state is on (it might still be shadowed by a higher state, though)
153 */ 145 */
154bool layer_state_is(uint8_t layer) 146bool layer_state_is(uint8_t layer) {
155{ 147 return layer_state_cmp(layer_state, layer);
156 return layer_state_cmp(layer_state, layer);
157} 148}
158 149
159/** \brief Layer state compare 150/** \brief Layer state compare
160 * 151 *
161 * FIXME: Needs docs 152 * Used for comparing layers {mostly used for unit testing}
162 */ 153 */
163bool layer_state_cmp(uint32_t cmp_layer_state, uint8_t layer) { 154bool layer_state_cmp(uint32_t cmp_layer_state, uint8_t layer) {
164 if (!cmp_layer_state) { return layer == 0; } 155 if (!cmp_layer_state) { return layer == 0; }
165 return (cmp_layer_state & (1UL<<layer)) != 0; 156 return (cmp_layer_state & (1UL<<layer)) != 0;
166} 157}
167 158
168/** \brief Layer move 159/** \brief Layer move
169 * 160 *
170 * FIXME: Needs docs 161 * Turns on the given layer and turn off all other layers
171 */ 162 */
172void layer_move(uint8_t layer) 163void layer_move(uint8_t layer) {
173{ 164 layer_state_set(1UL<<layer);
174 layer_state_set(1UL<<layer);
175} 165}
176 166
177/** \brief Layer on 167/** \brief Layer on
178 * 168 *
179 * FIXME: Needs docs 169 * Turns on given layer
180 */ 170 */
181void layer_on(uint8_t layer) 171void layer_on(uint8_t layer) {
182{ 172 layer_state_set(layer_state | (1UL<<layer));
183 layer_state_set(layer_state | (1UL<<layer));
184} 173}
185 174
186/** \brief Layer off 175/** \brief Layer off
187 * 176 *
188 * FIXME: Needs docs 177 * Turns off given layer
189 */ 178 */
190void layer_off(uint8_t layer) 179void layer_off(uint8_t layer) {
191{ 180 layer_state_set(layer_state & ~(1UL<<layer));
192 layer_state_set(layer_state & ~(1UL<<layer));
193} 181}
194 182
195/** \brief Layer invert 183/** \brief Layer invert
196 * 184 *
197 * FIXME: Needs docs 185 * Toggle the given layer (set it if it's unset, or unset it if it's set)
198 */ 186 */
199void layer_invert(uint8_t layer) 187void layer_invert(uint8_t layer) {
200{ 188 layer_state_set(layer_state ^ (1UL<<layer));
201 layer_state_set(layer_state ^ (1UL<<layer));
202} 189}
203 190
204/** \brief Layer or 191/** \brief Layer or
205 * 192 *
206 * FIXME: Needs docs 193 * Turns on layers based on matching bits between specifed layer and existing layer state
207 */ 194 */
208void layer_or(uint32_t state) 195void layer_or(uint32_t state) {
209{ 196 layer_state_set(layer_state | state);
210 layer_state_set(layer_state | state);
211} 197}
212/** \brief Layer and 198/** \brief Layer and
213 * 199 *
214 * FIXME: Needs docs 200 * Turns on layers based on matching enabled bits between specifed layer and existing layer state
215 */ 201 */
216void layer_and(uint32_t state) 202void layer_and(uint32_t state) {
217{ 203 layer_state_set(layer_state & state);
218 layer_state_set(layer_state & state);
219} 204}
220/** \brief Layer xor 205/** \brief Layer xor
221 * 206 *
222 * FIXME: Needs docs 207 * Turns on layers based on non-matching bits between specifed layer and existing layer state
223 */ 208 */
224void layer_xor(uint32_t state) 209void layer_xor(uint32_t state) {
225{ 210 layer_state_set(layer_state ^ state);
226 layer_state_set(layer_state ^ state);
227} 211}
228 212
229/** \brief Layer debug printing 213/** \brief Layer debug printing
230 * 214 *
231 * FIXME: Needs docs 215 * Print out the hex value of the 32-bit layer state, as well as the value of the highest bit.
232 */ 216 */
233void layer_debug(void) 217void layer_debug(void) {
234{ 218 dprintf("%08lX(%u)", layer_state, biton32(layer_state));
235 dprintf("%08lX(%u)", layer_state, biton32(layer_state));
236} 219}
237#endif 220#endif
238 221
239#if !defined(NO_ACTION_LAYER) && !defined(STRICT_LAYER_RELEASE) 222#if !defined(NO_ACTION_LAYER) && !defined(STRICT_LAYER_RELEASE)
223/** \brief source layer cache
224 */
225
240uint8_t source_layers_cache[(MATRIX_ROWS * MATRIX_COLS + 7) / 8][MAX_LAYER_BITS] = {{0}}; 226uint8_t source_layers_cache[(MATRIX_ROWS * MATRIX_COLS + 7) / 8][MAX_LAYER_BITS] = {{0}};
241 227
242void update_source_layers_cache(keypos_t key, uint8_t layer) 228/** \brief update source layers cache
243{ 229 *
244 const uint8_t key_number = key.col + (key.row * MATRIX_COLS); 230 * Updates the cached keys when changing layers
245 const uint8_t storage_row = key_number / 8; 231 */
246 const uint8_t storage_bit = key_number % 8; 232void update_source_layers_cache(keypos_t key, uint8_t layer) {
247 233 const uint8_t key_number = key.col + (key.row * MATRIX_COLS);
248 for (uint8_t bit_number = 0; bit_number < MAX_LAYER_BITS; bit_number++) { 234 const uint8_t storage_row = key_number / 8;
249 source_layers_cache[storage_row][bit_number] ^= 235 const uint8_t storage_bit = key_number % 8;
250 (-((layer & (1U << bit_number)) != 0) 236
251 ^ source_layers_cache[storage_row][bit_number]) 237 for (uint8_t bit_number = 0; bit_number < MAX_LAYER_BITS; bit_number++) {
252 & (1U << storage_bit); 238 source_layers_cache[storage_row][bit_number] ^=
253 } 239 (-((layer & (1U << bit_number)) != 0)
240 ^ source_layers_cache[storage_row][bit_number])
241 & (1U << storage_bit);
242 }
254} 243}
255 244
256uint8_t read_source_layers_cache(keypos_t key) 245/** \brief read source layers cache
257{ 246 *
258 const uint8_t key_number = key.col + (key.row * MATRIX_COLS); 247 * reads the cached keys stored when the layer was changed
259 const uint8_t storage_row = key_number / 8; 248 */
260 const uint8_t storage_bit = key_number % 8; 249uint8_t read_source_layers_cache(keypos_t key) {
261 uint8_t layer = 0; 250 const uint8_t key_number = key.col + (key.row * MATRIX_COLS);
262 251 const uint8_t storage_row = key_number / 8;
263 for (uint8_t bit_number = 0; bit_number < MAX_LAYER_BITS; bit_number++) { 252 const uint8_t storage_bit = key_number % 8;
264 layer |= 253 uint8_t layer = 0;
265 ((source_layers_cache[storage_row][bit_number] 254
266 & (1U << storage_bit)) != 0) 255 for (uint8_t bit_number = 0; bit_number < MAX_LAYER_BITS; bit_number++) {
267 << bit_number; 256 layer |=
268 } 257 ((source_layers_cache[storage_row][bit_number]
269 258 & (1U << storage_bit)) != 0)
270 return layer; 259 << bit_number;
260 }
261
262 return layer;
271} 263}
272#endif 264#endif
273 265
@@ -278,61 +270,58 @@ uint8_t read_source_layers_cache(keypos_t key)
278 * when the layer is switched after the down event but before the up 270 * when the layer is switched after the down event but before the up
279 * event as they may get stuck otherwise. 271 * event as they may get stuck otherwise.
280 */ 272 */
281action_t store_or_get_action(bool pressed, keypos_t key) 273action_t store_or_get_action(bool pressed, keypos_t key) {
282{
283#if !defined(NO_ACTION_LAYER) && !defined(STRICT_LAYER_RELEASE) 274#if !defined(NO_ACTION_LAYER) && !defined(STRICT_LAYER_RELEASE)
284 if (disable_action_cache) { 275 if (disable_action_cache) {
285 return layer_switch_get_action(key);
286 }
287
288 uint8_t layer;
289
290 if (pressed) {
291 layer = layer_switch_get_layer(key);
292 update_source_layers_cache(key, layer);
293 }
294 else {
295 layer = read_source_layers_cache(key);
296 }
297 return action_for_key(layer, key);
298#else
299 return layer_switch_get_action(key); 276 return layer_switch_get_action(key);
277 }
278
279 uint8_t layer;
280
281 if (pressed) {
282 layer = layer_switch_get_layer(key);
283 update_source_layers_cache(key, layer);
284 }
285 else {
286 layer = read_source_layers_cache(key);
287 }
288 return action_for_key(layer, key);
289#else
290 return layer_switch_get_action(key);
300#endif 291#endif
301} 292}
302 293
303 294
304/** \brief Layer switch get layer 295/** \brief Layer switch get layer
305 * 296 *
306 * FIXME: Needs docs 297 * Gets the layer based on key info
307 */ 298 */
308int8_t layer_switch_get_layer(keypos_t key) 299int8_t layer_switch_get_layer(keypos_t key) {
309{
310#ifndef NO_ACTION_LAYER 300#ifndef NO_ACTION_LAYER
311 action_t action; 301 action_t action;
312 action.code = ACTION_TRANSPARENT; 302 action.code = ACTION_TRANSPARENT;
313 303
314 uint32_t layers = layer_state | default_layer_state; 304 uint32_t layers = layer_state | default_layer_state;
315 /* check top layer first */ 305 /* check top layer first */
316 for (int8_t i = 31; i >= 0; i--) { 306 for (int8_t i = 31; i >= 0; i--) {
317 if (layers & (1UL<<i)) { 307 if (layers & (1UL<<i)) {
318 action = action_for_key(i, key); 308 action = action_for_key(i, key);
319 if (action.code != ACTION_TRANSPARENT) { 309 if (action.code != ACTION_TRANSPARENT) {
320 return i; 310 return i;
321 } 311 }
322 }
323 } 312 }
324 /* fall back to layer 0 */ 313 }
325 return 0; 314 /* fall back to layer 0 */
315 return 0;
326#else 316#else
327 return biton32(default_layer_state); 317 return biton32(default_layer_state);
328#endif 318#endif
329} 319}
330 320
331/** \brief Layer switch get layer 321/** \brief Layer switch get layer
332 * 322 *
333 * FIXME: Needs docs 323 * Gets action code based on key position
334 */ 324 */
335action_t layer_switch_get_action(keypos_t key) 325action_t layer_switch_get_action(keypos_t key) {
336{ 326 return action_for_key(layer_switch_get_layer(key), key);
337 return action_for_key(layer_switch_get_layer(key), key);
338} 327}
diff --git a/tmk_core/common/action_util.c b/tmk_core/common/action_util.c
index afd4ae8b2..58401ace5 100644
--- a/tmk_core/common/action_util.c
+++ b/tmk_core/common/action_util.c
@@ -54,7 +54,7 @@ int8_t get_oneshot_locked_mods(void) { return oneshot_locked_mods; }
54void set_oneshot_locked_mods(int8_t mods) { oneshot_locked_mods = mods; } 54void set_oneshot_locked_mods(int8_t mods) { oneshot_locked_mods = mods; }
55void clear_oneshot_locked_mods(void) { oneshot_locked_mods = 0; } 55void clear_oneshot_locked_mods(void) { oneshot_locked_mods = 0; }
56#if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0)) 56#if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0))
57static int16_t oneshot_time = 0; 57static uint16_t oneshot_time = 0;
58bool has_oneshot_mods_timed_out(void) { 58bool has_oneshot_mods_timed_out(void) {
59 return TIMER_DIFF_16(timer_read(), oneshot_time) >= ONESHOT_TIMEOUT; 59 return TIMER_DIFF_16(timer_read(), oneshot_time) >= ONESHOT_TIMEOUT;
60} 60}
@@ -79,7 +79,7 @@ inline uint8_t get_oneshot_layer(void) { return oneshot_layer_data >> 3; }
79inline uint8_t get_oneshot_layer_state(void) { return oneshot_layer_data & 0b111; } 79inline uint8_t get_oneshot_layer_state(void) { return oneshot_layer_data & 0b111; }
80 80
81#if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0)) 81#if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0))
82static int16_t oneshot_layer_time = 0; 82static uint16_t oneshot_layer_time = 0;
83inline bool has_oneshot_layer_timed_out() { 83inline bool has_oneshot_layer_timed_out() {
84 return TIMER_DIFF_16(timer_read(), oneshot_layer_time) >= ONESHOT_TIMEOUT && 84 return TIMER_DIFF_16(timer_read(), oneshot_layer_time) >= ONESHOT_TIMEOUT &&
85 !(get_oneshot_layer_state() & ONESHOT_TOGGLED); 85 !(get_oneshot_layer_state() & ONESHOT_TOGGLED);
diff --git a/tmk_core/common/arm_atsam/timer.c b/tmk_core/common/arm_atsam/timer.c
index bcfe5002c..6c3905e30 100644
--- a/tmk_core/common/arm_atsam/timer.c
+++ b/tmk_core/common/arm_atsam/timer.c
@@ -9,7 +9,7 @@ void set_time(uint64_t tset)
9 9
10void timer_init(void) 10void timer_init(void)
11{ 11{
12 ms_clk = 0; 12 timer_clear();
13} 13}
14 14
15uint16_t timer_read(void) 15uint16_t timer_read(void)
@@ -37,23 +37,7 @@ uint32_t timer_elapsed32(uint32_t tlast)
37 return TIMER_DIFF_32(timer_read32(), tlast); 37 return TIMER_DIFF_32(timer_read32(), tlast);
38} 38}
39 39
40uint32_t timer_elapsed64(uint32_t tlast)
41{
42 uint64_t tnow = timer_read64();
43 return (tnow >= tlast ? tnow - tlast : UINT64_MAX - tlast + tnow);
44}
45
46void timer_clear(void) 40void timer_clear(void)
47{ 41{
48 ms_clk = 0; 42 set_time(0);
49}
50
51void wait_ms(uint64_t msec)
52{
53 CLK_delay_ms(msec);
54}
55
56void wait_us(uint16_t usec)
57{
58 CLK_delay_us(usec);
59} 43}
diff --git a/tmk_core/common/chibios/eeprom_stm32.c b/tmk_core/common/chibios/eeprom_stm32.c
index a86998550..a15430d67 100755
--- a/tmk_core/common/chibios/eeprom_stm32.c
+++ b/tmk_core/common/chibios/eeprom_stm32.c
@@ -10,664 +10,206 @@
10 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 10 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
11 * DEALINGS IN THE SOFTWARE. 11 * DEALINGS IN THE SOFTWARE.
12 * 12 *
13 * This files are free to use from https://github.com/rogerclarkmelbourne/Arduino_STM32 and 13 * This files are free to use from http://engsta.com/stm32-flash-memory-eeprom-emulator/ by
14 * https://github.com/leaflabs/libmaple 14 * Artur F.
15 * 15 *
16 * Modifications for QMK and STM32F303 by Yiancar 16 * Modifications for QMK and STM32F303 by Yiancar
17 */ 17 */
18 18
19#include <stdio.h>
20#include <string.h>
19#include "eeprom_stm32.h" 21#include "eeprom_stm32.h"
22/*****************************************************************************
23 * Allows to use the internal flash to store non volatile data. To initialize
24 * the functionality use the EEPROM_Init() function. Be sure that by reprogramming
25 * of the controller just affected pages will be deleted. In other case the non
26 * volatile data will be lost.
27******************************************************************************/
28
29/* Private macro -------------------------------------------------------------*/
30/* Private variables ---------------------------------------------------------*/
31/* Functions -----------------------------------------------------------------*/
32
33uint8_t DataBuf[FEE_PAGE_SIZE];
34/*****************************************************************************
35* Delete Flash Space used for user Data, deletes the whole space between
36* RW_PAGE_BASE_ADDRESS and the last uC Flash Page
37******************************************************************************/
38uint16_t EEPROM_Init(void) {
39 // unlock flash
40 FLASH_Unlock();
20 41
21 FLASH_Status EE_ErasePage(uint32_t); 42 // Clear Flags
22 43 //FLASH_ClearFlag(FLASH_SR_EOP|FLASH_SR_PGERR|FLASH_SR_WRPERR);
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 44
81/** 45 return FEE_DENSITY_BYTES;
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} 46}
47/*****************************************************************************
48* Erase the whole reserved Flash Space used for user Data
49******************************************************************************/
50void EEPROM_Erase (void) {
101 51
102/** 52 int page_num = 0;
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 53
121/** 54 // delete all pages from specified start page to the last page
122 * @brief Calculate unique variables in EEPROM 55 do {
123 * @param start: address of first slot to check (page + 4) 56 FLASH_ErasePage(FEE_PAGE_BASE_ADDRESS + (page_num * FEE_PAGE_SIZE));
124 * @param end: page end address 57 page_num++;
125 * @param address: 16 bit virtual address of the variable to excluse (or 0XFFFF) 58 } while (page_num < FEE_DENSITY_PAGES);
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} 59}
60/*****************************************************************************
61* Writes once data byte to flash on specified address. If a byte is already
62* written, the whole page must be copied to a buffer, the byte changed and
63* the manipulated buffer written after PageErase.
64*******************************************************************************/
65uint16_t EEPROM_WriteDataByte (uint16_t Address, uint8_t DataByte) {
154 66
155/** 67 FLASH_Status FlashStatus = FLASH_COMPLETE;
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 68
210 FlashStatus = FLASH_ProgramHalfWord(newIdx + 2, address); 69 uint32_t page;
211 if (FlashStatus != FLASH_COMPLETE) 70 int i;
212 return FlashStatus;
213 71
214 newIdx += 4; 72 // exit if desired address is above the limit (e.G. under 2048 Bytes for 4 pages)
215 } 73 if (Address > FEE_DENSITY_BYTES) {
216 else 74 return 0;
217 return EEPROM_OUT_SIZE;
218 } 75 }
219 76
220 // Erase the old Page: Set old Page status to EEPROM_EEPROM_ERASED status 77 // calculate which page is affected (Pagenum1/Pagenum2...PagenumN)
221 data = EE_CheckErasePage(oldPage, EEPROM_ERASED); 78 page = (FEE_PAGE_BASE_ADDRESS + FEE_ADDR_OFFSET(Address)) & 0x00000FFF;
222 if (data != EEPROM_OK)
223 return data;
224 79
225 // Set new Page status 80 if (page % FEE_PAGE_SIZE) page = page + FEE_PAGE_SIZE;
226 FlashStatus = FLASH_ProgramHalfWord(newPage, EEPROM_VALID_PAGE); 81 page = (page / FEE_PAGE_SIZE) - 1;
227 if (FlashStatus != FLASH_COMPLETE)
228 return FlashStatus;
229 82
230 return EEPROM_OK; 83 // if current data is 0xFF, the byte is empty, just overwrite with the new one
231} 84 if ((*(__IO uint16_t*)(FEE_PAGE_BASE_ADDRESS + FEE_ADDR_OFFSET(Address))) == FEE_EMPTY_WORD) {
232 85
233/** 86 FlashStatus = FLASH_ProgramHalfWord(FEE_PAGE_BASE_ADDRESS + FEE_ADDR_OFFSET(Address), (uint16_t)(0x00FF & DataByte));
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 } 87 }
88 else {
274 89
275 // Check each active page address starting from begining 90 // Copy Page to a buffer
276 for (idx = pageBase + 4; idx < pageEnd; idx += 4) 91 memcpy(DataBuf, (uint8_t*)FEE_PAGE_BASE_ADDRESS + (page * FEE_PAGE_SIZE), FEE_PAGE_SIZE); // !!! Calculate base address for the desired page
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 92
332uint16_t EEPROM_init(void) 93 // check if new data is differ to current data, return if not, proceed if yes
333{ 94 if (DataByte == *(__IO uint8_t*)(FEE_PAGE_BASE_ADDRESS + FEE_ADDR_OFFSET(Address))) {
334 uint16_t status0 = 6, status1 = 6; 95 return 0;
335 FLASH_Status FlashStatus; 96 }
336 97
337 FLASH_Unlock(); 98 // manipulate desired data byte in temp data array if new byte is differ to the current
338 Status = EEPROM_NO_VALID_PAGE; 99 DataBuf[FEE_ADDR_OFFSET(Address)] = DataByte;
339 100
340 status0 = (*(__IO uint16_t *)PageBase0); 101 //Erase Page
341 status1 = (*(__IO uint16_t *)PageBase1); 102 FlashStatus = FLASH_ErasePage(FEE_PAGE_BASE_ADDRESS + page);
342 103
343 switch (status0) 104 // Write new data (whole page) to flash if data has beed changed
344 { 105 for(i = 0; i < (FEE_PAGE_SIZE / 2); i++) {
345/* 106 if ((__IO uint16_t)(0xFF00 | DataBuf[FEE_ADDR_OFFSET(i)]) != 0xFFFF) {
346 Page0 Page1 107 FlashStatus = FLASH_ProgramHalfWord((FEE_PAGE_BASE_ADDRESS + (page * FEE_PAGE_SIZE)) + (i * 2), (uint16_t)(0xFF00 | DataBuf[FEE_ADDR_OFFSET(i)]));
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 } 108 }
388 } 109 }
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 110
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 } 111 }
451 // Erase Page1 112 return FlashStatus;
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 (temp == Data)
578 return EEPROM_SAME_VALUE;
579 else
580 return EEPROM_write(Address, Data);
581} 113}
114/*****************************************************************************
115* Read once data byte from a specified address.
116*******************************************************************************/
117uint8_t EEPROM_ReadDataByte (uint16_t Address) {
582 118
583/** 119 uint8_t DataByte = 0xFF;
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 120
598 *Count = EE_GetVariablesCount(pageBase, 0xFFFF); 121 // Get Byte from specified address
599 return EEPROM_OK; 122 DataByte = (*(__IO uint8_t*)(FEE_PAGE_BASE_ADDRESS + FEE_ADDR_OFFSET(Address)));
600}
601 123
602uint16_t EEPROM_maxcount(void) 124 return DataByte;
603{
604 return ((PageSize / 4)-1);
605} 125}
606 126
607 127/*****************************************************************************
128* Wrap library in AVR style functions.
129*******************************************************************************/
608uint8_t eeprom_read_byte (const uint8_t *Address) 130uint8_t eeprom_read_byte (const uint8_t *Address)
609{ 131{
610 const uint16_t p = (const uint32_t) Address; 132 const uint16_t p = (const uint32_t) Address;
611 uint16_t temp; 133 return EEPROM_ReadDataByte(p);
612 EEPROM_read(p, &temp);
613 return (uint8_t) temp;
614} 134}
615 135
616void eeprom_write_byte (uint8_t *Address, uint8_t Value) 136void eeprom_write_byte (uint8_t *Address, uint8_t Value)
617{ 137{
618 uint16_t p = (uint32_t) Address; 138 uint16_t p = (uint32_t) Address;
619 EEPROM_write(p, (uint16_t) Value); 139 EEPROM_WriteDataByte(p, Value);
620} 140}
621 141
622void eeprom_update_byte (uint8_t *Address, uint8_t Value) 142void eeprom_update_byte (uint8_t *Address, uint8_t Value)
623{ 143{
624 uint16_t p = (uint32_t) Address; 144 uint16_t p = (uint32_t) Address;
625 EEPROM_update(p, (uint16_t) Value); 145 EEPROM_WriteDataByte(p, Value);
626} 146}
627 147
628uint16_t eeprom_read_word (const uint16_t *Address) 148uint16_t eeprom_read_word (const uint16_t *Address)
629{ 149{
630 const uint16_t p = (const uint32_t) Address; 150 const uint16_t p = (const uint32_t) Address;
631 uint16_t temp; 151 return EEPROM_ReadDataByte(p) | (EEPROM_ReadDataByte(p+1) << 8);
632 EEPROM_read(p, &temp);
633 return temp;
634} 152}
635 153
636void eeprom_write_word (uint16_t *Address, uint16_t Value) 154void eeprom_write_word (uint16_t *Address, uint16_t Value)
637{ 155{
638 uint16_t p = (uint32_t) Address; 156 uint16_t p = (uint32_t) Address;
639 EEPROM_write(p, Value); 157 EEPROM_WriteDataByte(p, (uint8_t) Value);
158 EEPROM_WriteDataByte(p + 1, (uint8_t) (Value >> 8));
640} 159}
641 160
642void eeprom_update_word (uint16_t *Address, uint16_t Value) 161void eeprom_update_word (uint16_t *Address, uint16_t Value)
643{ 162{
644 uint16_t p = (uint32_t) Address; 163 uint16_t p = (uint32_t) Address;
645 EEPROM_update(p, Value); 164 EEPROM_WriteDataByte(p, (uint8_t) Value);
165 EEPROM_WriteDataByte(p + 1, (uint8_t) (Value >> 8));
646} 166}
647 167
648uint32_t eeprom_read_dword (const uint32_t *Address) 168uint32_t eeprom_read_dword (const uint32_t *Address)
649{ 169{
650 const uint16_t p = (const uint32_t) Address; 170 const uint16_t p = (const uint32_t) Address;
651 uint16_t temp1, temp2; 171 return EEPROM_ReadDataByte(p) | (EEPROM_ReadDataByte(p+1) << 8)
652 EEPROM_read(p, &temp1); 172 | (EEPROM_ReadDataByte(p+2) << 16) | (EEPROM_ReadDataByte(p+3) << 24);
653 EEPROM_read(p + 1, &temp2);
654 return temp1 | (temp2 << 16);
655} 173}
656 174
657void eeprom_write_dword (uint32_t *Address, uint32_t Value) 175void eeprom_write_dword (uint32_t *Address, uint32_t Value)
658{ 176{
659 uint16_t temp = (uint16_t) Value; 177 uint16_t p = (const uint32_t) Address;
660 uint16_t p = (uint32_t) Address; 178 EEPROM_WriteDataByte(p, (uint8_t) Value);
661 EEPROM_write(p, temp); 179 EEPROM_WriteDataByte(p+1, (uint8_t) (Value >> 8));
662 temp = (uint16_t) (Value >> 16); 180 EEPROM_WriteDataByte(p+2, (uint8_t) (Value >> 16));
663 EEPROM_write(p + 1, temp); 181 EEPROM_WriteDataByte(p+3, (uint8_t) (Value >> 24));
664} 182}
665 183
666void eeprom_update_dword (uint32_t *Address, uint32_t Value) 184void eeprom_update_dword (uint32_t *Address, uint32_t Value)
667{ 185{
668 uint16_t temp = (uint16_t) Value; 186 uint16_t p = (const uint32_t) Address;
669 uint16_t p = (uint32_t) Address; 187 EEPROM_WriteDataByte(p, (uint8_t) Value);
670 EEPROM_update(p, temp); 188 EEPROM_WriteDataByte(p+1, (uint8_t) (Value >> 8));
671 temp = (uint16_t) (Value >> 16); 189 EEPROM_WriteDataByte(p+2, (uint8_t) (Value >> 16));
672 EEPROM_update(p + 1, temp); 190 EEPROM_WriteDataByte(p+3, (uint8_t) (Value >> 24));
191}
192
193void eeprom_read_block(void *buf, const void *addr, uint32_t len) {
194 const uint8_t *p = (const uint8_t *)addr;
195 uint8_t *dest = (uint8_t *)buf;
196 while (len--) {
197 *dest++ = eeprom_read_byte(p++);
198 }
199}
200
201void eeprom_write_block(const void *buf, void *addr, uint32_t len) {
202 uint8_t *p = (uint8_t *)addr;
203 const uint8_t *src = (const uint8_t *)buf;
204 while (len--) {
205 eeprom_write_byte(p++, *src++);
206 }
207}
208
209void eeprom_update_block(const void *buf, void *addr, uint32_t len) {
210 uint8_t *p = (uint8_t *)addr;
211 const uint8_t *src = (const uint8_t *)buf;
212 while (len--) {
213 eeprom_write_byte(p++, *src++);
214 }
673} 215}
diff --git a/tmk_core/common/chibios/eeprom_stm32.h b/tmk_core/common/chibios/eeprom_stm32.h
index 09229530c..892e417b7 100755
--- a/tmk_core/common/chibios/eeprom_stm32.h
+++ b/tmk_core/common/chibios/eeprom_stm32.h
@@ -10,15 +10,17 @@
10 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 10 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
11 * DEALINGS IN THE SOFTWARE. 11 * DEALINGS IN THE SOFTWARE.
12 * 12 *
13 * This files are free to use from https://github.com/rogerclarkmelbourne/Arduino_STM32 and 13 * This files are free to use from http://engsta.com/stm32-flash-memory-eeprom-emulator/ by
14 * https://github.com/leaflabs/libmaple 14 * Artur F.
15 * 15 *
16 * Modifications for QMK and STM32F303 by Yiancar 16 * Modifications for QMK and STM32F303 by Yiancar
17 *
18 * This library assumes 8-bit data locations. To add a new MCU, please provide the flash
19 * page size and the total flash size in Kb. The number of available pages must be a multiple
20 * of 2. Only half of the pages account for the total EEPROM size.
21 * This library also assumes that the pages are not used by the firmware.
17 */ 22 */
18 23
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 24#ifndef __EEPROM_H
23#define __EEPROM_H 25#define __EEPROM_H
24 26
@@ -38,9 +40,11 @@
38 40
39#ifndef EEPROM_PAGE_SIZE 41#ifndef EEPROM_PAGE_SIZE
40 #if defined (MCU_STM32F103RB) 42 #if defined (MCU_STM32F103RB)
41 #define EEPROM_PAGE_SIZE (uint16_t)0x400 /* Page size = 1KByte */ 43 #define FEE_PAGE_SIZE (uint16_t)0x400 // Page size = 1KByte
44 #define FEE_DENSITY_PAGES 2 // How many pages are used
42 #elif defined (MCU_STM32F103ZE) || defined (MCU_STM32F103RE) || defined (MCU_STM32F103RD) || defined (MCU_STM32F303CC) 45 #elif defined (MCU_STM32F103ZE) || defined (MCU_STM32F103RE) || defined (MCU_STM32F103RD) || defined (MCU_STM32F303CC)
43 #define EEPROM_PAGE_SIZE (uint16_t)0x800 /* Page size = 2KByte */ 46 #define FEE_PAGE_SIZE (uint16_t)0x800 // Page size = 2KByte
47 #define FEE_DENSITY_PAGES 4 // How many pages are used
44 #else 48 #else
45 #error "No MCU type specified. Add something like -DMCU_STM32F103RB to your compiler arguments (probably in a Makefile)." 49 #error "No MCU type specified. Add something like -DMCU_STM32F103RB to your compiler arguments (probably in a Makefile)."
46 #endif 50 #endif
@@ -48,48 +52,30 @@
48 52
49#ifndef EEPROM_START_ADDRESS 53#ifndef EEPROM_START_ADDRESS
50 #if defined (MCU_STM32F103RB) 54 #if defined (MCU_STM32F103RB)
51 #define EEPROM_START_ADDRESS ((uint32_t)(0x8000000 + 128 * 1024 - 2 * EEPROM_PAGE_SIZE)) 55 #define FEE_MCU_FLASH_SIZE 128 // Size in Kb
52 #elif defined (MCU_STM32F103ZE) || defined (MCU_STM32F103RE) 56 #elif defined (MCU_STM32F103ZE) || defined (MCU_STM32F103RE)
53 #define EEPROM_START_ADDRESS ((uint32_t)(0x8000000 + 512 * 1024 - 2 * EEPROM_PAGE_SIZE)) 57 #define FEE_MCU_FLASH_SIZE 512 // Size in Kb
54 #elif defined (MCU_STM32F103RD) 58 #elif defined (MCU_STM32F103RD)
55 #define EEPROM_START_ADDRESS ((uint32_t)(0x8000000 + 384 * 1024 - 2 * EEPROM_PAGE_SIZE)) 59 #define FEE_MCU_FLASH_SIZE 384 // Size in Kb
56 #elif defined (MCU_STM32F303CC) 60 #elif defined (MCU_STM32F303CC)
57 #define EEPROM_START_ADDRESS ((uint32_t)(0x8000000 + 256 * 1024 - 2 * EEPROM_PAGE_SIZE)) 61 #define FEE_MCU_FLASH_SIZE 256 // Size in Kb
58 #else 62 #else
59 #error "No MCU type specified. Add something like -DMCU_STM32F103RB to your compiler arguments (probably in a Makefile)." 63 #error "No MCU type specified. Add something like -DMCU_STM32F103RB to your compiler arguments (probably in a Makefile)."
60 #endif 64 #endif
61#endif 65#endif
62 66
63/* Pages 0 and 1 base and end addresses */ 67// DONT CHANGE
64#define EEPROM_PAGE0_BASE ((uint32_t)(EEPROM_START_ADDRESS + 0x000)) 68// Choose location for the first EEPROM Page address on the top of flash
65#define EEPROM_PAGE1_BASE ((uint32_t)(EEPROM_START_ADDRESS + EEPROM_PAGE_SIZE)) 69#define FEE_PAGE_BASE_ADDRESS ((uint32_t)(0x8000000 + FEE_MCU_FLASH_SIZE * 1024 - FEE_DENSITY_PAGES * FEE_PAGE_SIZE))
66 70#define FEE_DENSITY_BYTES ((FEE_PAGE_SIZE / 2) * FEE_DENSITY_PAGES - 1)
67/* Page status definitions */ 71#define FEE_LAST_PAGE_ADDRESS (FEE_PAGE_BASE_ADDRESS + (FEE_PAGE_SIZE * FEE_DENSITY_PAGES))
68#define EEPROM_ERASED ((uint16_t)0xFFFF) /* PAGE is empty */ 72#define FEE_EMPTY_WORD ((uint16_t)0xFFFF)
69#define EEPROM_RECEIVE_DATA ((uint16_t)0xEEEE) /* PAGE is marked to receive data */ 73#define FEE_ADDR_OFFSET(Address)(Address * 2) // 1Byte per Word will be saved to preserve Flash
70#define EEPROM_VALID_PAGE ((uint16_t)0x0000) /* PAGE containing valid data */
71
72/* Page full define */
73enum uint16_t
74 {
75 EEPROM_OK = ((uint16_t)0x0000),
76 EEPROM_OUT_SIZE = ((uint16_t)0x0081),
77 EEPROM_BAD_ADDRESS = ((uint16_t)0x0082),
78 EEPROM_BAD_FLASH = ((uint16_t)0x0083),
79 EEPROM_NOT_INIT = ((uint16_t)0x0084),
80 EEPROM_SAME_VALUE = ((uint16_t)0x0085),
81 EEPROM_NO_VALID_PAGE = ((uint16_t)0x00AB)
82 };
83
84#define EEPROM_DEFAULT_DATA 0xFFFF
85 74
86 uint16_t EEPROM_init(void); 75// Use this function to initialize the functionality
87 uint16_t EEPROM_format(void); 76uint16_t EEPROM_Init(void);
88 uint16_t EEPROM_erases(uint16_t *); 77void EEPROM_Erase (void);
89 uint16_t EEPROM_read (uint16_t address, uint16_t *data); 78uint16_t EEPROM_WriteDataByte (uint16_t Address, uint8_t DataByte);
90 uint16_t EEPROM_write(uint16_t address, uint16_t data); 79uint8_t EEPROM_ReadDataByte (uint16_t Address);
91 uint16_t EEPROM_update(uint16_t address, uint16_t data);
92 uint16_t EEPROM_count(uint16_t *);
93 uint16_t EEPROM_maxcount(void);
94 80
95#endif /* __EEPROM_H */ 81#endif /* __EEPROM_H */
diff --git a/tmk_core/common/chibios/flash_stm32.c b/tmk_core/common/chibios/flash_stm32.c
index 273593484..164654a15 100755
--- a/tmk_core/common/chibios/flash_stm32.c
+++ b/tmk_core/common/chibios/flash_stm32.c
@@ -186,3 +186,18 @@ void FLASH_Lock(void)
186 /* Set the Lock Bit to lock the FPEC and the FCR */ 186 /* Set the Lock Bit to lock the FPEC and the FCR */
187 FLASH->CR |= FLASH_CR_LOCK; 187 FLASH->CR |= FLASH_CR_LOCK;
188} 188}
189
190/**
191 * @brief Clears the FLASH's pending flags.
192 * @param FLASH_FLAG: specifies the FLASH flags to clear.
193 * This parameter can be any combination of the following values:
194 * @arg FLASH_FLAG_PGERR: FLASH Programming error flag flag
195 * @arg FLASH_FLAG_WRPERR: FLASH Write protected error flag
196 * @arg FLASH_FLAG_EOP: FLASH End of Programming flag
197 * @retval None
198 */
199void FLASH_ClearFlag(uint32_t FLASH_FLAG)
200{
201 /* Clear the flags */
202 FLASH->SR = FLASH_FLAG;
203}
diff --git a/tmk_core/common/chibios/flash_stm32.h b/tmk_core/common/chibios/flash_stm32.h
index cc065cbca..3c99cc566 100755
--- a/tmk_core/common/chibios/flash_stm32.h
+++ b/tmk_core/common/chibios/flash_stm32.h
@@ -45,6 +45,7 @@ FLASH_Status FLASH_ProgramHalfWord(uint32_t Address, uint16_t Data);
45 45
46void FLASH_Unlock(void); 46void FLASH_Unlock(void);
47void FLASH_Lock(void); 47void FLASH_Lock(void);
48void FLASH_ClearFlag(uint32_t FLASH_FLAG);
48 49
49#ifdef __cplusplus 50#ifdef __cplusplus
50} 51}
diff --git a/tmk_core/common/eeconfig.c b/tmk_core/common/eeconfig.c
index d8bab7d2e..59b2bffbc 100644
--- a/tmk_core/common/eeconfig.c
+++ b/tmk_core/common/eeconfig.c
@@ -33,7 +33,7 @@ void eeconfig_init_kb(void) {
33 */ 33 */
34void eeconfig_init_quantum(void) { 34void eeconfig_init_quantum(void) {
35#ifdef STM32_EEPROM_ENABLE 35#ifdef STM32_EEPROM_ENABLE
36 EEPROM_format(); 36 EEPROM_Erase();
37#endif 37#endif
38 eeprom_update_word(EECONFIG_MAGIC, EECONFIG_MAGIC_NUMBER); 38 eeprom_update_word(EECONFIG_MAGIC, EECONFIG_MAGIC_NUMBER);
39 eeprom_update_byte(EECONFIG_DEBUG, 0); 39 eeprom_update_byte(EECONFIG_DEBUG, 0);
@@ -74,7 +74,7 @@ void eeconfig_enable(void)
74void eeconfig_disable(void) 74void eeconfig_disable(void)
75{ 75{
76#ifdef STM32_EEPROM_ENABLE 76#ifdef STM32_EEPROM_ENABLE
77 EEPROM_format(); 77 EEPROM_Erase();
78#endif 78#endif
79 eeprom_update_word(EECONFIG_MAGIC, EECONFIG_MAGIC_NUMBER_OFF); 79 eeprom_update_word(EECONFIG_MAGIC, EECONFIG_MAGIC_NUMBER_OFF);
80} 80}
diff --git a/tmk_core/common/eeconfig.h b/tmk_core/common/eeconfig.h
index 8d4e1d4d0..eedd67602 100644
--- a/tmk_core/common/eeconfig.h
+++ b/tmk_core/common/eeconfig.h
@@ -25,8 +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#define EECONFIG_MAGIC_NUMBER_OFF (uint16_t)0xFFFF 26#define EECONFIG_MAGIC_NUMBER_OFF (uint16_t)0xFFFF
27 27
28/* eeprom parameteter address */ 28/* EEPROM parameter address */
29#if !defined(STM32_EEPROM_ENABLE)
30#define EECONFIG_MAGIC (uint16_t *)0 29#define EECONFIG_MAGIC (uint16_t *)0
31#define EECONFIG_DEBUG (uint8_t *)2 30#define EECONFIG_DEBUG (uint8_t *)2
32#define EECONFIG_DEFAULT_LAYER (uint8_t *)3 31#define EECONFIG_DEFAULT_LAYER (uint8_t *)3
@@ -42,24 +41,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
42#define EECONFIG_KEYBOARD (uint32_t *)15 41#define EECONFIG_KEYBOARD (uint32_t *)15
43#define EECONFIG_USER (uint32_t *)19 42#define EECONFIG_USER (uint32_t *)19
44 43
45#else
46/* STM32F3 uses 16byte block. Reconfigure memory map */
47#define EECONFIG_MAGIC (uint16_t *)0
48#define EECONFIG_DEBUG (uint8_t *)1
49#define EECONFIG_DEFAULT_LAYER (uint8_t *)2
50#define EECONFIG_KEYMAP (uint8_t *)3
51#define EECONFIG_MOUSEKEY_ACCEL (uint8_t *)4
52#define EECONFIG_BACKLIGHT (uint8_t *)5
53#define EECONFIG_AUDIO (uint8_t *)6
54#define EECONFIG_RGBLIGHT (uint32_t *)7
55#define EECONFIG_UNICODEMODE (uint8_t *)9
56#define EECONFIG_STENOMODE (uint8_t *)10
57// EEHANDS for two handed boards
58#define EECONFIG_HANDEDNESS (uint8_t *)11
59#define EECONFIG_KEYBOARD (uint32_t *)12
60#define EECONFIG_USER (uint32_t *)14
61#endif
62
63/* debug bit */ 44/* debug bit */
64#define EECONFIG_DEBUG_ENABLE (1<<0) 45#define EECONFIG_DEBUG_ENABLE (1<<0)
65#define EECONFIG_DEBUG_MATRIX (1<<1) 46#define EECONFIG_DEBUG_MATRIX (1<<1)
diff --git a/tmk_core/common/eeprom.h b/tmk_core/common/eeprom.h
index 3696d0df3..5ae0f6eeb 100644
--- a/tmk_core/common/eeprom.h
+++ b/tmk_core/common/eeprom.h
@@ -20,5 +20,4 @@ void eeprom_update_dword (uint32_t *__p, uint32_t __value);
20void eeprom_update_block (const void *__src, void *__dst, uint32_t __n); 20void eeprom_update_block (const void *__src, void *__dst, uint32_t __n);
21#endif 21#endif
22 22
23
24#endif /* TMK_CORE_COMMON_EEPROM_H_ */ 23#endif /* TMK_CORE_COMMON_EEPROM_H_ */
diff --git a/tmk_core/common/host.h b/tmk_core/common/host.h
index aeabba710..3d172eed6 100644
--- a/tmk_core/common/host.h
+++ b/tmk_core/common/host.h
@@ -15,14 +15,18 @@ You should have received a copy of the GNU General Public License
15along with this program. If not, see <http://www.gnu.org/licenses/>. 15along with this program. If not, see <http://www.gnu.org/licenses/>.
16*/ 16*/
17 17
18#ifndef HOST_H 18#pragma once
19#define HOST_H
20 19
21#include <stdint.h> 20#include <stdint.h>
22#include <stdbool.h> 21#include <stdbool.h>
23#include "report.h" 22#include "report.h"
24#include "host_driver.h" 23#include "host_driver.h"
25 24
25#define IS_LED_ON(leds, led_name) ( (leds) & (1 << (led_name)))
26#define IS_LED_OFF(leds, led_name) (~(leds) & (1 << (led_name)))
27
28#define IS_HOST_LED_ON(led_name) IS_LED_ON(host_keyboard_leds(), led_name)
29#define IS_HOST_LED_OFF(led_name) IS_LED_OFF(host_keyboard_leds(), led_name)
26 30
27#ifdef __cplusplus 31#ifdef __cplusplus
28extern "C" { 32extern "C" {
@@ -31,7 +35,6 @@ extern "C" {
31extern uint8_t keyboard_idle; 35extern uint8_t keyboard_idle;
32extern uint8_t keyboard_protocol; 36extern uint8_t keyboard_protocol;
33 37
34
35/* host driver */ 38/* host driver */
36void host_set_driver(host_driver_t *driver); 39void host_set_driver(host_driver_t *driver);
37host_driver_t *host_get_driver(void); 40host_driver_t *host_get_driver(void);
@@ -49,5 +52,3 @@ uint16_t host_last_consumer_report(void);
49#ifdef __cplusplus 52#ifdef __cplusplus
50} 53}
51#endif 54#endif
52
53#endif
diff --git a/tmk_core/common/keyboard.h b/tmk_core/common/keyboard.h
index 71e594a89..ea2f336e9 100644
--- a/tmk_core/common/keyboard.h
+++ b/tmk_core/common/keyboard.h
@@ -67,6 +67,8 @@ void keyboard_init(void);
67void keyboard_task(void); 67void keyboard_task(void);
68/* it runs when host LED status is updated */ 68/* it runs when host LED status is updated */
69void keyboard_set_leds(uint8_t leds); 69void keyboard_set_leds(uint8_t leds);
70/* it runs whenever code has to behave differently on a slave */
71bool is_keyboard_master(void);
70 72
71#ifdef __cplusplus 73#ifdef __cplusplus
72} 74}
diff --git a/tmk_core/common/keycode.h b/tmk_core/common/keycode.h
index ac3edbd21..d5904276e 100644
--- a/tmk_core/common/keycode.h
+++ b/tmk_core/common/keycode.h
@@ -46,6 +46,22 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
46#define MOD_BIT(code) (1 << MOD_INDEX(code)) 46#define MOD_BIT(code) (1 << MOD_INDEX(code))
47#define MOD_INDEX(code) ((code) & 0x07) 47#define MOD_INDEX(code) ((code) & 0x07)
48 48
49#define MOD_MASK_CTRL (MOD_BIT(KC_LCTRL) | MOD_BIT(KC_RCTRL))
50#define MOD_MASK_SHIFT (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT))
51#define MOD_MASK_ALT (MOD_BIT(KC_LALT) | MOD_BIT(KC_RALT))
52#define MOD_MASK_GUI (MOD_BIT(KC_LGUI) | MOD_BIT(KC_RGUI))
53#define MOD_MASK_CS (MOD_MASK_CTRL | MOD_MASK_SHIFT)
54#define MOD_MASK_CA (MOD_MASK_CTRL | MOD_MASK_ALT)
55#define MOD_MASK_CG (MOD_MASK_CTRL | MOD_MASK_GUI)
56#define MOD_MASK_SA (MOD_MASK_SHIFT | MOD_MASK_ALT)
57#define MOD_MASK_SG (MOD_MASK_SHIFT | MOD_MASK_GUI)
58#define MOD_MASK_AG (MOD_MASK_ALT | MOD_MASK_GUI)
59#define MOD_MASK_CSA (MOD_MASK_CTRL | MOD_MASK_SHIFT | MOD_MASK_ALT)
60#define MOD_MASK_CSG (MOD_MASK_CTRL | MOD_MASK_SHIFT | MOD_MASK_GUI)
61#define MOD_MASK_CAG (MOD_MASK_CTRL | MOD_MASK_ALT | MOD_MASK_GUI)
62#define MOD_MASK_SAG (MOD_MASK_SHIFT | MOD_MASK_ALT | MOD_MASK_GUI)
63#define MOD_MASK_CSAG (MOD_MASK_CTRL | MOD_MASK_SHIFT | MOD_MASK_ALT | MOD_MASK_GUI)
64
49#define FN_BIT(code) (1 << FN_INDEX(code)) 65#define FN_BIT(code) (1 << FN_INDEX(code))
50#define FN_INDEX(code) ((code) - KC_FN0) 66#define FN_INDEX(code) ((code) - KC_FN0)
51#define FN_MIN KC_FN0 67#define FN_MIN KC_FN0
@@ -174,6 +190,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
174#define KC_BRIU KC_BRIGHTNESS_UP 190#define KC_BRIU KC_BRIGHTNESS_UP
175#define KC_BRID KC_BRIGHTNESS_DOWN 191#define KC_BRID KC_BRIGHTNESS_DOWN
176 192
193/* System Specific */
194#define KC_BRMU KC_PAUSE
195#define KC_BRMD KC_SCROLLLOCK
196
177/* Mouse Keys */ 197/* Mouse Keys */
178#define KC_MS_U KC_MS_UP 198#define KC_MS_U KC_MS_UP
179#define KC_MS_D KC_MS_DOWN 199#define KC_MS_D KC_MS_DOWN
diff --git a/tmk_core/common/progmem.h b/tmk_core/common/progmem.h
index dcc9efb3c..de9313839 100644
--- a/tmk_core/common/progmem.h
+++ b/tmk_core/common/progmem.h
@@ -5,9 +5,9 @@
5# include <avr/pgmspace.h> 5# include <avr/pgmspace.h>
6#else 6#else
7# define PROGMEM 7# define PROGMEM
8# define pgm_read_byte(p) *((unsigned char*)p) 8# define pgm_read_byte(p) *((unsigned char*)(p))
9# define pgm_read_word(p) *((uint16_t*)p) 9# define pgm_read_word(p) *((uint16_t*)(p))
10# define pgm_read_dword(p) *((uint32_t*)p) 10# define pgm_read_dword(p) *((uint32_t*)(p))
11#endif 11#endif
12 12
13#endif 13#endif
diff --git a/tmk_core/common/report.h b/tmk_core/common/report.h
index eb9afb727..e7c31bd37 100644
--- a/tmk_core/common/report.h
+++ b/tmk_core/common/report.h
@@ -48,8 +48,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
48#define TRANSPORT_STOP 0x00B7 48#define TRANSPORT_STOP 0x00B7
49#define TRANSPORT_STOP_EJECT 0x00CC 49#define TRANSPORT_STOP_EJECT 0x00CC
50#define TRANSPORT_PLAY_PAUSE 0x00CD 50#define TRANSPORT_PLAY_PAUSE 0x00CD
51#define BRIGHTNESSUP 0x006F 51#define BRIGHTNESS_UP 0x006F
52#define BRIGHTNESSDOWN 0x0070 52#define BRIGHTNESS_DOWN 0x0070
53/* application launch */ 53/* application launch */
54#define AL_CC_CONFIG 0x0183 54#define AL_CC_CONFIG 0x0183
55#define AL_EMAIL 0x018A 55#define AL_EMAIL 0x018A
@@ -192,8 +192,8 @@ typedef struct {
192 (key == KC_WWW_FORWARD ? AC_FORWARD : \ 192 (key == KC_WWW_FORWARD ? AC_FORWARD : \
193 (key == KC_WWW_STOP ? AC_STOP : \ 193 (key == KC_WWW_STOP ? AC_STOP : \
194 (key == KC_WWW_REFRESH ? AC_REFRESH : \ 194 (key == KC_WWW_REFRESH ? AC_REFRESH : \
195 (key == KC_BRIGHTNESS_UP ? BRIGHTNESSUP : \ 195 (key == KC_BRIGHTNESS_UP ? BRIGHTNESS_UP : \
196 (key == KC_BRIGHTNESS_DOWN ? BRIGHTNESSDOWN : \ 196 (key == KC_BRIGHTNESS_DOWN ? BRIGHTNESS_DOWN : \
197 (key == KC_WWW_FAVORITES ? AC_BOOKMARKS : 0))))))))))))))))))))))) 197 (key == KC_WWW_FAVORITES ? AC_BOOKMARKS : 0)))))))))))))))))))))))
198 198
199uint8_t has_anykey(report_keyboard_t* keyboard_report); 199uint8_t has_anykey(report_keyboard_t* keyboard_report);
diff --git a/tmk_core/common/wait.h b/tmk_core/common/wait.h
index a7cded942..a77840bce 100644
--- a/tmk_core/common/wait.h
+++ b/tmk_core/common/wait.h
@@ -15,6 +15,10 @@ extern "C" {
15# include "ch.h" 15# include "ch.h"
16# define wait_ms(ms) chThdSleepMilliseconds(ms) 16# define wait_ms(ms) chThdSleepMilliseconds(ms)
17# define wait_us(us) chThdSleepMicroseconds(us) 17# define wait_us(us) chThdSleepMicroseconds(us)
18#elif defined PROTOCOL_ARM_ATSAM
19# include "clks.h"
20# define wait_ms(ms) CLK_delay_ms(ms)
21# define wait_us(us) CLK_delay_us(us)
18#elif defined(__arm__) 22#elif defined(__arm__)
19# include "wait_api.h" 23# include "wait_api.h"
20#else // Unit tests 24#else // Unit tests
diff --git a/tmk_core/protocol/arm_atsam/arm_atsam_protocol.h b/tmk_core/protocol/arm_atsam/arm_atsam_protocol.h
index 2ba099174..928af8c7e 100644
--- a/tmk_core/protocol/arm_atsam/arm_atsam_protocol.h
+++ b/tmk_core/protocol/arm_atsam/arm_atsam_protocol.h
@@ -21,8 +21,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
21#include "samd51j18a.h" 21#include "samd51j18a.h"
22#include "md_bootloader.h" 22#include "md_bootloader.h"
23 23
24#include "timer.h"
24#include "d51_util.h" 25#include "d51_util.h"
25#include "clks.h" 26#include "clks.h"
27#include "wait.h"
26#include "adc.h" 28#include "adc.h"
27#include "i2c_master.h" 29#include "i2c_master.h"
28#include "spi.h" 30#include "spi.h"
diff --git a/tmk_core/protocol/arm_atsam/clks.c b/tmk_core/protocol/arm_atsam/clks.c
index 8768d0a99..1ff318e59 100644
--- a/tmk_core/protocol/arm_atsam/clks.c
+++ b/tmk_core/protocol/arm_atsam/clks.c
@@ -21,8 +21,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
21 21
22volatile clk_t system_clks; 22volatile clk_t system_clks;
23volatile uint64_t ms_clk; 23volatile uint64_t ms_clk;
24 24uint32_t usec_delay_mult;
25volatile uint8_t us_delay_done; 25#define USEC_DELAY_LOOP_CYCLES 3 //Sum of instruction cycles in us delay loop
26 26
27const uint32_t sercom_apbbase[] = {(uint32_t)SERCOM0,(uint32_t)SERCOM1,(uint32_t)SERCOM2,(uint32_t)SERCOM3,(uint32_t)SERCOM4,(uint32_t)SERCOM5}; 27const uint32_t sercom_apbbase[] = {(uint32_t)SERCOM0,(uint32_t)SERCOM1,(uint32_t)SERCOM2,(uint32_t)SERCOM3,(uint32_t)SERCOM4,(uint32_t)SERCOM5};
28const uint8_t sercom_pchan[] = {7, 8, 23, 24, 34, 35}; 28const uint8_t sercom_pchan[] = {7, 8, 23, 24, 34, 35};
@@ -73,6 +73,9 @@ void CLK_oscctrl_init(void)
73 73
74 system_clks.freq_gclk[0] = system_clks.freq_dpll[0]; 74 system_clks.freq_gclk[0] = system_clks.freq_dpll[0];
75 75
76 usec_delay_mult = system_clks.freq_gclk[0] / (USEC_DELAY_LOOP_CYCLES * 1000000);
77 if (usec_delay_mult < 1) usec_delay_mult = 1; //Never allow a multiplier of zero
78
76 DBGC(DC_CLK_OSC_INIT_COMPLETE); 79 DBGC(DC_CLK_OSC_INIT_COMPLETE);
77} 80}
78 81
@@ -158,23 +161,11 @@ void TC4_Handler()
158 } 161 }
159} 162}
160 163
161void TC5_Handler()
162{
163 if (TC5->COUNT16.INTFLAG.bit.MC0)
164 {
165 TC5->COUNT16.INTFLAG.reg = TC_INTENCLR_MC0;
166 us_delay_done = 1;
167 TC5->COUNT16.CTRLA.bit.ENABLE = 0;
168 while (TC5->COUNT16.SYNCBUSY.bit.ENABLE) {}
169 }
170}
171
172uint32_t CLK_enable_timebase(void) 164uint32_t CLK_enable_timebase(void)
173{ 165{
174 Gclk *pgclk = GCLK; 166 Gclk *pgclk = GCLK;
175 Mclk *pmclk = MCLK; 167 Mclk *pmclk = MCLK;
176 Tc *ptc4 = TC4; 168 Tc *ptc4 = TC4;
177 Tc *ptc5 = TC5;
178 Tc *ptc0 = TC0; 169 Tc *ptc0 = TC0;
179 Evsys *pevsys = EVSYS; 170 Evsys *pevsys = EVSYS;
180 171
@@ -189,11 +180,6 @@ uint32_t CLK_enable_timebase(void)
189 pgclk->PCHCTRL[TC4_GCLK_ID].bit.GEN = GEN_TC45; 180 pgclk->PCHCTRL[TC4_GCLK_ID].bit.GEN = GEN_TC45;
190 pgclk->PCHCTRL[TC4_GCLK_ID].bit.CHEN = 1; 181 pgclk->PCHCTRL[TC4_GCLK_ID].bit.CHEN = 1;
191 182
192 //unmask TC5 sourcegclk2 to TC5
193 pmclk->APBCMASK.bit.TC5_ = 1;
194 pgclk->PCHCTRL[TC5_GCLK_ID].bit.GEN = GEN_TC45;
195 pgclk->PCHCTRL[TC5_GCLK_ID].bit.CHEN = 1;
196
197 //configure TC4 183 //configure TC4
198 DBGC(DC_CLK_ENABLE_TIMEBASE_TC4_BEGIN); 184 DBGC(DC_CLK_ENABLE_TIMEBASE_TC4_BEGIN);
199 ptc4->COUNT16.CTRLA.bit.ENABLE = 0; 185 ptc4->COUNT16.CTRLA.bit.ENABLE = 0;
@@ -220,30 +206,6 @@ uint32_t CLK_enable_timebase(void)
220 206
221 DBGC(DC_CLK_ENABLE_TIMEBASE_TC4_COMPLETE); 207 DBGC(DC_CLK_ENABLE_TIMEBASE_TC4_COMPLETE);
222 208
223 //configure TC5
224 DBGC(DC_CLK_ENABLE_TIMEBASE_TC5_BEGIN);
225 ptc5->COUNT16.CTRLA.bit.ENABLE = 0;
226 while (ptc5->COUNT16.SYNCBUSY.bit.ENABLE) { DBGC(DC_CLK_ENABLE_TIMEBASE_TC5_SYNC_DISABLE); }
227 ptc5->COUNT16.CTRLA.bit.SWRST = 1;
228 while (ptc5->COUNT16.SYNCBUSY.bit.SWRST) { DBGC(DC_CLK_ENABLE_TIMEBASE_TC5_SYNC_SWRST_1); }
229 while (ptc5->COUNT16.CTRLA.bit.SWRST) { DBGC(DC_CLK_ENABLE_TIMEBASE_TC5_SYNC_SWRST_2); }
230
231 //CTRLA defaults
232 //CTRLB as default, counting up
233 ptc5->COUNT16.CTRLBCLR.reg = 5;
234 while (ptc5->COUNT16.SYNCBUSY.bit.CTRLB) { DBGC(DC_CLK_ENABLE_TIMEBASE_TC5_SYNC_CLTRB); }
235 //ptc5->COUNT16.DBGCTRL.bit.DBGRUN = 1;
236
237 //wave mode
238 ptc5->COUNT16.WAVE.bit.WAVEGEN = 1; //MFRQ match frequency mode, toggle each CC match
239 //generate event for next stage
240 ptc5->COUNT16.EVCTRL.bit.MCEO0 = 1;
241
242 NVIC_EnableIRQ(TC5_IRQn);
243 ptc5->COUNT16.INTENSET.bit.MC0 = 1;
244
245 DBGC(DC_CLK_ENABLE_TIMEBASE_TC5_COMPLETE);
246
247 //unmask TC0,1, sourcegclk2 to TC0,1 209 //unmask TC0,1, sourcegclk2 to TC0,1
248 pmclk->APBAMASK.bit.TC0_ = 1; 210 pmclk->APBAMASK.bit.TC0_ = 1;
249 pgclk->PCHCTRL[TC0_GCLK_ID].bit.GEN = GEN_TC45; 211 pgclk->PCHCTRL[TC0_GCLK_ID].bit.GEN = GEN_TC45;
@@ -289,37 +251,27 @@ uint32_t CLK_enable_timebase(void)
289 return 0; 251 return 0;
290} 252}
291 253
292uint32_t CLK_get_ms(void) 254void CLK_delay_us(uint32_t usec)
293{ 255{
294 return ms_clk; 256 asm (
295} 257 "CBZ R0, return\n\t" //If usec == 0, branch to return label
296 258 );
297void CLK_delay_us(uint16_t usec) 259 asm (
298{ 260 "MULS R0, %0\n\t" //Multiply R0(usec) by usec_delay_mult and store in R0
299 us_delay_done = 0; 261 ".balign 16\n\t" //Ensure loop is aligned for fastest performance
300 262 "loop: SUBS R0, #1\n\t" //Subtract 1 from R0 and update flags (1 cycle)
301 if (TC5->COUNT16.CTRLA.bit.ENABLE) 263 "BNE loop\n\t" //Branch if non-zero to loop label (2 cycles) NOTE: USEC_DELAY_LOOP_CYCLES is the sum of loop cycles
302 { 264 "return:\n\t" //Return label
303 TC5->COUNT16.CTRLA.bit.ENABLE = 0; 265 : //No output registers
304 while (TC5->COUNT16.SYNCBUSY.bit.ENABLE) {} 266 : "r" (usec_delay_mult) //For %0
305 } 267 );
306 268 //Note: BX LR generated
307 if (usec < 10) usec = 0;
308 else usec -= 10;
309
310 TC5->COUNT16.CC[0].reg = usec;
311 while (TC5->COUNT16.SYNCBUSY.bit.CC0) {}
312
313 TC5->COUNT16.CTRLA.bit.ENABLE = 1;
314 while (TC5->COUNT16.SYNCBUSY.bit.ENABLE) {}
315
316 while (!us_delay_done) {}
317} 269}
318 270
319void CLK_delay_ms(uint64_t msec) 271void CLK_delay_ms(uint64_t msec)
320{ 272{
321 msec += CLK_get_ms(); 273 msec += timer_read64();
322 while (msec > CLK_get_ms()) {} 274 while (msec > timer_read64()) {}
323} 275}
324 276
325void clk_enable_sercom_apbmask(int sercomn) 277void clk_enable_sercom_apbmask(int sercomn)
diff --git a/tmk_core/protocol/arm_atsam/clks.h b/tmk_core/protocol/arm_atsam/clks.h
index 96819bfdd..1b01a1764 100644
--- a/tmk_core/protocol/arm_atsam/clks.h
+++ b/tmk_core/protocol/arm_atsam/clks.h
@@ -77,9 +77,8 @@ void CLK_oscctrl_init(void);
77void CLK_reset_time(void); 77void CLK_reset_time(void);
78uint32_t CLK_set_gclk_freq(uint8_t gclkn, uint32_t freq); 78uint32_t CLK_set_gclk_freq(uint8_t gclkn, uint32_t freq);
79uint32_t CLK_enable_timebase(void); 79uint32_t CLK_enable_timebase(void);
80uint32_t CLK_get_ms(void); 80uint64_t timer_read64(void);
81uint64_t CLK_get_us(void); 81void CLK_delay_us(uint32_t usec);
82void CLK_delay_us(uint16_t usec);
83void CLK_delay_ms(uint64_t msec); 82void CLK_delay_ms(uint64_t msec);
84 83
85uint32_t CLK_set_spi_freq(uint8_t sercomn, uint32_t freq); 84uint32_t CLK_set_spi_freq(uint8_t sercomn, uint32_t freq);
diff --git a/tmk_core/protocol/arm_atsam/i2c_master.c b/tmk_core/protocol/arm_atsam/i2c_master.c
index f608a79cc..d91a851f3 100644
--- a/tmk_core/protocol/arm_atsam/i2c_master.c
+++ b/tmk_core/protocol/arm_atsam/i2c_master.c
@@ -265,12 +265,12 @@ uint8_t I2C3733_Init_Control(void)
265 //USB state machine will enable driver when communication is ready 265 //USB state machine will enable driver when communication is ready
266 I2C3733_Control_Set(0); 266 I2C3733_Control_Set(0);
267 267
268 CLK_delay_ms(1); 268 wait_ms(1);
269 269
270 sr_exp_data.bit.IRST = 0; 270 sr_exp_data.bit.IRST = 0;
271 SR_EXP_WriteData(); 271 SR_EXP_WriteData();
272 272
273 CLK_delay_ms(1); 273 wait_ms(1);
274 274
275 DBGC(DC_I2C3733_INIT_CONTROL_COMPLETE); 275 DBGC(DC_I2C3733_INIT_CONTROL_COMPLETE);
276 276
diff --git a/tmk_core/protocol/arm_atsam/led_matrix.c b/tmk_core/protocol/arm_atsam/led_matrix.c
index e914fc80e..04d05af6d 100644
--- a/tmk_core/protocol/arm_atsam/led_matrix.c
+++ b/tmk_core/protocol/arm_atsam/led_matrix.c
@@ -18,6 +18,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
18#include "arm_atsam_protocol.h" 18#include "arm_atsam_protocol.h"
19#include "tmk_core/common/led.h" 19#include "tmk_core/common/led.h"
20#include <string.h> 20#include <string.h>
21#include <math.h>
21 22
22void SERCOM1_0_Handler( void ) 23void SERCOM1_0_Handler( void )
23{ 24{
@@ -217,6 +218,7 @@ void disp_calc_extents(void)
217 218
218 disp.width = disp.right - disp.left; 219 disp.width = disp.right - disp.left;
219 disp.height = disp.top - disp.bottom; 220 disp.height = disp.top - disp.bottom;
221 disp.max_distance = sqrtf(powf(disp.width, 2) + powf(disp.height, 2));
220} 222}
221 223
222void disp_pixel_setup(void) 224void disp_pixel_setup(void)
@@ -249,6 +251,7 @@ uint8_t led_animation_breathing;
249uint8_t led_animation_breathe_cur; 251uint8_t led_animation_breathe_cur;
250uint8_t breathe_step; 252uint8_t breathe_step;
251uint8_t breathe_dir; 253uint8_t breathe_dir;
254uint8_t led_animation_circular;
252uint64_t led_next_run; 255uint64_t led_next_run;
253 256
254uint8_t led_animation_id; 257uint8_t led_animation_id;
@@ -265,6 +268,7 @@ void led_matrix_run(void)
265 float go; 268 float go;
266 float bo; 269 float bo;
267 float po; 270 float po;
271
268 uint8_t led_this_run = 0; 272 uint8_t led_this_run = 0;
269 led_setup_t *f = (led_setup_t*)led_setups[led_animation_id]; 273 led_setup_t *f = (led_setup_t*)led_setups[led_animation_id];
270 274
@@ -327,13 +331,18 @@ void led_matrix_run(void)
327 for (fcur = 0; fcur < fmax; fcur++) 331 for (fcur = 0; fcur < fmax; fcur++)
328 { 332 {
329 333
330 if (led_animation_orientation) 334 if (led_animation_circular) {
331 { 335 po = sqrtf((powf(fabsf((disp.width / 2) - (led_cur->x - disp.left)), 2) + powf(fabsf((disp.height / 2) - (led_cur->y - disp.bottom)), 2))) / disp.max_distance * 100;
332 po = led_cur->py;
333 } 336 }
334 else 337 else {
335 { 338 if (led_animation_orientation)
336 po = led_cur->px; 339 {
340 po = led_cur->py;
341 }
342 else
343 {
344 po = led_cur->px;
345 }
337 } 346 }
338 347
339 float pomod; 348 float pomod;
@@ -466,6 +475,7 @@ uint8_t led_matrix_init(void)
466 led_animation_breathe_cur = BREATHE_MIN_STEP; 475 led_animation_breathe_cur = BREATHE_MIN_STEP;
467 breathe_step = 1; 476 breathe_step = 1;
468 breathe_dir = 1; 477 breathe_dir = 1;
478 led_animation_circular = 0;
469 479
470 gcr_min_counter = 0; 480 gcr_min_counter = 0;
471 v_5v_cat_hit = 0; 481 v_5v_cat_hit = 0;
@@ -494,11 +504,11 @@ void led_matrix_task(void)
494 if (led_enabled) 504 if (led_enabled)
495 { 505 {
496 //If an update may run and frame processing has completed 506 //If an update may run and frame processing has completed
497 if (CLK_get_ms() >= led_next_run && led_cur == lede) 507 if (timer_read64() >= led_next_run && led_cur == lede)
498 { 508 {
499 uint8_t drvid; 509 uint8_t drvid;
500 510
501 led_next_run = CLK_get_ms() + LED_UPDATE_RATE; //Set next frame update time 511 led_next_run = timer_read64() + LED_UPDATE_RATE; //Set next frame update time
502 512
503 //NOTE: GCR does not need to be timed with LED processing, but there is really no harm 513 //NOTE: GCR does not need to be timed with LED processing, but there is really no harm
504 if (gcr_actual != gcr_actual_last) 514 if (gcr_actual != gcr_actual_last)
diff --git a/tmk_core/protocol/arm_atsam/led_matrix.h b/tmk_core/protocol/arm_atsam/led_matrix.h
index cedea8a85..4513234e7 100644
--- a/tmk_core/protocol/arm_atsam/led_matrix.h
+++ b/tmk_core/protocol/arm_atsam/led_matrix.h
@@ -83,6 +83,7 @@ typedef struct led_disp_s {
83 float bottom; 83 float bottom;
84 float width; 84 float width;
85 float height; 85 float height;
86 float max_distance;
86} led_disp_t; 87} led_disp_t;
87 88
88uint8_t led_matrix_init(void); 89uint8_t led_matrix_init(void);
@@ -129,6 +130,7 @@ extern uint8_t led_animation_orientation;
129extern uint8_t led_animation_breathing; 130extern uint8_t led_animation_breathing;
130extern uint8_t led_animation_breathe_cur; 131extern uint8_t led_animation_breathe_cur;
131extern uint8_t breathe_dir; 132extern uint8_t breathe_dir;
133extern uint8_t led_animation_circular;
132extern const uint8_t led_setups_count; 134extern const uint8_t led_setups_count;
133 135
134extern void *led_setups[]; 136extern void *led_setups[];
diff --git a/tmk_core/protocol/arm_atsam/main_arm_atsam.c b/tmk_core/protocol/arm_atsam/main_arm_atsam.c
index 2bda7d7c7..eaad66e9f 100644
--- a/tmk_core/protocol/arm_atsam/main_arm_atsam.c
+++ b/tmk_core/protocol/arm_atsam/main_arm_atsam.c
@@ -159,7 +159,7 @@ void send_consumer(uint16_t data)
159 159
160void main_subtask_usb_state(void) 160void main_subtask_usb_state(void)
161{ 161{
162 static uint32_t fsmstate_on_delay = 0; //Delay timer to be sure USB is actually operating before bringing up hardware 162 static uint64_t fsmstate_on_delay = 0; //Delay timer to be sure USB is actually operating before bringing up hardware
163 uint8_t fsmstate_now = USB->DEVICE.FSMSTATUS.reg; //Current state from hardware register 163 uint8_t fsmstate_now = USB->DEVICE.FSMSTATUS.reg; //Current state from hardware register
164 164
165 if (fsmstate_now == USB_FSMSTATUS_FSMSTATE_SUSPEND_Val) //If USB SUSPENDED 165 if (fsmstate_now == USB_FSMSTATUS_FSMSTATE_SUSPEND_Val) //If USB SUSPENDED
@@ -188,9 +188,9 @@ void main_subtask_usb_state(void)
188 { 188 {
189 if (fsmstate_on_delay == 0) //If ON delay timer is cleared 189 if (fsmstate_on_delay == 0) //If ON delay timer is cleared
190 { 190 {
191 fsmstate_on_delay = CLK_get_ms() + 250; //Set ON delay timer 191 fsmstate_on_delay = timer_read64() + 250; //Set ON delay timer
192 } 192 }
193 else if (CLK_get_ms() > fsmstate_on_delay) //Else if ON delay timer is active and timed out 193 else if (timer_read64() > fsmstate_on_delay) //Else if ON delay timer is active and timed out
194 { 194 {
195 suspend_wakeup_init(); //Run wakeup routine 195 suspend_wakeup_init(); //Run wakeup routine
196 g_usb_state = fsmstate_now; //Save current USB state 196 g_usb_state = fsmstate_now; //Save current USB state
@@ -214,9 +214,9 @@ void main_subtask_power_check(void)
214{ 214{
215 static uint64_t next_5v_checkup = 0; 215 static uint64_t next_5v_checkup = 0;
216 216
217 if (CLK_get_ms() > next_5v_checkup) 217 if (timer_read64() > next_5v_checkup)
218 { 218 {
219 next_5v_checkup = CLK_get_ms() + 5; 219 next_5v_checkup = timer_read64() + 5;
220 220
221 v_5v = adc_get(ADC_5V); 221 v_5v = adc_get(ADC_5V);
222 v_5v_avg = 0.9 * v_5v_avg + 0.1 * v_5v; 222 v_5v_avg = 0.9 * v_5v_avg + 0.1 * v_5v;
@@ -229,9 +229,9 @@ void main_subtask_usb_extra_device(void)
229{ 229{
230 static uint64_t next_usb_checkup = 0; 230 static uint64_t next_usb_checkup = 0;
231 231
232 if (CLK_get_ms() > next_usb_checkup) 232 if (timer_read64() > next_usb_checkup)
233 { 233 {
234 next_usb_checkup = CLK_get_ms() + 10; 234 next_usb_checkup = timer_read64() + 10;
235 235
236 USB_HandleExtraDevice(); 236 USB_HandleExtraDevice();
237 } 237 }
@@ -325,9 +325,9 @@ int main(void)
325 keyboard_task(); 325 keyboard_task();
326 326
327#ifdef CONSOLE_ENABLE 327#ifdef CONSOLE_ENABLE
328 if (CLK_get_ms() > next_print) 328 if (timer_read64() > next_print)
329 { 329 {
330 next_print = CLK_get_ms() + 250; 330 next_print = timer_read64() + 250;
331 //Add any debug information here that you want to see very often 331 //Add any debug information here that you want to see very often
332 //dprintf("5v=%u 5vu=%u dlow=%u dhi=%u gca=%u gcd=%u\r\n", v_5v, v_5v_avg, v_5v_avg - V5_LOW, v_5v_avg - V5_HIGH, gcr_actual, gcr_desired); 332 //dprintf("5v=%u 5vu=%u dlow=%u dhi=%u gca=%u gcd=%u\r\n", v_5v, v_5v_avg, v_5v_avg - V5_LOW, v_5v_avg - V5_HIGH, gcr_actual, gcr_desired);
333 } 333 }
diff --git a/tmk_core/protocol/arm_atsam/usb/compiler.h b/tmk_core/protocol/arm_atsam/usb/compiler.h
index 7d8350896..b2ccfd73e 100644
--- a/tmk_core/protocol/arm_atsam/usb/compiler.h
+++ b/tmk_core/protocol/arm_atsam/usb/compiler.h
@@ -134,13 +134,15 @@
134 * heuristics and inline the function no matter how big it thinks it 134 * heuristics and inline the function no matter how big it thinks it
135 * becomes. 135 * becomes.
136 */ 136 */
137#if !defined(__always_inline)
137#if defined(__CC_ARM) 138#if defined(__CC_ARM)
138# define __always_inline __forceinline 139# define __always_inline __forceinline
139#elif (defined __GNUC__ && __GNUC__ <= 6) 140#elif (defined __GNUC__)
140# define __always_inline __attribute__((__always_inline__)) 141# define __always_inline __attribute__((__always_inline__))
141#elif (defined __ICCARM__) 142#elif (defined __ICCARM__)
142# define __always_inline _Pragma("inline=forced") 143# define __always_inline _Pragma("inline=forced")
143#endif 144#endif
145#endif
144 146
145/** 147/**
146 * \def __no_inline 148 * \def __no_inline
diff --git a/tmk_core/protocol/arm_atsam/usb/udi_cdc.c b/tmk_core/protocol/arm_atsam/usb/udi_cdc.c
index 5f3c289e8..ffe3526db 100644
--- a/tmk_core/protocol/arm_atsam/usb/udi_cdc.c
+++ b/tmk_core/protocol/arm_atsam/usb/udi_cdc.c
@@ -1227,9 +1227,9 @@ uint32_t cdc_tx_send_time_next;
1227 1227
1228void CDC_send(void) 1228void CDC_send(void)
1229{ 1229{
1230 while (CLK_get_ms() < cdc_tx_send_time_next); 1230 while (timer_read64() < cdc_tx_send_time_next);
1231 udi_cdc_tx_send(0); 1231 udi_cdc_tx_send(0);
1232 cdc_tx_send_time_next = CLK_get_ms() + CDC_SEND_INTERVAL; 1232 cdc_tx_send_time_next = timer_read64() + CDC_SEND_INTERVAL;
1233} 1233}
1234 1234
1235uint32_t CDC_print(char *printbuf) 1235uint32_t CDC_print(char *printbuf)
@@ -1238,7 +1238,7 @@ uint32_t CDC_print(char *printbuf)
1238 char *buf = printbuf; 1238 char *buf = printbuf;
1239 char c; 1239 char c;
1240 1240
1241 if (CLK_get_ms() < 5000) return 0; 1241 if (timer_read64() < 5000) return 0;
1242 1242
1243 while ((c = *buf++) != 0 && !(count >= MAX_PRINT)) 1243 while ((c = *buf++) != 0 && !(count >= MAX_PRINT))
1244 { 1244 {
@@ -1339,7 +1339,7 @@ void CDC_init(void)
1339 inbuf.count = 0; 1339 inbuf.count = 0;
1340 inbuf.lastcount = 0; 1340 inbuf.lastcount = 0;
1341 printbuf[0] = 0; 1341 printbuf[0] = 0;
1342 cdc_tx_send_time_next = CLK_get_ms() + CDC_SEND_INTERVAL; 1342 cdc_tx_send_time_next = timer_read64() + CDC_SEND_INTERVAL;
1343} 1343}
1344 1344
1345#else //CDC line 62 1345#else //CDC line 62
diff --git a/tmk_core/protocol/arm_atsam/usb/usb2422.c b/tmk_core/protocol/arm_atsam/usb/usb2422.c
index ac19bf4ea..d6e192242 100644
--- a/tmk_core/protocol/arm_atsam/usb/usb2422.c
+++ b/tmk_core/protocol/arm_atsam/usb/usb2422.c
@@ -64,7 +64,7 @@ void USB_write2422_block(void)
64 i2c0_transmit(USB2422_ADDR, dest, 34, 50000); 64 i2c0_transmit(USB2422_ADDR, dest, 34, 50000);
65 SERCOM0->I2CM.CTRLB.bit.CMD = 0x03; 65 SERCOM0->I2CM.CTRLB.bit.CMD = 0x03;
66 while (SERCOM0->I2CM.SYNCBUSY.bit.SYSOP) { DBGC(DC_USB_WRITE2422_BLOCK_SYNC_SYSOP); } 66 while (SERCOM0->I2CM.SYNCBUSY.bit.SYSOP) { DBGC(DC_USB_WRITE2422_BLOCK_SYNC_SYSOP); }
67 CLK_delay_us(100); 67 wait_us(100);
68 } 68 }
69 69
70 DBGC(DC_USB_WRITE2422_BLOCK_COMPLETE); 70 DBGC(DC_USB_WRITE2422_BLOCK_COMPLETE);
@@ -135,7 +135,7 @@ void USB2422_init(void)
135 sr_exp_data.bit.HUB_RESET_N = 1; //reset high 135 sr_exp_data.bit.HUB_RESET_N = 1; //reset high
136 SR_EXP_WriteData(); 136 SR_EXP_WriteData();
137 137
138 CLK_delay_us(100); 138 wait_us(100);
139 139
140#ifndef MD_BOOTLOADER 140#ifndef MD_BOOTLOADER
141 141
@@ -154,10 +154,9 @@ void USB_reset(void)
154 //pulse reset for at least 1 usec 154 //pulse reset for at least 1 usec
155 sr_exp_data.bit.HUB_RESET_N = 0; //reset low 155 sr_exp_data.bit.HUB_RESET_N = 0; //reset low
156 SR_EXP_WriteData(); 156 SR_EXP_WriteData();
157 CLK_delay_us(1); 157 wait_us(2);
158 sr_exp_data.bit.HUB_RESET_N = 1; //reset high to run 158 sr_exp_data.bit.HUB_RESET_N = 1; //reset high to run
159 SR_EXP_WriteData(); 159 SR_EXP_WriteData();
160 CLK_delay_us(1);
161 160
162 DBGC(DC_USB_RESET_COMPLETE); 161 DBGC(DC_USB_RESET_COMPLETE);
163} 162}
@@ -247,7 +246,7 @@ void USB_set_host_by_voltage(void)
247 246
248 SR_EXP_WriteData(); 247 SR_EXP_WriteData();
249 248
250 CLK_delay_ms(250); 249 wait_ms(250);
251 250
252 while ((v_5v = adc_get(ADC_5V)) < ADC_5V_START_LEVEL) { DBGC(DC_USB_SET_HOST_5V_LOW_WAITING); } 251 while ((v_5v = adc_get(ADC_5V)) < ADC_5V_START_LEVEL) { DBGC(DC_USB_SET_HOST_5V_LOW_WAITING); }
253 252
@@ -313,11 +312,11 @@ uint8_t USB2422_Port_Detect_Init(void)
313 312
314 USB_set_host_by_voltage(); 313 USB_set_host_by_voltage();
315 314
316 port_detect_retry_ms = CLK_get_ms() + PORT_DETECT_RETRY_INTERVAL; 315 port_detect_retry_ms = timer_read64() + PORT_DETECT_RETRY_INTERVAL;
317 316
318 while (!USB_active()) 317 while (!USB_active())
319 { 318 {
320 tmod = CLK_get_ms() % PORT_DETECT_RETRY_INTERVAL; 319 tmod = timer_read64() % PORT_DETECT_RETRY_INTERVAL;
321 320
322 if (v_con_1 > v_con_2) //Values updated from USB_set_host_by_voltage(); 321 if (v_con_1 > v_con_2) //Values updated from USB_set_host_by_voltage();
323 { 322 {
@@ -333,7 +332,7 @@ uint8_t USB2422_Port_Detect_Init(void)
333 else { DBG_LED_OFF; } 332 else { DBG_LED_OFF; }
334 } 333 }
335 334
336 if (CLK_get_ms() > port_detect_retry_ms) 335 if (timer_read64() > port_detect_retry_ms)
337 { 336 {
338 DBGC(DC_PORT_DETECT_INIT_FAILED); 337 DBGC(DC_PORT_DETECT_INIT_FAILED);
339 return 0; 338 return 0;
diff --git a/tmk_core/protocol/chibios/main.c b/tmk_core/protocol/chibios/main.c
index ee9571c95..5436d4909 100644
--- a/tmk_core/protocol/chibios/main.c
+++ b/tmk_core/protocol/chibios/main.c
@@ -113,7 +113,7 @@ int main(void) {
113 chSysInit(); 113 chSysInit();
114 114
115#ifdef STM32_EEPROM_ENABLE 115#ifdef STM32_EEPROM_ENABLE
116 EEPROM_init(); 116 EEPROM_Init();
117#endif 117#endif
118 118
119 // TESTING 119 // TESTING
diff --git a/tmk_core/protocol/lufa/lufa.c b/tmk_core/protocol/lufa/lufa.c
index 27cf51b16..f2ecf2465 100644
--- a/tmk_core/protocol/lufa/lufa.c
+++ b/tmk_core/protocol/lufa/lufa.c
@@ -517,17 +517,16 @@ void EVENT_USB_Device_ControlRequest(void)
517 if (USB_DeviceState == DEVICE_STATE_Unattached) 517 if (USB_DeviceState == DEVICE_STATE_Unattached)
518 return; 518 return;
519 } 519 }
520#ifdef KEYBOARD_SHARED_EP 520
521 uint8_t report_id = REPORT_ID_KEYBOARD; 521 if (Endpoint_BytesInEndpoint() == 2) {
522 if (keyboard_protocol) { 522 uint8_t report_id = Endpoint_Read_8();
523 report_id = Endpoint_Read_8(); 523
524 } 524 if (report_id == REPORT_ID_KEYBOARD || report_id == REPORT_ID_NKRO) {
525 if (report_id == REPORT_ID_KEYBOARD || report_id == REPORT_ID_NKRO) {
526 keyboard_led_stats = Endpoint_Read_8(); 525 keyboard_led_stats = Endpoint_Read_8();
526 }
527 } else {
528 keyboard_led_stats = Endpoint_Read_8();
527 } 529 }
528#else
529 keyboard_led_stats = Endpoint_Read_8();
530#endif
531 530
532 Endpoint_ClearOUT(); 531 Endpoint_ClearOUT();
533 Endpoint_ClearStatusStage(); 532 Endpoint_ClearStatusStage();