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