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