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