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