Merge pull request #1072 from nicinabox/improve-ls-avrdude-target
[jackhill/qmk/firmware.git] / quantum / quantum.c
CommitLineData
1a8c0dd2 1#include "quantum.h"
e7c4f621 2#ifdef PROTOCOL_LUFA
c17070ec 3#include "outputselect.h"
2bef8b5b 4#endif
1a8c0dd2 5
74a1f007
GN
6#ifndef TAPPING_TERM
7#define TAPPING_TERM 200
8#endif
9
0d28787c
GN
10static void do_code16 (uint16_t code, void (*f) (uint8_t)) {
11 switch (code) {
12 case QK_MODS ... QK_MODS_MAX:
13 break;
14 default:
15 return;
16 }
17
18 if (code & QK_LCTL)
19 f(KC_LCTL);
20 if (code & QK_LSFT)
21 f(KC_LSFT);
22 if (code & QK_LALT)
23 f(KC_LALT);
24 if (code & QK_LGUI)
25 f(KC_LGUI);
26
01038ab5
OP
27 if (code < QK_RMODS_MIN) return;
28
0d28787c
GN
29 if (code & QK_RCTL)
30 f(KC_RCTL);
31 if (code & QK_RSFT)
32 f(KC_RSFT);
33 if (code & QK_RALT)
34 f(KC_RALT);
35 if (code & QK_RGUI)
36 f(KC_RGUI);
37}
38
f644b9a0
S
39static inline void qk_register_weak_mods(uint8_t kc) {
40 add_weak_mods(MOD_BIT(kc));
41 send_keyboard_report();
42}
43
44static inline void qk_unregister_weak_mods(uint8_t kc) {
45 del_weak_mods(MOD_BIT(kc));
46 send_keyboard_report();
47}
48
2b385993 49static inline void qk_register_mods(uint8_t kc) {
f644b9a0
S
50 add_weak_mods(MOD_BIT(kc));
51 send_keyboard_report();
2b385993
S
52}
53
54static inline void qk_unregister_mods(uint8_t kc) {
f644b9a0
S
55 del_weak_mods(MOD_BIT(kc));
56 send_keyboard_report();
2b385993
S
57}
58
0d28787c 59void register_code16 (uint16_t code) {
f644b9a0
S
60 if (IS_MOD(code) || code == KC_NO) {
61 do_code16 (code, qk_register_mods);
62 } else {
63 do_code16 (code, qk_register_weak_mods);
64 }
0d28787c
GN
65 register_code (code);
66}
67
68void unregister_code16 (uint16_t code) {
69 unregister_code (code);
f644b9a0
S
70 if (IS_MOD(code) || code == KC_NO) {
71 do_code16 (code, qk_unregister_mods);
72 } else {
73 do_code16 (code, qk_unregister_weak_mods);
74 }
0d28787c
GN
75}
76
1a8c0dd2 77__attribute__ ((weak))
1a8c0dd2
EZ
78bool process_action_kb(keyrecord_t *record) {
79 return true;
80}
81
17977a7e
JH
82__attribute__ ((weak))
83bool process_record_kb(uint16_t keycode, keyrecord_t *record) {
84 return process_record_user(keycode, record);
85}
86
87__attribute__ ((weak))
88bool process_record_user(uint16_t keycode, keyrecord_t *record) {
89 return true;
90}
91
a28a6e5b
PV
92void reset_keyboard(void) {
93 clear_keyboard();
94#ifdef AUDIO_ENABLE
95 stop_all_notes();
96 shutdown_user();
97#endif
98 wait_ms(250);
99#ifdef CATERINA_BOOTLOADER
100 *(uint16_t *)0x0800 = 0x7777; // these two are a-star-specific
101#endif
102 bootloader_jump();
103}
104
b70248fa
JH
105// Shift / paren setup
106
107#ifndef LSPO_KEY
108 #define LSPO_KEY KC_9
109#endif
110#ifndef RSPC_KEY
111 #define RSPC_KEY KC_0
112#endif
113
8bc69afc 114static bool shift_interrupted[2] = {0, 0};
ffa5b1e7 115static uint16_t scs_timer = 0;
12370259 116
bf5c2cce 117bool process_record_quantum(keyrecord_t *record) {
1a8c0dd2
EZ
118
119 /* This gets the keycode from the key pressed */
120 keypos_t key = record->event.key;
121 uint16_t keycode;
122
123 #if !defined(NO_ACTION_LAYER) && defined(PREVENT_STUCK_MODIFIERS)
644c8c79
WS
124 /* TODO: Use store_or_get_action() or a similar function. */
125 if (!disable_action_cache) {
126 uint8_t layer;
1a8c0dd2 127
644c8c79
WS
128 if (record->event.pressed) {
129 layer = layer_switch_get_layer(key);
130 update_source_layers_cache(key, layer);
131 } else {
132 layer = read_source_layers_cache(key);
133 }
134 keycode = keymap_key_to_keycode(layer, key);
135 } else
1a8c0dd2 136 #endif
644c8c79 137 keycode = keymap_key_to_keycode(layer_switch_get_layer(key), key);
1a8c0dd2 138
bf5c2cce
JH
139 // This is how you use actions here
140 // if (keycode == KC_LEAD) {
141 // action_t action;
142 // action.code = ACTION_DEFAULT_LAYER_SET(0);
143 // process_action(record, action);
144 // return false;
145 // }
146
65faab3b
JH
147 if (!(
148 process_record_kb(keycode, record) &&
fde477a9 149 #ifdef MIDI_ENABLE
65faab3b 150 process_midi(keycode, record) &&
fde477a9 151 #endif
1a8c0dd2 152 #ifdef AUDIO_ENABLE
65faab3b 153 process_music(keycode, record) &&
1a8c0dd2 154 #endif
65faab3b
JH
155 #ifdef TAP_DANCE_ENABLE
156 process_tap_dance(keycode, record) &&
157 #endif
158 #ifndef DISABLE_LEADER
159 process_leader(keycode, record) &&
160 #endif
161 #ifndef DISABLE_CHORDING
162 process_chording(keycode, record) &&
163 #endif
40abf8bc
OP
164 #ifdef COMBO_ENABLE
165 process_combo(keycode, record) &&
166 #endif
65faab3b
JH
167 #ifdef UNICODE_ENABLE
168 process_unicode(keycode, record) &&
857aa5be
GN
169 #endif
170 #ifdef UCIS_ENABLE
171 process_ucis(keycode, record) &&
5f91fb41
JH
172 #endif
173 #ifdef PRINTING_ENABLE
174 process_printer(keycode, record) &&
e9f74875 175 #endif
5b2e455d
PIN
176 #ifdef UNICODEMAP_ENABLE
177 process_unicode_map(keycode, record) &&
65faab3b
JH
178 #endif
179 true)) {
180 return false;
b732b79b
JH
181 }
182
b70248fa
JH
183 // Shift / paren setup
184
12370259 185 switch(keycode) {
db32864c
JH
186 case RESET:
187 if (record->event.pressed) {
a28a6e5b 188 reset_keyboard();
db32864c 189 }
f7a86822 190 return false;
db32864c
JH
191 break;
192 case DEBUG:
193 if (record->event.pressed) {
194 print("\nDEBUG: enabled.\n");
195 debug_enable = true;
db32864c 196 }
f7a86822 197 return false;
db32864c 198 break;
50c68658
T
199 #ifdef RGBLIGHT_ENABLE
200 case RGB_TOG:
201 if (record->event.pressed) {
202 rgblight_toggle();
f7a86822
T
203 }
204 return false;
205 break;
50c68658
T
206 case RGB_MOD:
207 if (record->event.pressed) {
208 rgblight_step();
f7a86822
T
209 }
210 return false;
211 break;
50c68658
T
212 case RGB_HUI:
213 if (record->event.pressed) {
214 rgblight_increase_hue();
f7a86822
T
215 }
216 return false;
217 break;
50c68658
T
218 case RGB_HUD:
219 if (record->event.pressed) {
220 rgblight_decrease_hue();
f7a86822
T
221 }
222 return false;
223 break;
50c68658
T
224 case RGB_SAI:
225 if (record->event.pressed) {
226 rgblight_increase_sat();
f7a86822
T
227 }
228 return false;
229 break;
50c68658
T
230 case RGB_SAD:
231 if (record->event.pressed) {
232 rgblight_decrease_sat();
f7a86822
T
233 }
234 return false;
235 break;
50c68658
T
236 case RGB_VAI:
237 if (record->event.pressed) {
238 rgblight_increase_val();
f7a86822
T
239 }
240 return false;
241 break;
50c68658
T
242 case RGB_VAD:
243 if (record->event.pressed) {
244 rgblight_decrease_val();
f7a86822
T
245 }
246 return false;
247 break;
50c68658 248 #endif
e7c4f621 249 #ifdef PROTOCOL_LUFA
c17070ec
PIN
250 case OUT_AUTO:
251 if (record->event.pressed) {
252 set_output(OUTPUT_AUTO);
253 }
254 return false;
255 break;
256 case OUT_USB:
257 if (record->event.pressed) {
258 set_output(OUTPUT_USB);
259 }
260 return false;
261 break;
262 #ifdef BLUETOOTH_ENABLE
263 case OUT_BT:
264 if (record->event.pressed) {
265 set_output(OUTPUT_BLUETOOTH);
266 }
267 return false;
268 break;
269 #endif
270 #ifdef ADAFRUIT_BLE_ENABLE
271 case OUT_BLE:
272 if (record->event.pressed) {
273 set_output(OUTPUT_ADAFRUIT_BLE);
274 }
275 return false;
276 break;
277 #endif
2bef8b5b 278 #endif
558f3ec1 279 case MAGIC_SWAP_CONTROL_CAPSLOCK ... MAGIC_TOGGLE_NKRO:
db32864c
JH
280 if (record->event.pressed) {
281 // MAGIC actions (BOOTMAGIC without the boot)
282 if (!eeconfig_is_enabled()) {
283 eeconfig_init();
284 }
285 /* keymap config */
286 keymap_config.raw = eeconfig_read_keymap();
558f3ec1
I
287 switch (keycode)
288 {
289 case MAGIC_SWAP_CONTROL_CAPSLOCK:
290 keymap_config.swap_control_capslock = true;
291 break;
292 case MAGIC_CAPSLOCK_TO_CONTROL:
293 keymap_config.capslock_to_control = true;
294 break;
295 case MAGIC_SWAP_LALT_LGUI:
296 keymap_config.swap_lalt_lgui = true;
297 break;
298 case MAGIC_SWAP_RALT_RGUI:
299 keymap_config.swap_ralt_rgui = true;
300 break;
301 case MAGIC_NO_GUI:
302 keymap_config.no_gui = true;
303 break;
304 case MAGIC_SWAP_GRAVE_ESC:
305 keymap_config.swap_grave_esc = true;
306 break;
307 case MAGIC_SWAP_BACKSLASH_BACKSPACE:
308 keymap_config.swap_backslash_backspace = true;
309 break;
310 case MAGIC_HOST_NKRO:
311 keymap_config.nkro = true;
312 break;
313 case MAGIC_SWAP_ALT_GUI:
314 keymap_config.swap_lalt_lgui = true;
315 keymap_config.swap_ralt_rgui = true;
316 break;
317 case MAGIC_UNSWAP_CONTROL_CAPSLOCK:
318 keymap_config.swap_control_capslock = false;
319 break;
320 case MAGIC_UNCAPSLOCK_TO_CONTROL:
321 keymap_config.capslock_to_control = false;
322 break;
323 case MAGIC_UNSWAP_LALT_LGUI:
324 keymap_config.swap_lalt_lgui = false;
325 break;
326 case MAGIC_UNSWAP_RALT_RGUI:
327 keymap_config.swap_ralt_rgui = false;
328 break;
329 case MAGIC_UNNO_GUI:
330 keymap_config.no_gui = false;
331 break;
332 case MAGIC_UNSWAP_GRAVE_ESC:
333 keymap_config.swap_grave_esc = false;
334 break;
335 case MAGIC_UNSWAP_BACKSLASH_BACKSPACE:
336 keymap_config.swap_backslash_backspace = false;
337 break;
338 case MAGIC_UNHOST_NKRO:
339 keymap_config.nkro = false;
340 break;
341 case MAGIC_UNSWAP_ALT_GUI:
342 keymap_config.swap_lalt_lgui = false;
343 keymap_config.swap_ralt_rgui = false;
344 break;
345 case MAGIC_TOGGLE_NKRO:
346 keymap_config.nkro = !keymap_config.nkro;
347 break;
348 default:
349 break;
db32864c
JH
350 }
351 eeconfig_update_keymap(keymap_config.raw);
558f3ec1
I
352 clear_keyboard(); // clear to prevent stuck keys
353
db32864c
JH
354 return false;
355 }
356 break;
12370259 357 case KC_LSPO: {
db32864c
JH
358 if (record->event.pressed) {
359 shift_interrupted[0] = false;
ffa5b1e7 360 scs_timer = timer_read ();
76076db7 361 register_mods(MOD_BIT(KC_LSFT));
db32864c
JH
362 }
363 else {
b12fe6ab
S
364 #ifdef DISABLE_SPACE_CADET_ROLLOVER
365 if (get_mods() & MOD_BIT(KC_RSFT)) {
366 shift_interrupted[0] = true;
367 shift_interrupted[1] = true;
368 }
369 #endif
ffa5b1e7 370 if (!shift_interrupted[0] && timer_elapsed(scs_timer) < TAPPING_TERM) {
db32864c
JH
371 register_code(LSPO_KEY);
372 unregister_code(LSPO_KEY);
373 }
76076db7 374 unregister_mods(MOD_BIT(KC_LSFT));
db32864c
JH
375 }
376 return false;
558f3ec1 377 // break;
db32864c 378 }
12370259
EZ
379
380 case KC_RSPC: {
db32864c
JH
381 if (record->event.pressed) {
382 shift_interrupted[1] = false;
ffa5b1e7 383 scs_timer = timer_read ();
76076db7 384 register_mods(MOD_BIT(KC_RSFT));
db32864c
JH
385 }
386 else {
b12fe6ab
S
387 #ifdef DISABLE_SPACE_CADET_ROLLOVER
388 if (get_mods() & MOD_BIT(KC_LSFT)) {
389 shift_interrupted[0] = true;
390 shift_interrupted[1] = true;
391 }
392 #endif
ffa5b1e7 393 if (!shift_interrupted[1] && timer_elapsed(scs_timer) < TAPPING_TERM) {
db32864c
JH
394 register_code(RSPC_KEY);
395 unregister_code(RSPC_KEY);
396 }
76076db7 397 unregister_mods(MOD_BIT(KC_RSFT));
db32864c
JH
398 }
399 return false;
558f3ec1 400 // break;
db32864c 401 }
12370259 402 default: {
db32864c
JH
403 shift_interrupted[0] = true;
404 shift_interrupted[1] = true;
405 break;
406 }
12370259
EZ
407 }
408
1a8c0dd2
EZ
409 return process_action_kb(record);
410}
411
794aed37
ET
412const bool ascii_to_qwerty_shift_lut[0x80] PROGMEM = {
413 0, 0, 0, 0, 0, 0, 0, 0,
414 0, 0, 0, 0, 0, 0, 0, 0,
415 0, 0, 0, 0, 0, 0, 0, 0,
416 0, 0, 0, 0, 0, 0, 0, 0,
417 0, 1, 1, 1, 1, 1, 1, 0,
418 1, 1, 1, 1, 0, 0, 0, 0,
419 0, 0, 0, 0, 0, 0, 0, 0,
420 0, 0, 1, 0, 1, 0, 1, 1,
421 1, 1, 1, 1, 1, 1, 1, 1,
422 1, 1, 1, 1, 1, 1, 1, 1,
423 1, 1, 1, 1, 1, 1, 1, 1,
424 1, 1, 1, 0, 0, 0, 1, 1,
425 0, 0, 0, 0, 0, 0, 0, 0,
426 0, 0, 0, 0, 0, 0, 0, 0,
427 0, 0, 0, 0, 0, 0, 0, 0,
428 0, 0, 0, 1, 1, 1, 1, 0
1c9f33c0
JH
429};
430
794aed37
ET
431const uint8_t ascii_to_qwerty_keycode_lut[0x80] PROGMEM = {
432 0, 0, 0, 0, 0, 0, 0, 0,
433 KC_BSPC, KC_TAB, KC_ENT, 0, 0, 0, 0, 0,
434 0, 0, 0, 0, 0, 0, 0, 0,
435 0, 0, 0, KC_ESC, 0, 0, 0, 0,
436 KC_SPC, KC_1, KC_QUOT, KC_3, KC_4, KC_5, KC_7, KC_QUOT,
437 KC_9, KC_0, KC_8, KC_EQL, KC_COMM, KC_MINS, KC_DOT, KC_SLSH,
438 KC_0, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7,
439 KC_8, KC_9, KC_SCLN, KC_SCLN, KC_COMM, KC_EQL, KC_DOT, KC_SLSH,
440 KC_2, KC_A, KC_B, KC_C, KC_D, KC_E, KC_F, KC_G,
441 KC_H, KC_I, KC_J, KC_K, KC_L, KC_M, KC_N, KC_O,
442 KC_P, KC_Q, KC_R, KC_S, KC_T, KC_U, KC_V, KC_W,
443 KC_X, KC_Y, KC_Z, KC_LBRC, KC_BSLS, KC_RBRC, KC_6, KC_MINS,
444 KC_GRV, KC_A, KC_B, KC_C, KC_D, KC_E, KC_F, KC_G,
445 KC_H, KC_I, KC_J, KC_K, KC_L, KC_M, KC_N, KC_O,
446 KC_P, KC_Q, KC_R, KC_S, KC_T, KC_U, KC_V, KC_W,
447 KC_X, KC_Y, KC_Z, KC_LBRC, KC_BSLS, KC_RBRC, KC_GRV, KC_DEL
1c9f33c0
JH
448};
449
794aed37
ET
450/* for users whose OSes are set to Colemak */
451#if 0
452#include "keymap_colemak.h"
453
454const bool ascii_to_colemak_shift_lut[0x80] PROGMEM = {
455 0, 0, 0, 0, 0, 0, 0, 0,
456 0, 0, 0, 0, 0, 0, 0, 0,
457 0, 0, 0, 0, 0, 0, 0, 0,
458 0, 0, 0, 0, 0, 0, 0, 0,
459 0, 1, 1, 1, 1, 1, 1, 0,
460 1, 1, 1, 1, 0, 0, 0, 0,
461 0, 0, 0, 0, 0, 0, 0, 0,
462 0, 0, 1, 0, 1, 0, 1, 1,
463 1, 1, 1, 1, 1, 1, 1, 1,
464 1, 1, 1, 1, 1, 1, 1, 1,
465 1, 1, 1, 1, 1, 1, 1, 1,
466 1, 1, 1, 0, 0, 0, 1, 1,
467 0, 0, 0, 0, 0, 0, 0, 0,
468 0, 0, 0, 0, 0, 0, 0, 0,
469 0, 0, 0, 0, 0, 0, 0, 0,
470 0, 0, 0, 1, 1, 1, 1, 0
471};
472
473const uint8_t ascii_to_colemak_keycode_lut[0x80] PROGMEM = {
474 0, 0, 0, 0, 0, 0, 0, 0,
475 KC_BSPC, KC_TAB, KC_ENT, 0, 0, 0, 0, 0,
476 0, 0, 0, 0, 0, 0, 0, 0,
477 0, 0, 0, KC_ESC, 0, 0, 0, 0,
478 KC_SPC, KC_1, KC_QUOT, KC_3, KC_4, KC_5, KC_7, KC_QUOT,
479 KC_9, KC_0, KC_8, KC_EQL, KC_COMM, KC_MINS, KC_DOT, KC_SLSH,
480 KC_0, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7,
481 KC_8, KC_9, CM_SCLN, CM_SCLN, KC_COMM, KC_EQL, KC_DOT, KC_SLSH,
482 KC_2, CM_A, CM_B, CM_C, CM_D, CM_E, CM_F, CM_G,
483 CM_H, CM_I, CM_J, CM_K, CM_L, CM_M, CM_N, CM_O,
484 CM_P, CM_Q, CM_R, CM_S, CM_T, CM_U, CM_V, CM_W,
485 CM_X, CM_Y, CM_Z, KC_LBRC, KC_BSLS, KC_RBRC, KC_6, KC_MINS,
486 KC_GRV, CM_A, CM_B, CM_C, CM_D, CM_E, CM_F, CM_G,
487 CM_H, CM_I, CM_J, CM_K, CM_L, CM_M, CM_N, CM_O,
488 CM_P, CM_Q, CM_R, CM_S, CM_T, CM_U, CM_V, CM_W,
489 CM_X, CM_Y, CM_Z, KC_LBRC, KC_BSLS, KC_RBRC, KC_GRV, KC_DEL
490};
491
492#endif
493
494void send_string(const char *str) {
495 while (1) {
496 uint8_t keycode;
497 uint8_t ascii_code = pgm_read_byte(str);
498 if (!ascii_code) break;
499 keycode = pgm_read_byte(&ascii_to_qwerty_keycode_lut[ascii_code]);
500 if (pgm_read_byte(&ascii_to_qwerty_shift_lut[ascii_code])) {
501 register_code(KC_LSFT);
502 register_code(keycode);
503 unregister_code(keycode);
504 unregister_code(KC_LSFT);
505 }
506 else {
507 register_code(keycode);
508 unregister_code(keycode);
509 }
510 ++str;
1c9f33c0 511 }
1c9f33c0
JH
512}
513
db32864c
JH
514void update_tri_layer(uint8_t layer1, uint8_t layer2, uint8_t layer3) {
515 if (IS_LAYER_ON(layer1) && IS_LAYER_ON(layer2)) {
516 layer_on(layer3);
517 } else {
518 layer_off(layer3);
519 }
520}
1c9f33c0 521
197f152d 522void tap_random_base64(void) {
60fd885a
JH
523 #if defined(__AVR_ATmega32U4__)
524 uint8_t key = (TCNT0 + TCNT1 + TCNT3 + TCNT4) % 64;
525 #else
526 uint8_t key = rand() % 64;
527 #endif
197f152d
JH
528 switch (key) {
529 case 0 ... 25:
530 register_code(KC_LSFT);
531 register_code(key + KC_A);
532 unregister_code(key + KC_A);
533 unregister_code(KC_LSFT);
534 break;
535 case 26 ... 51:
536 register_code(key - 26 + KC_A);
537 unregister_code(key - 26 + KC_A);
538 break;
539 case 52:
540 register_code(KC_0);
541 unregister_code(KC_0);
542 break;
543 case 53 ... 61:
544 register_code(key - 53 + KC_1);
545 unregister_code(key - 53 + KC_1);
546 break;
547 case 62:
548 register_code(KC_LSFT);
549 register_code(KC_EQL);
550 unregister_code(KC_EQL);
551 unregister_code(KC_LSFT);
552 break;
553 case 63:
554 register_code(KC_SLSH);
555 unregister_code(KC_SLSH);
556 break;
557 }
558}
559
1a8c0dd2 560void matrix_init_quantum() {
13bb6b4b
JH
561 #ifdef BACKLIGHT_ENABLE
562 backlight_init_ports();
563 #endif
1a8c0dd2
EZ
564 matrix_init_kb();
565}
566
567void matrix_scan_quantum() {
15719f35 568 #ifdef AUDIO_ENABLE
65faab3b 569 matrix_scan_music();
15719f35 570 #endif
fde477a9 571
65faab3b
JH
572 #ifdef TAP_DANCE_ENABLE
573 matrix_scan_tap_dance();
574 #endif
b6bf4e0d
OP
575
576 #ifdef COMBO_ENABLE
577 matrix_scan_combo();
578 #endif
579
1a8c0dd2 580 matrix_scan_kb();
0428214b 581}
13bb6b4b 582
13bb6b4b
JH
583#if defined(BACKLIGHT_ENABLE) && defined(BACKLIGHT_PIN)
584
585static const uint8_t backlight_pin = BACKLIGHT_PIN;
586
587#if BACKLIGHT_PIN == B7
588# define COM1x1 COM1C1
589# define OCR1x OCR1C
590#elif BACKLIGHT_PIN == B6
591# define COM1x1 COM1B1
592# define OCR1x OCR1B
593#elif BACKLIGHT_PIN == B5
594# define COM1x1 COM1A1
595# define OCR1x OCR1A
596#else
597# error "Backlight pin not supported - use B5, B6, or B7"
598#endif
599
600__attribute__ ((weak))
601void backlight_init_ports(void)
602{
603
604 // Setup backlight pin as output and output low.
605 // DDRx |= n
606 _SFR_IO8((backlight_pin >> 4) + 1) |= _BV(backlight_pin & 0xF);
607 // PORTx &= ~n
608 _SFR_IO8((backlight_pin >> 4) + 2) &= ~_BV(backlight_pin & 0xF);
609
610 // Use full 16-bit resolution.
611 ICR1 = 0xFFFF;
612
613 // I could write a wall of text here to explain... but TL;DW
614 // Go read the ATmega32u4 datasheet.
615 // And this: http://blog.saikoled.com/post/43165849837/secret-konami-cheat-code-to-high-resolution-pwm-on
616
617 // Pin PB7 = OCR1C (Timer 1, Channel C)
618 // Compare Output Mode = Clear on compare match, Channel C = COM1C1=1 COM1C0=0
619 // (i.e. start high, go low when counter matches.)
620 // WGM Mode 14 (Fast PWM) = WGM13=1 WGM12=1 WGM11=1 WGM10=0
621 // Clock Select = clk/1 (no prescaling) = CS12=0 CS11=0 CS10=1
622
623 TCCR1A = _BV(COM1x1) | _BV(WGM11); // = 0b00001010;
624 TCCR1B = _BV(WGM13) | _BV(WGM12) | _BV(CS10); // = 0b00011001;
625
626 backlight_init();
627 #ifdef BACKLIGHT_BREATHING
628 breathing_defaults();
629 #endif
630}
631
632__attribute__ ((weak))
633void backlight_set(uint8_t level)
634{
635 // Prevent backlight blink on lowest level
636 // PORTx &= ~n
637 _SFR_IO8((backlight_pin >> 4) + 2) &= ~_BV(backlight_pin & 0xF);
638
639 if ( level == 0 ) {
640 // Turn off PWM control on backlight pin, revert to output low.
641 TCCR1A &= ~(_BV(COM1x1));
642 OCR1x = 0x0;
643 } else if ( level == BACKLIGHT_LEVELS ) {
644 // Turn on PWM control of backlight pin
645 TCCR1A |= _BV(COM1x1);
646 // Set the brightness
647 OCR1x = 0xFFFF;
648 } else {
649 // Turn on PWM control of backlight pin
650 TCCR1A |= _BV(COM1x1);
651 // Set the brightness
652 OCR1x = 0xFFFF >> ((BACKLIGHT_LEVELS - level) * ((BACKLIGHT_LEVELS + 1) / 2));
653 }
654
655 #ifdef BACKLIGHT_BREATHING
656 breathing_intensity_default();
657 #endif
658}
659
660
661#ifdef BACKLIGHT_BREATHING
662
663#define BREATHING_NO_HALT 0
664#define BREATHING_HALT_OFF 1
665#define BREATHING_HALT_ON 2
666
667static uint8_t breath_intensity;
668static uint8_t breath_speed;
669static uint16_t breathing_index;
670static uint8_t breathing_halt;
671
672void breathing_enable(void)
673{
674 if (get_backlight_level() == 0)
675 {
676 breathing_index = 0;
677 }
678 else
679 {
680 // Set breathing_index to be at the midpoint (brightest point)
681 breathing_index = 0x20 << breath_speed;
682 }
683
684 breathing_halt = BREATHING_NO_HALT;
685
686 // Enable breathing interrupt
687 TIMSK1 |= _BV(OCIE1A);
688}
689
690void breathing_pulse(void)
691{
692 if (get_backlight_level() == 0)
693 {
694 breathing_index = 0;
695 }
696 else
697 {
698 // Set breathing_index to be at the midpoint + 1 (brightest point)
699 breathing_index = 0x21 << breath_speed;
700 }
701
702 breathing_halt = BREATHING_HALT_ON;
703
704 // Enable breathing interrupt
705 TIMSK1 |= _BV(OCIE1A);
706}
707
708void breathing_disable(void)
709{
710 // Disable breathing interrupt
711 TIMSK1 &= ~_BV(OCIE1A);
712 backlight_set(get_backlight_level());
713}
714
715void breathing_self_disable(void)
716{
717 if (get_backlight_level() == 0)
718 {
719 breathing_halt = BREATHING_HALT_OFF;
720 }
721 else
722 {
723 breathing_halt = BREATHING_HALT_ON;
724 }
725
726 //backlight_set(get_backlight_level());
727}
728
729void breathing_toggle(void)
730{
731 if (!is_breathing())
732 {
733 if (get_backlight_level() == 0)
734 {
735 breathing_index = 0;
736 }
737 else
738 {
739 // Set breathing_index to be at the midpoint + 1 (brightest point)
740 breathing_index = 0x21 << breath_speed;
741 }
742
743 breathing_halt = BREATHING_NO_HALT;
744 }
745
746 // Toggle breathing interrupt
747 TIMSK1 ^= _BV(OCIE1A);
748
749 // Restore backlight level
750 if (!is_breathing())
751 {
752 backlight_set(get_backlight_level());
753 }
754}
755
756bool is_breathing(void)
757{
758 return (TIMSK1 && _BV(OCIE1A));
759}
760
761void breathing_intensity_default(void)
762{
763 //breath_intensity = (uint8_t)((uint16_t)100 * (uint16_t)get_backlight_level() / (uint16_t)BACKLIGHT_LEVELS);
764 breath_intensity = ((BACKLIGHT_LEVELS - get_backlight_level()) * ((BACKLIGHT_LEVELS + 1) / 2));
765}
766
767void breathing_intensity_set(uint8_t value)
768{
769 breath_intensity = value;
770}
771
772void breathing_speed_default(void)
773{
774 breath_speed = 4;
775}
776
777void breathing_speed_set(uint8_t value)
778{
779 bool is_breathing_now = is_breathing();
780 uint8_t old_breath_speed = breath_speed;
781
782 if (is_breathing_now)
783 {
784 // Disable breathing interrupt
785 TIMSK1 &= ~_BV(OCIE1A);
786 }
787
788 breath_speed = value;
789
790 if (is_breathing_now)
791 {
792 // Adjust index to account for new speed
793 breathing_index = (( (uint8_t)( (breathing_index) >> old_breath_speed ) ) & 0x3F) << breath_speed;
794
795 // Enable breathing interrupt
796 TIMSK1 |= _BV(OCIE1A);
797 }
798
799}
800
801void breathing_speed_inc(uint8_t value)
802{
803 if ((uint16_t)(breath_speed - value) > 10 )
804 {
805 breathing_speed_set(0);
806 }
807 else
808 {
809 breathing_speed_set(breath_speed - value);
810 }
811}
812
813void breathing_speed_dec(uint8_t value)
814{
815 if ((uint16_t)(breath_speed + value) > 10 )
816 {
817 breathing_speed_set(10);
818 }
819 else
820 {
821 breathing_speed_set(breath_speed + value);
822 }
823}
824
825void breathing_defaults(void)
826{
827 breathing_intensity_default();
828 breathing_speed_default();
829 breathing_halt = BREATHING_NO_HALT;
830}
831
832/* Breathing Sleep LED brighness(PWM On period) table
833 * (64[steps] * 4[duration]) / 64[PWM periods/s] = 4 second breath cycle
834 *
835 * http://www.wolframalpha.com/input/?i=%28sin%28+x%2F64*pi%29**8+*+255%2C+x%3D0+to+63
836 * (0..63).each {|x| p ((sin(x/64.0*PI)**8)*255).to_i }
837 */
838static const uint8_t breathing_table[64] PROGMEM = {
839 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 4, 6, 10,
840 15, 23, 32, 44, 58, 74, 93, 113, 135, 157, 179, 199, 218, 233, 245, 252,
841255, 252, 245, 233, 218, 199, 179, 157, 135, 113, 93, 74, 58, 44, 32, 23,
842 15, 10, 6, 4, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
843};
844
845ISR(TIMER1_COMPA_vect)
846{
847 // OCR1x = (pgm_read_byte(&breathing_table[ ( (uint8_t)( (breathing_index++) >> breath_speed ) ) & 0x3F ] )) * breath_intensity;
848
849
850 uint8_t local_index = ( (uint8_t)( (breathing_index++) >> breath_speed ) ) & 0x3F;
851
852 if (((breathing_halt == BREATHING_HALT_ON) && (local_index == 0x20)) || ((breathing_halt == BREATHING_HALT_OFF) && (local_index == 0x3F)))
853 {
854 // Disable breathing interrupt
855 TIMSK1 &= ~_BV(OCIE1A);
856 }
857
858 OCR1x = (uint16_t)(((uint16_t)pgm_read_byte(&breathing_table[local_index]) * 257)) >> breath_intensity;
859
860}
861
862
863
864#endif // breathing
865
866#else // backlight
867
868__attribute__ ((weak))
869void backlight_init_ports(void)
870{
871
872}
873
874__attribute__ ((weak))
875void backlight_set(uint8_t level)
876{
877
878}
879
880#endif // backlight
881
882
664c0a03
JH
883// Functions for spitting out values
884//
885
886void send_dword(uint32_t number) { // this might not actually work
887 uint16_t word = (number >> 16);
888 send_word(word);
889 send_word(number & 0xFFFFUL);
890}
891
892void send_word(uint16_t number) {
893 uint8_t byte = number >> 8;
894 send_byte(byte);
895 send_byte(number & 0xFF);
896}
897
898void send_byte(uint8_t number) {
899 uint8_t nibble = number >> 4;
900 send_nibble(nibble);
901 send_nibble(number & 0xF);
902}
903
904void send_nibble(uint8_t number) {
905 switch (number) {
906 case 0:
907 register_code(KC_0);
908 unregister_code(KC_0);
909 break;
910 case 1 ... 9:
911 register_code(KC_1 + (number - 1));
912 unregister_code(KC_1 + (number - 1));
913 break;
914 case 0xA ... 0xF:
915 register_code(KC_A + (number - 0xA));
916 unregister_code(KC_A + (number - 0xA));
917 break;
918 }
919}
920
7edac212
JH
921void api_send_unicode(uint32_t unicode) {
922#ifdef API_ENABLE
cefa8468
JH
923 uint8_t chunk[4];
924 dword_to_bytes(unicode, chunk);
925 MT_SEND_DATA(DT_UNICODE, chunk, 5);
7edac212 926#endif
cefa8468 927}
13bb6b4b
JH
928
929__attribute__ ((weak))
930void led_set_user(uint8_t usb_led) {
931
932}
933
934__attribute__ ((weak))
935void led_set_kb(uint8_t usb_led) {
936 led_set_user(usb_led);
937}
938
939__attribute__ ((weak))
940void led_init_ports(void)
941{
942
943}
944
945__attribute__ ((weak))
946void led_set(uint8_t usb_led)
947{
948
949 // Example LED Code
950 //
951 // // Using PE6 Caps Lock LED
952 // if (usb_led & (1<<USB_LED_CAPS_LOCK))
953 // {
954 // // Output high.
955 // DDRE |= (1<<6);
956 // PORTE |= (1<<6);
957 // }
958 // else
959 // {
960 // // Output low.
961 // DDRE &= ~(1<<6);
962 // PORTE &= ~(1<<6);
963 // }
964
965 led_set_kb(usb_led);
966}
967
968
287eb7ad 969//------------------------------------------------------------------------------
794aed37 970// Override these functions in your keymap file to play different tunes on
287eb7ad
JH
971// different events such as startup and bootloader jump
972
973__attribute__ ((weak))
974void startup_user() {}
975
976__attribute__ ((weak))
977void shutdown_user() {}
978
12370259 979//------------------------------------------------------------------------------