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