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