Store backlight breathing state in EEPROM (#6105)
[jackhill/qmk/firmware.git] / quantum / quantum.c
1 /* Copyright 2016-2017 Jack Humbert
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17 #include "quantum.h"
18
19 #if !defined(RGBLIGHT_ENABLE) && !defined(RGB_MATRIX_ENABLE)
20 #include "rgb.h"
21 #endif
22
23 #ifdef PROTOCOL_LUFA
24 #include "outputselect.h"
25 #endif
26
27 #ifndef BREATHING_PERIOD
28 #define BREATHING_PERIOD 6
29 #endif
30
31 #include "backlight.h"
32 extern backlight_config_t backlight_config;
33
34 #ifdef FAUXCLICKY_ENABLE
35 #include "fauxclicky.h"
36 #endif
37
38 #ifdef API_ENABLE
39 #include "api.h"
40 #endif
41
42 #ifdef MIDI_ENABLE
43 #include "process_midi.h"
44 #endif
45
46 #ifdef VELOCIKEY_ENABLE
47 #include "velocikey.h"
48 #endif
49
50 #ifdef HAPTIC_ENABLE
51 #include "haptic.h"
52 #endif
53
54 #ifdef ENCODER_ENABLE
55 #include "encoder.h"
56 #endif
57
58 #ifdef AUDIO_ENABLE
59 #ifndef GOODBYE_SONG
60 #define GOODBYE_SONG SONG(GOODBYE_SOUND)
61 #endif
62 #ifndef AG_NORM_SONG
63 #define AG_NORM_SONG SONG(AG_NORM_SOUND)
64 #endif
65 #ifndef AG_SWAP_SONG
66 #define AG_SWAP_SONG SONG(AG_SWAP_SOUND)
67 #endif
68 float goodbye_song[][2] = GOODBYE_SONG;
69 float ag_norm_song[][2] = AG_NORM_SONG;
70 float ag_swap_song[][2] = AG_SWAP_SONG;
71 #ifdef DEFAULT_LAYER_SONGS
72 float default_layer_songs[][16][2] = DEFAULT_LAYER_SONGS;
73 #endif
74 #endif
75
76 static void do_code16 (uint16_t code, void (*f) (uint8_t)) {
77 switch (code) {
78 case QK_MODS ... QK_MODS_MAX:
79 break;
80 default:
81 return;
82 }
83
84 if (code & QK_LCTL)
85 f(KC_LCTL);
86 if (code & QK_LSFT)
87 f(KC_LSFT);
88 if (code & QK_LALT)
89 f(KC_LALT);
90 if (code & QK_LGUI)
91 f(KC_LGUI);
92
93 if (code < QK_RMODS_MIN) return;
94
95 if (code & QK_RCTL)
96 f(KC_RCTL);
97 if (code & QK_RSFT)
98 f(KC_RSFT);
99 if (code & QK_RALT)
100 f(KC_RALT);
101 if (code & QK_RGUI)
102 f(KC_RGUI);
103 }
104
105 static inline void qk_register_weak_mods(uint8_t kc) {
106 add_weak_mods(MOD_BIT(kc));
107 send_keyboard_report();
108 }
109
110 static inline void qk_unregister_weak_mods(uint8_t kc) {
111 del_weak_mods(MOD_BIT(kc));
112 send_keyboard_report();
113 }
114
115 static inline void qk_register_mods(uint8_t kc) {
116 add_weak_mods(MOD_BIT(kc));
117 send_keyboard_report();
118 }
119
120 static inline void qk_unregister_mods(uint8_t kc) {
121 del_weak_mods(MOD_BIT(kc));
122 send_keyboard_report();
123 }
124
125 void register_code16 (uint16_t code) {
126 if (IS_MOD(code) || code == KC_NO) {
127 do_code16 (code, qk_register_mods);
128 } else {
129 do_code16 (code, qk_register_weak_mods);
130 }
131 register_code (code);
132 }
133
134 void unregister_code16 (uint16_t code) {
135 unregister_code (code);
136 if (IS_MOD(code) || code == KC_NO) {
137 do_code16 (code, qk_unregister_mods);
138 } else {
139 do_code16 (code, qk_unregister_weak_mods);
140 }
141 }
142
143 void tap_code16(uint16_t code) {
144 register_code16(code);
145 #if TAP_CODE_DELAY > 0
146 wait_ms(TAP_CODE_DELAY);
147 #endif
148 unregister_code16(code);
149 }
150
151 __attribute__ ((weak))
152 bool process_action_kb(keyrecord_t *record) {
153 return true;
154 }
155
156 __attribute__ ((weak))
157 bool process_record_kb(uint16_t keycode, keyrecord_t *record) {
158 return process_record_user(keycode, record);
159 }
160
161 __attribute__ ((weak))
162 bool process_record_user(uint16_t keycode, keyrecord_t *record) {
163 return true;
164 }
165
166 void reset_keyboard(void) {
167 clear_keyboard();
168 #if defined(MIDI_ENABLE) && defined(MIDI_BASIC)
169 process_midi_all_notes_off();
170 #endif
171 #ifdef AUDIO_ENABLE
172 #ifndef NO_MUSIC_MODE
173 music_all_notes_off();
174 #endif
175 uint16_t timer_start = timer_read();
176 PLAY_SONG(goodbye_song);
177 shutdown_user();
178 while(timer_elapsed(timer_start) < 250)
179 wait_ms(1);
180 stop_all_notes();
181 #else
182 shutdown_user();
183 wait_ms(250);
184 #endif
185 #ifdef HAPTIC_ENABLE
186 haptic_shutdown();
187 #endif
188 // this is also done later in bootloader.c - not sure if it's neccesary here
189 #ifdef BOOTLOADER_CATERINA
190 *(uint16_t *)0x0800 = 0x7777; // these two are a-star-specific
191 #endif
192 bootloader_jump();
193 }
194
195 /* true if the last press of GRAVE_ESC was shifted (i.e. GUI or SHIFT were pressed), false otherwise.
196 * Used to ensure that the correct keycode is released if the key is released.
197 */
198 static bool grave_esc_was_shifted = false;
199
200 /* Convert record into usable keycode via the contained event. */
201 uint16_t get_record_keycode(keyrecord_t *record) {
202 return get_event_keycode(record->event);
203 }
204
205
206 /* Convert event into usable keycode. Checks the layer cache to ensure that it
207 * retains the correct keycode after a layer change, if the key is still pressed.
208 */
209 uint16_t get_event_keycode(keyevent_t event) {
210
211 #if !defined(NO_ACTION_LAYER) && !defined(STRICT_LAYER_RELEASE)
212 /* TODO: Use store_or_get_action() or a similar function. */
213 if (!disable_action_cache) {
214 uint8_t layer;
215
216 if (event.pressed) {
217 layer = layer_switch_get_layer(event.key);
218 update_source_layers_cache(event.key, layer);
219 } else {
220 layer = read_source_layers_cache(event.key);
221 }
222 return keymap_key_to_keycode(layer, event.key);
223 } else
224 #endif
225 return keymap_key_to_keycode(layer_switch_get_layer(event.key), event.key);
226 }
227
228 /* Main keycode processing function. Hands off handling to other functions,
229 * then processes internal Quantum keycodes, then processes ACTIONs.
230 */
231 bool process_record_quantum(keyrecord_t *record) {
232 uint16_t keycode = get_record_keycode(record);
233
234 // This is how you use actions here
235 // if (keycode == KC_LEAD) {
236 // action_t action;
237 // action.code = ACTION_DEFAULT_LAYER_SET(0);
238 // process_action(record, action);
239 // return false;
240 // }
241
242 #ifdef VELOCIKEY_ENABLE
243 if (velocikey_enabled() && record->event.pressed) { velocikey_accelerate(); }
244 #endif
245
246 #ifdef TAP_DANCE_ENABLE
247 preprocess_tap_dance(keycode, record);
248 #endif
249
250 if (!(
251 #if defined(KEY_LOCK_ENABLE)
252 // Must run first to be able to mask key_up events.
253 process_key_lock(&keycode, record) &&
254 #endif
255 #if defined(AUDIO_ENABLE) && defined(AUDIO_CLICKY)
256 process_clicky(keycode, record) &&
257 #endif //AUDIO_CLICKY
258 #ifdef HAPTIC_ENABLE
259 process_haptic(keycode, record) &&
260 #endif //HAPTIC_ENABLE
261 #if defined(RGB_MATRIX_ENABLE)
262 process_rgb_matrix(keycode, record) &&
263 #endif
264 process_record_kb(keycode, record) &&
265 #if defined(MIDI_ENABLE) && defined(MIDI_ADVANCED)
266 process_midi(keycode, record) &&
267 #endif
268 #ifdef AUDIO_ENABLE
269 process_audio(keycode, record) &&
270 #endif
271 #ifdef STENO_ENABLE
272 process_steno(keycode, record) &&
273 #endif
274 #if (defined(AUDIO_ENABLE) || (defined(MIDI_ENABLE) && defined(MIDI_BASIC))) && !defined(NO_MUSIC_MODE)
275 process_music(keycode, record) &&
276 #endif
277 #ifdef TAP_DANCE_ENABLE
278 process_tap_dance(keycode, record) &&
279 #endif
280 #if defined(UNICODE_ENABLE) || defined(UNICODEMAP_ENABLE) || defined(UCIS_ENABLE)
281 process_unicode_common(keycode, record) &&
282 #endif
283 #ifdef LEADER_ENABLE
284 process_leader(keycode, record) &&
285 #endif
286 #ifdef COMBO_ENABLE
287 process_combo(keycode, record) &&
288 #endif
289 #ifdef PRINTING_ENABLE
290 process_printer(keycode, record) &&
291 #endif
292 #ifdef AUTO_SHIFT_ENABLE
293 process_auto_shift(keycode, record) &&
294 #endif
295 #ifdef TERMINAL_ENABLE
296 process_terminal(keycode, record) &&
297 #endif
298 #ifdef SPACE_CADET_ENABLE
299 process_space_cadet(keycode, record) &&
300 #endif
301 true)) {
302 return false;
303 }
304
305 // Shift / paren setup
306
307 switch(keycode) {
308 case RESET:
309 if (record->event.pressed) {
310 reset_keyboard();
311 }
312 return false;
313 case DEBUG:
314 if (record->event.pressed) {
315 debug_enable ^= 1;
316 if (debug_enable) {
317 print("DEBUG: enabled.\n");
318 } else {
319 print("DEBUG: disabled.\n");
320 }
321 }
322 return false;
323 case EEPROM_RESET:
324 if (record->event.pressed) {
325 eeconfig_init();
326 }
327 return false;
328 #ifdef FAUXCLICKY_ENABLE
329 case FC_TOG:
330 if (record->event.pressed) {
331 FAUXCLICKY_TOGGLE;
332 }
333 return false;
334 case FC_ON:
335 if (record->event.pressed) {
336 FAUXCLICKY_ON;
337 }
338 return false;
339 case FC_OFF:
340 if (record->event.pressed) {
341 FAUXCLICKY_OFF;
342 }
343 return false;
344 #endif
345 #if defined(RGBLIGHT_ENABLE) || defined(RGB_MATRIX_ENABLE)
346 case RGB_TOG:
347 // Split keyboards need to trigger on key-up for edge-case issue
348 #ifndef SPLIT_KEYBOARD
349 if (record->event.pressed) {
350 #else
351 if (!record->event.pressed) {
352 #endif
353 rgblight_toggle();
354 }
355 return false;
356 case RGB_MODE_FORWARD:
357 if (record->event.pressed) {
358 uint8_t shifted = get_mods() & (MOD_BIT(KC_LSHIFT)|MOD_BIT(KC_RSHIFT));
359 if(shifted) {
360 rgblight_step_reverse();
361 }
362 else {
363 rgblight_step();
364 }
365 }
366 return false;
367 case RGB_MODE_REVERSE:
368 if (record->event.pressed) {
369 uint8_t shifted = get_mods() & (MOD_BIT(KC_LSHIFT)|MOD_BIT(KC_RSHIFT));
370 if(shifted) {
371 rgblight_step();
372 }
373 else {
374 rgblight_step_reverse();
375 }
376 }
377 return false;
378 case RGB_HUI:
379 // Split keyboards need to trigger on key-up for edge-case issue
380 #ifndef SPLIT_KEYBOARD
381 if (record->event.pressed) {
382 #else
383 if (!record->event.pressed) {
384 #endif
385 rgblight_increase_hue();
386 }
387 return false;
388 case RGB_HUD:
389 // Split keyboards need to trigger on key-up for edge-case issue
390 #ifndef SPLIT_KEYBOARD
391 if (record->event.pressed) {
392 #else
393 if (!record->event.pressed) {
394 #endif
395 rgblight_decrease_hue();
396 }
397 return false;
398 case RGB_SAI:
399 // Split keyboards need to trigger on key-up for edge-case issue
400 #ifndef SPLIT_KEYBOARD
401 if (record->event.pressed) {
402 #else
403 if (!record->event.pressed) {
404 #endif
405 rgblight_increase_sat();
406 }
407 return false;
408 case RGB_SAD:
409 // Split keyboards need to trigger on key-up for edge-case issue
410 #ifndef SPLIT_KEYBOARD
411 if (record->event.pressed) {
412 #else
413 if (!record->event.pressed) {
414 #endif
415 rgblight_decrease_sat();
416 }
417 return false;
418 case RGB_VAI:
419 // Split keyboards need to trigger on key-up for edge-case issue
420 #ifndef SPLIT_KEYBOARD
421 if (record->event.pressed) {
422 #else
423 if (!record->event.pressed) {
424 #endif
425 rgblight_increase_val();
426 }
427 return false;
428 case RGB_VAD:
429 // Split keyboards need to trigger on key-up for edge-case issue
430 #ifndef SPLIT_KEYBOARD
431 if (record->event.pressed) {
432 #else
433 if (!record->event.pressed) {
434 #endif
435 rgblight_decrease_val();
436 }
437 return false;
438 case RGB_SPI:
439 if (record->event.pressed) {
440 rgblight_increase_speed();
441 }
442 return false;
443 case RGB_SPD:
444 if (record->event.pressed) {
445 rgblight_decrease_speed();
446 }
447 return false;
448 case RGB_MODE_PLAIN:
449 if (record->event.pressed) {
450 rgblight_mode(RGBLIGHT_MODE_STATIC_LIGHT);
451 }
452 return false;
453 case RGB_MODE_BREATHE:
454 #ifdef RGBLIGHT_EFFECT_BREATHING
455 if (record->event.pressed) {
456 if ((RGBLIGHT_MODE_BREATHING <= rgblight_get_mode()) &&
457 (rgblight_get_mode() < RGBLIGHT_MODE_BREATHING_end)) {
458 rgblight_step();
459 } else {
460 rgblight_mode(RGBLIGHT_MODE_BREATHING);
461 }
462 }
463 #endif
464 return false;
465 case RGB_MODE_RAINBOW:
466 #ifdef RGBLIGHT_EFFECT_RAINBOW_MOOD
467 if (record->event.pressed) {
468 if ((RGBLIGHT_MODE_RAINBOW_MOOD <= rgblight_get_mode()) &&
469 (rgblight_get_mode() < RGBLIGHT_MODE_RAINBOW_MOOD_end)) {
470 rgblight_step();
471 } else {
472 rgblight_mode(RGBLIGHT_MODE_RAINBOW_MOOD);
473 }
474 }
475 #endif
476 return false;
477 case RGB_MODE_SWIRL:
478 #ifdef RGBLIGHT_EFFECT_RAINBOW_SWIRL
479 if (record->event.pressed) {
480 if ((RGBLIGHT_MODE_RAINBOW_SWIRL <= rgblight_get_mode()) &&
481 (rgblight_get_mode() < RGBLIGHT_MODE_RAINBOW_SWIRL_end)) {
482 rgblight_step();
483 } else {
484 rgblight_mode(RGBLIGHT_MODE_RAINBOW_SWIRL);
485 }
486 }
487 #endif
488 return false;
489 case RGB_MODE_SNAKE:
490 #ifdef RGBLIGHT_EFFECT_SNAKE
491 if (record->event.pressed) {
492 if ((RGBLIGHT_MODE_SNAKE <= rgblight_get_mode()) &&
493 (rgblight_get_mode() < RGBLIGHT_MODE_SNAKE_end)) {
494 rgblight_step();
495 } else {
496 rgblight_mode(RGBLIGHT_MODE_SNAKE);
497 }
498 }
499 #endif
500 return false;
501 case RGB_MODE_KNIGHT:
502 #ifdef RGBLIGHT_EFFECT_KNIGHT
503 if (record->event.pressed) {
504 if ((RGBLIGHT_MODE_KNIGHT <= rgblight_get_mode()) &&
505 (rgblight_get_mode() < RGBLIGHT_MODE_KNIGHT_end)) {
506 rgblight_step();
507 } else {
508 rgblight_mode(RGBLIGHT_MODE_KNIGHT);
509 }
510 }
511 #endif
512 return false;
513 case RGB_MODE_XMAS:
514 #ifdef RGBLIGHT_EFFECT_CHRISTMAS
515 if (record->event.pressed) {
516 rgblight_mode(RGBLIGHT_MODE_CHRISTMAS);
517 }
518 #endif
519 return false;
520 case RGB_MODE_GRADIENT:
521 #ifdef RGBLIGHT_EFFECT_STATIC_GRADIENT
522 if (record->event.pressed) {
523 if ((RGBLIGHT_MODE_STATIC_GRADIENT <= rgblight_get_mode()) &&
524 (rgblight_get_mode() < RGBLIGHT_MODE_STATIC_GRADIENT_end)) {
525 rgblight_step();
526 } else {
527 rgblight_mode(RGBLIGHT_MODE_STATIC_GRADIENT);
528 }
529 }
530 #endif
531 return false;
532 case RGB_MODE_RGBTEST:
533 #ifdef RGBLIGHT_EFFECT_RGB_TEST
534 if (record->event.pressed) {
535 rgblight_mode(RGBLIGHT_MODE_RGB_TEST);
536 }
537 #endif
538 return false;
539 #endif // defined(RGBLIGHT_ENABLE) || defined(RGB_MATRIX_ENABLE)
540 #ifdef VELOCIKEY_ENABLE
541 case VLK_TOG:
542 if (record->event.pressed) {
543 velocikey_toggle();
544 }
545 return false;
546 #endif
547 #ifdef PROTOCOL_LUFA
548 case OUT_AUTO:
549 if (record->event.pressed) {
550 set_output(OUTPUT_AUTO);
551 }
552 return false;
553 case OUT_USB:
554 if (record->event.pressed) {
555 set_output(OUTPUT_USB);
556 }
557 return false;
558 #ifdef BLUETOOTH_ENABLE
559 case OUT_BT:
560 if (record->event.pressed) {
561 set_output(OUTPUT_BLUETOOTH);
562 }
563 return false;
564 #endif
565 #endif
566 case MAGIC_SWAP_CONTROL_CAPSLOCK ... MAGIC_TOGGLE_NKRO:
567 if (record->event.pressed) {
568 // MAGIC actions (BOOTMAGIC without the boot)
569 if (!eeconfig_is_enabled()) {
570 eeconfig_init();
571 }
572 /* keymap config */
573 keymap_config.raw = eeconfig_read_keymap();
574 switch (keycode)
575 {
576 case MAGIC_SWAP_CONTROL_CAPSLOCK:
577 keymap_config.swap_control_capslock = true;
578 break;
579 case MAGIC_CAPSLOCK_TO_CONTROL:
580 keymap_config.capslock_to_control = true;
581 break;
582 case MAGIC_SWAP_LALT_LGUI:
583 keymap_config.swap_lalt_lgui = true;
584 break;
585 case MAGIC_SWAP_RALT_RGUI:
586 keymap_config.swap_ralt_rgui = true;
587 break;
588 case MAGIC_NO_GUI:
589 keymap_config.no_gui = true;
590 break;
591 case MAGIC_SWAP_GRAVE_ESC:
592 keymap_config.swap_grave_esc = true;
593 break;
594 case MAGIC_SWAP_BACKSLASH_BACKSPACE:
595 keymap_config.swap_backslash_backspace = true;
596 break;
597 case MAGIC_HOST_NKRO:
598 keymap_config.nkro = true;
599 break;
600 case MAGIC_SWAP_ALT_GUI:
601 keymap_config.swap_lalt_lgui = true;
602 keymap_config.swap_ralt_rgui = true;
603 #ifdef AUDIO_ENABLE
604 PLAY_SONG(ag_swap_song);
605 #endif
606 break;
607 case MAGIC_UNSWAP_CONTROL_CAPSLOCK:
608 keymap_config.swap_control_capslock = false;
609 break;
610 case MAGIC_UNCAPSLOCK_TO_CONTROL:
611 keymap_config.capslock_to_control = false;
612 break;
613 case MAGIC_UNSWAP_LALT_LGUI:
614 keymap_config.swap_lalt_lgui = false;
615 break;
616 case MAGIC_UNSWAP_RALT_RGUI:
617 keymap_config.swap_ralt_rgui = false;
618 break;
619 case MAGIC_UNNO_GUI:
620 keymap_config.no_gui = false;
621 break;
622 case MAGIC_UNSWAP_GRAVE_ESC:
623 keymap_config.swap_grave_esc = false;
624 break;
625 case MAGIC_UNSWAP_BACKSLASH_BACKSPACE:
626 keymap_config.swap_backslash_backspace = false;
627 break;
628 case MAGIC_UNHOST_NKRO:
629 keymap_config.nkro = false;
630 break;
631 case MAGIC_UNSWAP_ALT_GUI:
632 keymap_config.swap_lalt_lgui = false;
633 keymap_config.swap_ralt_rgui = false;
634 #ifdef AUDIO_ENABLE
635 PLAY_SONG(ag_norm_song);
636 #endif
637 break;
638 case MAGIC_TOGGLE_ALT_GUI:
639 keymap_config.swap_lalt_lgui = !keymap_config.swap_lalt_lgui;
640 keymap_config.swap_ralt_rgui = !keymap_config.swap_ralt_rgui;
641 #ifdef AUDIO_ENABLE
642 if (keymap_config.swap_ralt_rgui) {
643 PLAY_SONG(ag_swap_song);
644 } else {
645 PLAY_SONG(ag_norm_song);
646 }
647 #endif
648 break;
649 case MAGIC_TOGGLE_NKRO:
650 keymap_config.nkro = !keymap_config.nkro;
651 break;
652 default:
653 break;
654 }
655 eeconfig_update_keymap(keymap_config.raw);
656 clear_keyboard(); // clear to prevent stuck keys
657
658 return false;
659 }
660 break;
661
662 case GRAVE_ESC: {
663 uint8_t shifted = get_mods() & ((MOD_BIT(KC_LSHIFT)|MOD_BIT(KC_RSHIFT)
664 |MOD_BIT(KC_LGUI)|MOD_BIT(KC_RGUI)));
665
666 #ifdef GRAVE_ESC_ALT_OVERRIDE
667 // if ALT is pressed, ESC is always sent
668 // this is handy for the cmd+opt+esc shortcut on macOS, among other things.
669 if (get_mods() & (MOD_BIT(KC_LALT) | MOD_BIT(KC_RALT))) {
670 shifted = 0;
671 }
672 #endif
673
674 #ifdef GRAVE_ESC_CTRL_OVERRIDE
675 // if CTRL is pressed, ESC is always sent
676 // this is handy for the ctrl+shift+esc shortcut on windows, among other things.
677 if (get_mods() & (MOD_BIT(KC_LCTL) | MOD_BIT(KC_RCTL))) {
678 shifted = 0;
679 }
680 #endif
681
682 #ifdef GRAVE_ESC_GUI_OVERRIDE
683 // if GUI is pressed, ESC is always sent
684 if (get_mods() & (MOD_BIT(KC_LGUI) | MOD_BIT(KC_RGUI))) {
685 shifted = 0;
686 }
687 #endif
688
689 #ifdef GRAVE_ESC_SHIFT_OVERRIDE
690 // if SHIFT is pressed, ESC is always sent
691 if (get_mods() & (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT))) {
692 shifted = 0;
693 }
694 #endif
695
696 if (record->event.pressed) {
697 grave_esc_was_shifted = shifted;
698 add_key(shifted ? KC_GRAVE : KC_ESCAPE);
699 }
700 else {
701 del_key(grave_esc_was_shifted ? KC_GRAVE : KC_ESCAPE);
702 }
703
704 send_keyboard_report();
705 return false;
706 }
707
708 #if defined(BACKLIGHT_ENABLE) && defined(BACKLIGHT_BREATHING)
709 case BL_BRTG: {
710 if (record->event.pressed) {
711 backlight_toggle_breathing();
712 }
713 return false;
714 }
715 #endif
716 }
717
718 return process_action_kb(record);
719 }
720
721 __attribute__ ((weak))
722 const bool ascii_to_shift_lut[128] PROGMEM = {
723 0, 0, 0, 0, 0, 0, 0, 0,
724 0, 0, 0, 0, 0, 0, 0, 0,
725 0, 0, 0, 0, 0, 0, 0, 0,
726 0, 0, 0, 0, 0, 0, 0, 0,
727
728 0, 1, 1, 1, 1, 1, 1, 0,
729 1, 1, 1, 1, 0, 0, 0, 0,
730 0, 0, 0, 0, 0, 0, 0, 0,
731 0, 0, 1, 0, 1, 0, 1, 1,
732 1, 1, 1, 1, 1, 1, 1, 1,
733 1, 1, 1, 1, 1, 1, 1, 1,
734 1, 1, 1, 1, 1, 1, 1, 1,
735 1, 1, 1, 0, 0, 0, 1, 1,
736 0, 0, 0, 0, 0, 0, 0, 0,
737 0, 0, 0, 0, 0, 0, 0, 0,
738 0, 0, 0, 0, 0, 0, 0, 0,
739 0, 0, 0, 1, 1, 1, 1, 0
740 };
741
742 __attribute__ ((weak))
743 const bool ascii_to_altgr_lut[128] PROGMEM = {
744 0, 0, 0, 0, 0, 0, 0, 0,
745 0, 0, 0, 0, 0, 0, 0, 0,
746 0, 0, 0, 0, 0, 0, 0, 0,
747 0, 0, 0, 0, 0, 0, 0, 0,
748
749 0, 0, 0, 0, 0, 0, 0, 0,
750 0, 0, 0, 0, 0, 0, 0, 0,
751 0, 0, 0, 0, 0, 0, 0, 0,
752 0, 0, 0, 0, 0, 0, 0, 0,
753 0, 0, 0, 0, 0, 0, 0, 0,
754 0, 0, 0, 0, 0, 0, 0, 0,
755 0, 0, 0, 0, 0, 0, 0, 0,
756 0, 0, 0, 0, 0, 0, 0, 0,
757 0, 0, 0, 0, 0, 0, 0, 0,
758 0, 0, 0, 0, 0, 0, 0, 0,
759 0, 0, 0, 0, 0, 0, 0, 0,
760 0, 0, 0, 0, 0, 0, 0, 0
761 };
762
763 __attribute__ ((weak))
764 const uint8_t ascii_to_keycode_lut[128] PROGMEM = {
765 // NUL SOH STX ETX EOT ENQ ACK BEL
766 XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
767 // BS TAB LF VT FF CR SO SI
768 KC_BSPC, KC_TAB, KC_ENT, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
769 // DLE DC1 DC2 DC3 DC4 NAK SYN ETB
770 XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
771 // CAN EM SUB ESC FS GS RS US
772 XXXXXXX, XXXXXXX, XXXXXXX, KC_ESC, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
773
774 // ! " # $ % & '
775 KC_SPC, KC_1, KC_QUOT, KC_3, KC_4, KC_5, KC_7, KC_QUOT,
776 // ( ) * + , - . /
777 KC_9, KC_0, KC_8, KC_EQL, KC_COMM, KC_MINS, KC_DOT, KC_SLSH,
778 // 0 1 2 3 4 5 6 7
779 KC_0, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7,
780 // 8 9 : ; < = > ?
781 KC_8, KC_9, KC_SCLN, KC_SCLN, KC_COMM, KC_EQL, KC_DOT, KC_SLSH,
782 // @ A B C D E F G
783 KC_2, KC_A, KC_B, KC_C, KC_D, KC_E, KC_F, KC_G,
784 // H I J K L M N O
785 KC_H, KC_I, KC_J, KC_K, KC_L, KC_M, KC_N, KC_O,
786 // P Q R S T U V W
787 KC_P, KC_Q, KC_R, KC_S, KC_T, KC_U, KC_V, KC_W,
788 // X Y Z [ \ ] ^ _
789 KC_X, KC_Y, KC_Z, KC_LBRC, KC_BSLS, KC_RBRC, KC_6, KC_MINS,
790 // ` a b c d e f g
791 KC_GRV, KC_A, KC_B, KC_C, KC_D, KC_E, KC_F, KC_G,
792 // h i j k l m n o
793 KC_H, KC_I, KC_J, KC_K, KC_L, KC_M, KC_N, KC_O,
794 // p q r s t u v w
795 KC_P, KC_Q, KC_R, KC_S, KC_T, KC_U, KC_V, KC_W,
796 // x y z { | } ~ DEL
797 KC_X, KC_Y, KC_Z, KC_LBRC, KC_BSLS, KC_RBRC, KC_GRV, KC_DEL
798 };
799
800 void send_string(const char *str) {
801 send_string_with_delay(str, 0);
802 }
803
804 void send_string_P(const char *str) {
805 send_string_with_delay_P(str, 0);
806 }
807
808 void send_string_with_delay(const char *str, uint8_t interval) {
809 while (1) {
810 char ascii_code = *str;
811 if (!ascii_code) break;
812 if (ascii_code == SS_TAP_CODE) {
813 // tap
814 uint8_t keycode = *(++str);
815 register_code(keycode);
816 unregister_code(keycode);
817 } else if (ascii_code == SS_DOWN_CODE) {
818 // down
819 uint8_t keycode = *(++str);
820 register_code(keycode);
821 } else if (ascii_code == SS_UP_CODE) {
822 // up
823 uint8_t keycode = *(++str);
824 unregister_code(keycode);
825 } else {
826 send_char(ascii_code);
827 }
828 ++str;
829 // interval
830 { uint8_t ms = interval; while (ms--) wait_ms(1); }
831 }
832 }
833
834 void send_string_with_delay_P(const char *str, uint8_t interval) {
835 while (1) {
836 char ascii_code = pgm_read_byte(str);
837 if (!ascii_code) break;
838 if (ascii_code == SS_TAP_CODE) {
839 // tap
840 uint8_t keycode = pgm_read_byte(++str);
841 register_code(keycode);
842 unregister_code(keycode);
843 } else if (ascii_code == SS_DOWN_CODE) {
844 // down
845 uint8_t keycode = pgm_read_byte(++str);
846 register_code(keycode);
847 } else if (ascii_code == SS_UP_CODE) {
848 // up
849 uint8_t keycode = pgm_read_byte(++str);
850 unregister_code(keycode);
851 } else {
852 send_char(ascii_code);
853 }
854 ++str;
855 // interval
856 { uint8_t ms = interval; while (ms--) wait_ms(1); }
857 }
858 }
859
860 void send_char(char ascii_code) {
861 uint8_t keycode = pgm_read_byte(&ascii_to_keycode_lut[(uint8_t)ascii_code]);
862 bool is_shifted = pgm_read_byte(&ascii_to_shift_lut[(uint8_t)ascii_code]);
863 bool is_altgred = pgm_read_byte(&ascii_to_altgr_lut[(uint8_t)ascii_code]);
864
865 if (is_shifted) {
866 register_code(KC_LSFT);
867 }
868 if (is_altgred) {
869 register_code(KC_RALT);
870 }
871 tap_code(keycode);
872 if (is_altgred) {
873 unregister_code(KC_RALT);
874 }
875 if (is_shifted) {
876 unregister_code(KC_LSFT);
877 }
878 }
879
880 void set_single_persistent_default_layer(uint8_t default_layer) {
881 #if defined(AUDIO_ENABLE) && defined(DEFAULT_LAYER_SONGS)
882 PLAY_SONG(default_layer_songs[default_layer]);
883 #endif
884 eeconfig_update_default_layer(1U<<default_layer);
885 default_layer_set(1U<<default_layer);
886 }
887
888 uint32_t update_tri_layer_state(uint32_t state, uint8_t layer1, uint8_t layer2, uint8_t layer3) {
889 uint32_t mask12 = (1UL << layer1) | (1UL << layer2);
890 uint32_t mask3 = 1UL << layer3;
891 return (state & mask12) == mask12 ? (state | mask3) : (state & ~mask3);
892 }
893
894 void update_tri_layer(uint8_t layer1, uint8_t layer2, uint8_t layer3) {
895 layer_state_set(update_tri_layer_state(layer_state, layer1, layer2, layer3));
896 }
897
898 void tap_random_base64(void) {
899 #if defined(__AVR_ATmega32U4__)
900 uint8_t key = (TCNT0 + TCNT1 + TCNT3 + TCNT4) % 64;
901 #else
902 uint8_t key = rand() % 64;
903 #endif
904 switch (key) {
905 case 0 ... 25:
906 register_code(KC_LSFT);
907 register_code(key + KC_A);
908 unregister_code(key + KC_A);
909 unregister_code(KC_LSFT);
910 break;
911 case 26 ... 51:
912 register_code(key - 26 + KC_A);
913 unregister_code(key - 26 + KC_A);
914 break;
915 case 52:
916 register_code(KC_0);
917 unregister_code(KC_0);
918 break;
919 case 53 ... 61:
920 register_code(key - 53 + KC_1);
921 unregister_code(key - 53 + KC_1);
922 break;
923 case 62:
924 register_code(KC_LSFT);
925 register_code(KC_EQL);
926 unregister_code(KC_EQL);
927 unregister_code(KC_LSFT);
928 break;
929 case 63:
930 register_code(KC_SLSH);
931 unregister_code(KC_SLSH);
932 break;
933 }
934 }
935
936 __attribute__((weak))
937 void bootmagic_lite(void) {
938 // The lite version of TMK's bootmagic based on Wilba.
939 // 100% less potential for accidentally making the
940 // keyboard do stupid things.
941
942 // We need multiple scans because debouncing can't be turned off.
943 matrix_scan();
944 #if defined(DEBOUNCING_DELAY) && DEBOUNCING_DELAY > 0
945 wait_ms(DEBOUNCING_DELAY * 2);
946 #elif defined(DEBOUNCE) && DEBOUNCE > 0
947 wait_ms(DEBOUNCE * 2);
948 #else
949 wait_ms(30);
950 #endif
951 matrix_scan();
952
953 // If the Esc and space bar are held down on power up,
954 // reset the EEPROM valid state and jump to bootloader.
955 // Assumes Esc is at [0,0].
956 // This isn't very generalized, but we need something that doesn't
957 // rely on user's keymaps in firmware or EEPROM.
958 if (matrix_get_row(BOOTMAGIC_LITE_ROW) & (1 << BOOTMAGIC_LITE_COLUMN)) {
959 eeconfig_disable();
960 // Jump to bootloader.
961 bootloader_jump();
962 }
963 }
964
965 void matrix_init_quantum() {
966 #ifdef BOOTMAGIC_LITE
967 bootmagic_lite();
968 #endif
969 if (!eeconfig_is_enabled()) {
970 eeconfig_init();
971 }
972 #ifdef BACKLIGHT_ENABLE
973 #ifdef LED_MATRIX_ENABLE
974 led_matrix_init();
975 #else
976 backlight_init_ports();
977 #endif
978 #endif
979 #ifdef AUDIO_ENABLE
980 audio_init();
981 #endif
982 #ifdef RGB_MATRIX_ENABLE
983 rgb_matrix_init();
984 #endif
985 #ifdef ENCODER_ENABLE
986 encoder_init();
987 #endif
988 #if defined(UNICODE_ENABLE) || defined(UNICODEMAP_ENABLE) || defined(UCIS_ENABLE)
989 unicode_input_mode_init();
990 #endif
991 #ifdef HAPTIC_ENABLE
992 haptic_init();
993 #endif
994 #ifdef OUTPUT_AUTO_ENABLE
995 set_output(OUTPUT_AUTO);
996 #endif
997 matrix_init_kb();
998 }
999
1000 void matrix_scan_quantum() {
1001 #if defined(AUDIO_ENABLE) && !defined(NO_MUSIC_MODE)
1002 matrix_scan_music();
1003 #endif
1004
1005 #ifdef TAP_DANCE_ENABLE
1006 matrix_scan_tap_dance();
1007 #endif
1008
1009 #ifdef COMBO_ENABLE
1010 matrix_scan_combo();
1011 #endif
1012
1013 #if defined(BACKLIGHT_ENABLE)
1014 #if defined(LED_MATRIX_ENABLE)
1015 led_matrix_task();
1016 #elif defined(BACKLIGHT_PIN)
1017 backlight_task();
1018 #endif
1019 #endif
1020
1021 #ifdef RGB_MATRIX_ENABLE
1022 rgb_matrix_task();
1023 #endif
1024
1025 #ifdef ENCODER_ENABLE
1026 encoder_read();
1027 #endif
1028
1029 #ifdef HAPTIC_ENABLE
1030 haptic_task();
1031 #endif
1032
1033 matrix_scan_kb();
1034 }
1035 #if defined(BACKLIGHT_ENABLE) && (defined(BACKLIGHT_PIN) || defined(BACKLIGHT_PINS))
1036
1037 // The logic is a bit complex, we support 3 setups:
1038 // 1. hardware PWM when backlight is wired to a PWM pin
1039 // depending on this pin, we use a different output compare unit
1040 // 2. software PWM with hardware timers, but the used timer depends
1041 // on the audio setup (audio wins other backlight)
1042 // 3. full software PWM
1043
1044 #if BACKLIGHT_PIN == B7
1045 # define HARDWARE_PWM
1046 # define TCCRxA TCCR1A
1047 # define TCCRxB TCCR1B
1048 # define COMxx1 COM1C1
1049 # define OCRxx OCR1C
1050 # define TIMERx_OVF_vect TIMER1_OVF_vect
1051 # define TOIEx TOIE1
1052 # define ICRx ICR1
1053 # define TIMSKx TIMSK1
1054 #elif BACKLIGHT_PIN == B6
1055 # define HARDWARE_PWM
1056 # define TCCRxA TCCR1A
1057 # define TCCRxB TCCR1B
1058 # define COMxx1 COM1B1
1059 # define OCRxx OCR1B
1060 # define TIMERx_OVF_vect TIMER1_OVF_vect
1061 # define TOIEx TOIE1
1062 # define ICRx ICR1
1063 # define TIMSKx TIMSK1
1064 #elif BACKLIGHT_PIN == B5
1065 # define HARDWARE_PWM
1066 # define TCCRxA TCCR1A
1067 # define TCCRxB TCCR1B
1068 # define COMxx1 COM1A1
1069 # define OCRxx OCR1A
1070 # define TIMERx_OVF_vect TIMER1_OVF_vect
1071 # define TOIEx TOIE1
1072 # define ICRx ICR1
1073 # define TIMSKx TIMSK1
1074 #elif BACKLIGHT_PIN == C6
1075 # define HARDWARE_PWM
1076 # define TCCRxA TCCR3A
1077 # define TCCRxB TCCR3B
1078 # define COMxx1 COM3A1
1079 # define OCRxx OCR3A
1080 # define TIMERx_OVF_vect TIMER3_OVF_vect
1081 # define TOIEx TOIE3
1082 # define ICRx ICR3
1083 # define TIMSKx TIMSK3
1084 #elif defined(__AVR_ATmega32A__) && BACKLIGHT_PIN == D4
1085 # define TCCRxA TCCR1A
1086 # define TCCRxB TCCR1B
1087 # define COMxx1 COM1B1
1088 # define OCRxx OCR1B
1089 # define TIMERx_OVF_vect TIMER1_OVF_vect
1090 # define TOIEx TOIE1
1091 # define ICRx ICR1
1092 # define TIMSKx TIMSK1
1093 #else
1094 # if !defined(BACKLIGHT_CUSTOM_DRIVER)
1095 # if !defined(B5_AUDIO) && !defined(B6_AUDIO) && !defined(B7_AUDIO)
1096 // timer 1 is not used by audio , backlight can use it
1097 #pragma message "Using hardware timer 1 with software PWM"
1098 # define HARDWARE_PWM
1099 # define BACKLIGHT_PWM_TIMER
1100 # define TCCRxA TCCR1A
1101 # define TCCRxB TCCR1B
1102 # define OCRxx OCR1A
1103 # define TIMERx_COMPA_vect TIMER1_COMPA_vect
1104 # define TIMERx_OVF_vect TIMER1_OVF_vect
1105 # define OCIExA OCIE1A
1106 # define TOIEx TOIE1
1107 # define ICRx ICR1
1108 # if defined(__AVR_ATmega32A__) // This MCU has only one TIMSK register
1109 # define TIMSKx TIMSK
1110 # else
1111 # define TIMSKx TIMSK1
1112 # endif
1113 # elif !defined(C6_AUDIO) && !defined(C5_AUDIO) && !defined(C4_AUDIO)
1114 #pragma message "Using hardware timer 3 with software PWM"
1115 // timer 3 is not used by audio, backlight can use it
1116 # define HARDWARE_PWM
1117 # define BACKLIGHT_PWM_TIMER
1118 # define TCCRxA TCCR3A
1119 # define TCCRxB TCCR3B
1120 # define OCRxx OCR3A
1121 # define TIMERx_COMPA_vect TIMER3_COMPA_vect
1122 # define TIMERx_OVF_vect TIMER3_OVF_vect
1123 # define OCIExA OCIE3A
1124 # define TOIEx TOIE3
1125 # define ICRx ICR1
1126 # define TIMSKx TIMSK3
1127 # else
1128 #pragma message "Audio in use - using pure software PWM"
1129 #define NO_HARDWARE_PWM
1130 # endif
1131 # else
1132 #pragma message "Custom driver defined - using pure software PWM"
1133 #define NO_HARDWARE_PWM
1134 # endif
1135 #endif
1136
1137 #ifndef BACKLIGHT_ON_STATE
1138 #define BACKLIGHT_ON_STATE 0
1139 #endif
1140
1141 void backlight_on(uint8_t backlight_pin) {
1142 #if BACKLIGHT_ON_STATE == 0
1143 writePinLow(backlight_pin);
1144 #else
1145 writePinHigh(backlight_pin);
1146 #endif
1147 }
1148
1149 void backlight_off(uint8_t backlight_pin) {
1150 #if BACKLIGHT_ON_STATE == 0
1151 writePinHigh(backlight_pin);
1152 #else
1153 writePinLow(backlight_pin);
1154 #endif
1155 }
1156
1157
1158 #if defined(NO_HARDWARE_PWM) || defined(BACKLIGHT_PWM_TIMER) // pwm through software
1159
1160 // we support multiple backlight pins
1161 #ifndef BACKLIGHT_LED_COUNT
1162 #define BACKLIGHT_LED_COUNT 1
1163 #endif
1164
1165 #if BACKLIGHT_LED_COUNT == 1
1166 #define BACKLIGHT_PIN_INIT { BACKLIGHT_PIN }
1167 #else
1168 #define BACKLIGHT_PIN_INIT BACKLIGHT_PINS
1169 #endif
1170
1171 #define FOR_EACH_LED(x) \
1172 for (uint8_t i = 0; i < BACKLIGHT_LED_COUNT; i++) \
1173 { \
1174 uint8_t backlight_pin = backlight_pins[i]; \
1175 { \
1176 x \
1177 } \
1178 }
1179
1180 static const uint8_t backlight_pins[BACKLIGHT_LED_COUNT] = BACKLIGHT_PIN_INIT;
1181
1182 #else // full hardware PWM
1183
1184 // we support only one backlight pin
1185 static const uint8_t backlight_pin = BACKLIGHT_PIN;
1186 #define FOR_EACH_LED(x) x
1187
1188 #endif
1189
1190 #ifdef NO_HARDWARE_PWM
1191 __attribute__((weak))
1192 void backlight_init_ports(void)
1193 {
1194 // Setup backlight pin as output and output to on state.
1195 FOR_EACH_LED(
1196 setPinOutput(backlight_pin);
1197 backlight_on(backlight_pin);
1198 )
1199
1200 #ifdef BACKLIGHT_BREATHING
1201 if (is_backlight_breathing()) {
1202 breathing_enable();
1203 }
1204 #endif
1205 }
1206
1207 __attribute__ ((weak))
1208 void backlight_set(uint8_t level) {}
1209
1210 uint8_t backlight_tick = 0;
1211
1212 #ifndef BACKLIGHT_CUSTOM_DRIVER
1213 void backlight_task(void) {
1214 if ((0xFFFF >> ((BACKLIGHT_LEVELS - get_backlight_level()) * ((BACKLIGHT_LEVELS + 1) / 2))) & (1 << backlight_tick)) {
1215 FOR_EACH_LED(
1216 backlight_on(backlight_pin);
1217 )
1218 }
1219 else {
1220 FOR_EACH_LED(
1221 backlight_off(backlight_pin);
1222 )
1223 }
1224 backlight_tick = (backlight_tick + 1) % 16;
1225 }
1226 #endif
1227
1228 #ifdef BACKLIGHT_BREATHING
1229 #ifndef BACKLIGHT_CUSTOM_DRIVER
1230 #error "Backlight breathing only available with hardware PWM. Please disable."
1231 #endif
1232 #endif
1233
1234 #else // hardware pwm through timer
1235
1236 #ifdef BACKLIGHT_PWM_TIMER
1237
1238 // The idea of software PWM assisted by hardware timers is the following
1239 // we use the hardware timer in fast PWM mode like for hardware PWM, but
1240 // instead of letting the Output Match Comparator control the led pin
1241 // (which is not possible since the backlight is not wired to PWM pins on the
1242 // CPU), we do the LED on/off by oursleves.
1243 // The timer is setup to count up to 0xFFFF, and we set the Output Compare
1244 // register to the current 16bits backlight level (after CIE correction).
1245 // This means the CPU will trigger a compare match interrupt when the counter
1246 // reaches the backlight level, where we turn off the LEDs,
1247 // but also an overflow interrupt when the counter rolls back to 0,
1248 // in which we're going to turn on the LEDs.
1249 // The LED will then be on for OCRxx/0xFFFF time, adjusted every 244Hz.
1250
1251 // Triggered when the counter reaches the OCRx value
1252 ISR(TIMERx_COMPA_vect) {
1253 FOR_EACH_LED(
1254 backlight_off(backlight_pin);
1255 )
1256 }
1257
1258 // Triggered when the counter reaches the TOP value
1259 // this one triggers at F_CPU/65536 =~ 244 Hz
1260 ISR(TIMERx_OVF_vect) {
1261 #ifdef BACKLIGHT_BREATHING
1262 if(is_breathing()) {
1263 breathing_task();
1264 }
1265 #endif
1266 // for very small values of OCRxx (or backlight level)
1267 // we can't guarantee this whole code won't execute
1268 // at the same time as the compare match interrupt
1269 // which means that we might turn on the leds while
1270 // trying to turn them off, leading to flickering
1271 // artifacts (especially while breathing, because breathing_task
1272 // takes many computation cycles).
1273 // so better not turn them on while the counter TOP is very low.
1274 if (OCRxx > 256) {
1275 FOR_EACH_LED(
1276 backlight_on(backlight_pin);
1277 )
1278 }
1279 }
1280
1281 #endif
1282
1283 #define TIMER_TOP 0xFFFFU
1284
1285 // See http://jared.geek.nz/2013/feb/linear-led-pwm
1286 static uint16_t cie_lightness(uint16_t v) {
1287 if (v <= 5243) // if below 8% of max
1288 return v / 9; // same as dividing by 900%
1289 else {
1290 uint32_t y = (((uint32_t) v + 10486) << 8) / (10486 + 0xFFFFUL); // add 16% of max and compare
1291 // to get a useful result with integer division, we shift left in the expression above
1292 // and revert what we've done again after squaring.
1293 y = y * y * y >> 8;
1294 if (y > 0xFFFFUL) // prevent overflow
1295 return 0xFFFFU;
1296 else
1297 return (uint16_t) y;
1298 }
1299 }
1300
1301 // range for val is [0..TIMER_TOP]. PWM pin is high while the timer count is below val.
1302 static inline void set_pwm(uint16_t val) {
1303 OCRxx = val;
1304 }
1305
1306 #ifndef BACKLIGHT_CUSTOM_DRIVER
1307 __attribute__ ((weak))
1308 void backlight_set(uint8_t level) {
1309 if (level > BACKLIGHT_LEVELS)
1310 level = BACKLIGHT_LEVELS;
1311
1312 if (level == 0) {
1313 #ifdef BACKLIGHT_PWM_TIMER
1314 if (OCRxx) {
1315 TIMSKx &= ~(_BV(OCIExA));
1316 TIMSKx &= ~(_BV(TOIEx));
1317 FOR_EACH_LED(
1318 backlight_off(backlight_pin);
1319 )
1320 }
1321 #else
1322 // Turn off PWM control on backlight pin
1323 TCCRxA &= ~(_BV(COMxx1));
1324 #endif
1325 } else {
1326 #ifdef BACKLIGHT_PWM_TIMER
1327 if (!OCRxx) {
1328 TIMSKx |= _BV(OCIExA);
1329 TIMSKx |= _BV(TOIEx);
1330 }
1331 #else
1332 // Turn on PWM control of backlight pin
1333 TCCRxA |= _BV(COMxx1);
1334 #endif
1335 }
1336 // Set the brightness
1337 set_pwm(cie_lightness(TIMER_TOP * (uint32_t)level / BACKLIGHT_LEVELS));
1338 }
1339
1340 void backlight_task(void) {}
1341 #endif // BACKLIGHT_CUSTOM_DRIVER
1342
1343 #ifdef BACKLIGHT_BREATHING
1344
1345 #define BREATHING_NO_HALT 0
1346 #define BREATHING_HALT_OFF 1
1347 #define BREATHING_HALT_ON 2
1348 #define BREATHING_STEPS 128
1349
1350 static uint8_t breathing_period = BREATHING_PERIOD;
1351 static uint8_t breathing_halt = BREATHING_NO_HALT;
1352 static uint16_t breathing_counter = 0;
1353
1354 #ifdef BACKLIGHT_PWM_TIMER
1355 static bool breathing = false;
1356
1357 bool is_breathing(void) {
1358 return breathing;
1359 }
1360
1361 #define breathing_interrupt_enable() do { breathing = true; } while (0)
1362 #define breathing_interrupt_disable() do { breathing = false; } while (0)
1363 #else
1364
1365 bool is_breathing(void) {
1366 return !!(TIMSKx & _BV(TOIEx));
1367 }
1368
1369 #define breathing_interrupt_enable() do {TIMSKx |= _BV(TOIEx);} while (0)
1370 #define breathing_interrupt_disable() do {TIMSKx &= ~_BV(TOIEx);} while (0)
1371 #endif
1372
1373 #define breathing_min() do {breathing_counter = 0;} while (0)
1374 #define breathing_max() do {breathing_counter = breathing_period * 244 / 2;} while (0)
1375
1376 void breathing_enable(void)
1377 {
1378 breathing_counter = 0;
1379 breathing_halt = BREATHING_NO_HALT;
1380 breathing_interrupt_enable();
1381 }
1382
1383 void breathing_pulse(void)
1384 {
1385 if (get_backlight_level() == 0)
1386 breathing_min();
1387 else
1388 breathing_max();
1389 breathing_halt = BREATHING_HALT_ON;
1390 breathing_interrupt_enable();
1391 }
1392
1393 void breathing_disable(void)
1394 {
1395 breathing_interrupt_disable();
1396 // Restore backlight level
1397 backlight_set(get_backlight_level());
1398 }
1399
1400 void breathing_self_disable(void)
1401 {
1402 if (get_backlight_level() == 0)
1403 breathing_halt = BREATHING_HALT_OFF;
1404 else
1405 breathing_halt = BREATHING_HALT_ON;
1406 }
1407
1408 void breathing_toggle(void) {
1409 if (is_breathing())
1410 breathing_disable();
1411 else
1412 breathing_enable();
1413 }
1414
1415 void breathing_period_set(uint8_t value)
1416 {
1417 if (!value)
1418 value = 1;
1419 breathing_period = value;
1420 }
1421
1422 void breathing_period_default(void) {
1423 breathing_period_set(BREATHING_PERIOD);
1424 }
1425
1426 void breathing_period_inc(void)
1427 {
1428 breathing_period_set(breathing_period+1);
1429 }
1430
1431 void breathing_period_dec(void)
1432 {
1433 breathing_period_set(breathing_period-1);
1434 }
1435
1436 /* To generate breathing curve in python:
1437 * from math import sin, pi; [int(sin(x/128.0*pi)**4*255) for x in range(128)]
1438 */
1439 static const uint8_t breathing_table[BREATHING_STEPS] PROGMEM = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 3, 4, 5, 6, 8, 10, 12, 15, 17, 20, 24, 28, 32, 36, 41, 46, 51, 57, 63, 70, 76, 83, 91, 98, 106, 113, 121, 129, 138, 146, 154, 162, 170, 178, 185, 193, 200, 207, 213, 220, 225, 231, 235, 240, 244, 247, 250, 252, 253, 254, 255, 254, 253, 252, 250, 247, 244, 240, 235, 231, 225, 220, 213, 207, 200, 193, 185, 178, 170, 162, 154, 146, 138, 129, 121, 113, 106, 98, 91, 83, 76, 70, 63, 57, 51, 46, 41, 36, 32, 28, 24, 20, 17, 15, 12, 10, 8, 6, 5, 4, 3, 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
1440
1441 // Use this before the cie_lightness function.
1442 static inline uint16_t scale_backlight(uint16_t v) {
1443 return v / BACKLIGHT_LEVELS * get_backlight_level();
1444 }
1445
1446 #ifdef BACKLIGHT_PWM_TIMER
1447 void breathing_task(void)
1448 #else
1449 /* Assuming a 16MHz CPU clock and a timer that resets at 64k (ICR1), the following interrupt handler will run
1450 * about 244 times per second.
1451 */
1452 ISR(TIMERx_OVF_vect)
1453 #endif
1454 {
1455 uint16_t interval = (uint16_t) breathing_period * 244 / BREATHING_STEPS;
1456 // resetting after one period to prevent ugly reset at overflow.
1457 breathing_counter = (breathing_counter + 1) % (breathing_period * 244);
1458 uint8_t index = breathing_counter / interval % BREATHING_STEPS;
1459
1460 if (((breathing_halt == BREATHING_HALT_ON) && (index == BREATHING_STEPS / 2)) ||
1461 ((breathing_halt == BREATHING_HALT_OFF) && (index == BREATHING_STEPS - 1)))
1462 {
1463 breathing_interrupt_disable();
1464 }
1465
1466 set_pwm(cie_lightness(scale_backlight((uint16_t) pgm_read_byte(&breathing_table[index]) * 0x0101U)));
1467 }
1468
1469 #endif // BACKLIGHT_BREATHING
1470
1471 __attribute__ ((weak))
1472 void backlight_init_ports(void)
1473 {
1474 // Setup backlight pin as output and output to on state.
1475 FOR_EACH_LED(
1476 setPinOutput(backlight_pin);
1477 backlight_on(backlight_pin);
1478 )
1479
1480 // I could write a wall of text here to explain... but TL;DW
1481 // Go read the ATmega32u4 datasheet.
1482 // And this: http://blog.saikoled.com/post/43165849837/secret-konami-cheat-code-to-high-resolution-pwm-on
1483
1484 #ifdef BACKLIGHT_PWM_TIMER
1485 // TimerX setup, Fast PWM mode count to TOP set in ICRx
1486 TCCRxA = _BV(WGM11); // = 0b00000010;
1487 // clock select clk/1
1488 TCCRxB = _BV(WGM13) | _BV(WGM12) | _BV(CS10); // = 0b00011001;
1489 #else // hardware PWM
1490 // Pin PB7 = OCR1C (Timer 1, Channel C)
1491 // Compare Output Mode = Clear on compare match, Channel C = COM1C1=1 COM1C0=0
1492 // (i.e. start high, go low when counter matches.)
1493 // WGM Mode 14 (Fast PWM) = WGM13=1 WGM12=1 WGM11=1 WGM10=0
1494 // Clock Select = clk/1 (no prescaling) = CS12=0 CS11=0 CS10=1
1495
1496 /*
1497 14.8.3:
1498 "In fast PWM mode, the compare units allow generation of PWM waveforms on the OCnx pins. Setting the COMnx1:0 bits to two will produce a non-inverted PWM [..]."
1499 "In fast PWM mode the counter is incremented until the counter value matches either one of the fixed values 0x00FF, 0x01FF, or 0x03FF (WGMn3:0 = 5, 6, or 7), the value in ICRn (WGMn3:0 = 14), or the value in OCRnA (WGMn3:0 = 15)."
1500 */
1501 TCCRxA = _BV(COMxx1) | _BV(WGM11); // = 0b00001010;
1502 TCCRxB = _BV(WGM13) | _BV(WGM12) | _BV(CS10); // = 0b00011001;
1503 #endif
1504 // Use full 16-bit resolution. Counter counts to ICR1 before reset to 0.
1505 ICRx = TIMER_TOP;
1506
1507 backlight_init();
1508 #ifdef BACKLIGHT_BREATHING
1509 if (is_backlight_breathing()) {
1510 breathing_enable();
1511 }
1512 #endif
1513 }
1514
1515 #endif // hardware backlight
1516
1517 #else // no backlight
1518
1519 __attribute__ ((weak))
1520 void backlight_init_ports(void) {}
1521
1522 __attribute__ ((weak))
1523 void backlight_set(uint8_t level) {}
1524
1525 #endif // backlight
1526
1527 #ifdef HD44780_ENABLED
1528 #include "hd44780.h"
1529 #endif
1530
1531
1532 // Functions for spitting out values
1533 //
1534
1535 void send_dword(uint32_t number) { // this might not actually work
1536 uint16_t word = (number >> 16);
1537 send_word(word);
1538 send_word(number & 0xFFFFUL);
1539 }
1540
1541 void send_word(uint16_t number) {
1542 uint8_t byte = number >> 8;
1543 send_byte(byte);
1544 send_byte(number & 0xFF);
1545 }
1546
1547 void send_byte(uint8_t number) {
1548 uint8_t nibble = number >> 4;
1549 send_nibble(nibble);
1550 send_nibble(number & 0xF);
1551 }
1552
1553 void send_nibble(uint8_t number) {
1554 switch (number) {
1555 case 0:
1556 register_code(KC_0);
1557 unregister_code(KC_0);
1558 break;
1559 case 1 ... 9:
1560 register_code(KC_1 + (number - 1));
1561 unregister_code(KC_1 + (number - 1));
1562 break;
1563 case 0xA ... 0xF:
1564 register_code(KC_A + (number - 0xA));
1565 unregister_code(KC_A + (number - 0xA));
1566 break;
1567 }
1568 }
1569
1570
1571 __attribute__((weak))
1572 uint16_t hex_to_keycode(uint8_t hex)
1573 {
1574 hex = hex & 0xF;
1575 if (hex == 0x0) {
1576 return KC_0;
1577 } else if (hex < 0xA) {
1578 return KC_1 + (hex - 0x1);
1579 } else {
1580 return KC_A + (hex - 0xA);
1581 }
1582 }
1583
1584 void api_send_unicode(uint32_t unicode) {
1585 #ifdef API_ENABLE
1586 uint8_t chunk[4];
1587 dword_to_bytes(unicode, chunk);
1588 MT_SEND_DATA(DT_UNICODE, chunk, 5);
1589 #endif
1590 }
1591
1592 __attribute__ ((weak))
1593 void led_set_user(uint8_t usb_led) {
1594
1595 }
1596
1597 __attribute__ ((weak))
1598 void led_set_kb(uint8_t usb_led) {
1599 led_set_user(usb_led);
1600 }
1601
1602 __attribute__ ((weak))
1603 void led_init_ports(void)
1604 {
1605
1606 }
1607
1608 __attribute__ ((weak))
1609 void led_set(uint8_t usb_led)
1610 {
1611 #if defined(BACKLIGHT_CAPS_LOCK) && defined(BACKLIGHT_ENABLE)
1612 // Use backlight as Caps Lock indicator
1613 uint8_t bl_toggle_lvl = 0;
1614
1615 if (IS_LED_ON(usb_led, USB_LED_CAPS_LOCK) && !backlight_config.enable) {
1616 // Turning Caps Lock ON and backlight is disabled in config
1617 // Toggling backlight to the brightest level
1618 bl_toggle_lvl = BACKLIGHT_LEVELS;
1619 } else if (IS_LED_OFF(usb_led, USB_LED_CAPS_LOCK) && backlight_config.enable) {
1620 // Turning Caps Lock OFF and backlight is enabled in config
1621 // Toggling backlight and restoring config level
1622 bl_toggle_lvl = backlight_config.level;
1623 }
1624
1625 // Set level without modify backlight_config to keep ability to restore state
1626 backlight_set(bl_toggle_lvl);
1627 #endif
1628
1629 led_set_kb(usb_led);
1630 }
1631
1632
1633 //------------------------------------------------------------------------------
1634 // Override these functions in your keymap file to play different tunes on
1635 // different events such as startup and bootloader jump
1636
1637 __attribute__ ((weak))
1638 void startup_user() {}
1639
1640 __attribute__ ((weak))
1641 void shutdown_user() {}
1642
1643 //------------------------------------------------------------------------------