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