3 static void do_code16 (uint16_t code, void (*f) (uint8_t)) {
5 case QK_MODS ... QK_MODS_MAX:
30 void register_code16 (uint16_t code) {
31 do_code16 (code, register_code);
35 void unregister_code16 (uint16_t code) {
36 unregister_code (code);
37 do_code16 (code, unregister_code);
40 __attribute__ ((weak))
41 bool process_action_kb(keyrecord_t *record) {
45 __attribute__ ((weak))
46 bool process_record_kb(uint16_t keycode, keyrecord_t *record) {
47 return process_record_user(keycode, record);
50 __attribute__ ((weak))
51 bool process_record_user(uint16_t keycode, keyrecord_t *record) {
55 void reset_keyboard(void) {
62 #ifdef CATERINA_BOOTLOADER
63 *(uint16_t *)0x0800 = 0x7777; // these two are a-star-specific
68 // Shift / paren setup
77 static bool shift_interrupted[2] = {0, 0};
79 bool process_record_quantum(keyrecord_t *record) {
81 /* This gets the keycode from the key pressed */
82 keypos_t key = record->event.key;
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) {
90 if (record->event.pressed) {
91 layer = layer_switch_get_layer(key);
92 update_source_layers_cache(key, layer);
94 layer = read_source_layers_cache(key);
96 keycode = keymap_key_to_keycode(layer, key);
99 keycode = keymap_key_to_keycode(layer_switch_get_layer(key), key);
101 // This is how you use actions here
102 // if (keycode == KC_LEAD) {
104 // action.code = ACTION_DEFAULT_LAYER_SET(0);
105 // process_action(record, action);
110 process_record_kb(keycode, record) &&
112 process_midi(keycode, record) &&
115 process_music(keycode, record) &&
117 #ifdef TAP_DANCE_ENABLE
118 process_tap_dance(keycode, record) &&
120 #ifndef DISABLE_LEADER
121 process_leader(keycode, record) &&
123 #ifndef DISABLE_CHORDING
124 process_chording(keycode, record) &&
126 #ifdef UNICODE_ENABLE
127 process_unicode(keycode, record) &&
130 process_ucis(keycode, record) &&
136 // Shift / paren setup
140 if (record->event.pressed) {
146 if (record->event.pressed) {
147 print("\nDEBUG: enabled.\n");
152 #ifdef RGBLIGHT_ENABLE
154 if (record->event.pressed) {
160 if (record->event.pressed) {
166 if (record->event.pressed) {
167 rgblight_increase_hue();
172 if (record->event.pressed) {
173 rgblight_decrease_hue();
178 if (record->event.pressed) {
179 rgblight_increase_sat();
184 if (record->event.pressed) {
185 rgblight_decrease_sat();
190 if (record->event.pressed) {
191 rgblight_increase_val();
196 if (record->event.pressed) {
197 rgblight_decrease_val();
202 case MAGIC_SWAP_CONTROL_CAPSLOCK ... MAGIC_TOGGLE_NKRO:
203 if (record->event.pressed) {
204 // MAGIC actions (BOOTMAGIC without the boot)
205 if (!eeconfig_is_enabled()) {
209 keymap_config.raw = eeconfig_read_keymap();
212 case MAGIC_SWAP_CONTROL_CAPSLOCK:
213 keymap_config.swap_control_capslock = true;
215 case MAGIC_CAPSLOCK_TO_CONTROL:
216 keymap_config.capslock_to_control = true;
218 case MAGIC_SWAP_LALT_LGUI:
219 keymap_config.swap_lalt_lgui = true;
221 case MAGIC_SWAP_RALT_RGUI:
222 keymap_config.swap_ralt_rgui = true;
225 keymap_config.no_gui = true;
227 case MAGIC_SWAP_GRAVE_ESC:
228 keymap_config.swap_grave_esc = true;
230 case MAGIC_SWAP_BACKSLASH_BACKSPACE:
231 keymap_config.swap_backslash_backspace = true;
233 case MAGIC_HOST_NKRO:
234 keymap_config.nkro = true;
236 case MAGIC_SWAP_ALT_GUI:
237 keymap_config.swap_lalt_lgui = true;
238 keymap_config.swap_ralt_rgui = true;
240 case MAGIC_UNSWAP_CONTROL_CAPSLOCK:
241 keymap_config.swap_control_capslock = false;
243 case MAGIC_UNCAPSLOCK_TO_CONTROL:
244 keymap_config.capslock_to_control = false;
246 case MAGIC_UNSWAP_LALT_LGUI:
247 keymap_config.swap_lalt_lgui = false;
249 case MAGIC_UNSWAP_RALT_RGUI:
250 keymap_config.swap_ralt_rgui = false;
253 keymap_config.no_gui = false;
255 case MAGIC_UNSWAP_GRAVE_ESC:
256 keymap_config.swap_grave_esc = false;
258 case MAGIC_UNSWAP_BACKSLASH_BACKSPACE:
259 keymap_config.swap_backslash_backspace = false;
261 case MAGIC_UNHOST_NKRO:
262 keymap_config.nkro = false;
264 case MAGIC_UNSWAP_ALT_GUI:
265 keymap_config.swap_lalt_lgui = false;
266 keymap_config.swap_ralt_rgui = false;
268 case MAGIC_TOGGLE_NKRO:
269 keymap_config.nkro = !keymap_config.nkro;
274 eeconfig_update_keymap(keymap_config.raw);
275 clear_keyboard(); // clear to prevent stuck keys
281 if (record->event.pressed) {
282 shift_interrupted[0] = false;
283 register_mods(MOD_BIT(KC_LSFT));
286 #ifdef DISABLE_SPACE_CADET_ROLLOVER
287 if (get_mods() & MOD_BIT(KC_RSFT)) {
288 shift_interrupted[0] = true;
289 shift_interrupted[1] = true;
292 if (!shift_interrupted[0]) {
293 register_code(LSPO_KEY);
294 unregister_code(LSPO_KEY);
296 unregister_mods(MOD_BIT(KC_LSFT));
303 if (record->event.pressed) {
304 shift_interrupted[1] = false;
305 register_mods(MOD_BIT(KC_RSFT));
308 #ifdef DISABLE_SPACE_CADET_ROLLOVER
309 if (get_mods() & MOD_BIT(KC_LSFT)) {
310 shift_interrupted[0] = true;
311 shift_interrupted[1] = true;
314 if (!shift_interrupted[1]) {
315 register_code(RSPC_KEY);
316 unregister_code(RSPC_KEY);
318 unregister_mods(MOD_BIT(KC_RSFT));
324 shift_interrupted[0] = true;
325 shift_interrupted[1] = true;
330 return process_action_kb(record);
333 const bool ascii_to_qwerty_shift_lut[0x80] PROGMEM = {
334 0, 0, 0, 0, 0, 0, 0, 0,
335 0, 0, 0, 0, 0, 0, 0, 0,
336 0, 0, 0, 0, 0, 0, 0, 0,
337 0, 0, 0, 0, 0, 0, 0, 0,
338 0, 1, 1, 1, 1, 1, 1, 0,
339 1, 1, 1, 1, 0, 0, 0, 0,
340 0, 0, 0, 0, 0, 0, 0, 0,
341 0, 0, 1, 0, 1, 0, 1, 1,
342 1, 1, 1, 1, 1, 1, 1, 1,
343 1, 1, 1, 1, 1, 1, 1, 1,
344 1, 1, 1, 1, 1, 1, 1, 1,
345 1, 1, 1, 0, 0, 0, 1, 1,
346 0, 0, 0, 0, 0, 0, 0, 0,
347 0, 0, 0, 0, 0, 0, 0, 0,
348 0, 0, 0, 0, 0, 0, 0, 0,
349 0, 0, 0, 1, 1, 1, 1, 0
352 const uint8_t ascii_to_qwerty_keycode_lut[0x80] PROGMEM = {
353 0, 0, 0, 0, 0, 0, 0, 0,
354 KC_BSPC, KC_TAB, KC_ENT, 0, 0, 0, 0, 0,
355 0, 0, 0, 0, 0, 0, 0, 0,
356 0, 0, 0, KC_ESC, 0, 0, 0, 0,
357 KC_SPC, KC_1, KC_QUOT, KC_3, KC_4, KC_5, KC_7, KC_QUOT,
358 KC_9, KC_0, KC_8, KC_EQL, KC_COMM, KC_MINS, KC_DOT, KC_SLSH,
359 KC_0, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7,
360 KC_8, KC_9, KC_SCLN, KC_SCLN, KC_COMM, KC_EQL, KC_DOT, KC_SLSH,
361 KC_2, KC_A, KC_B, KC_C, KC_D, KC_E, KC_F, KC_G,
362 KC_H, KC_I, KC_J, KC_K, KC_L, KC_M, KC_N, KC_O,
363 KC_P, KC_Q, KC_R, KC_S, KC_T, KC_U, KC_V, KC_W,
364 KC_X, KC_Y, KC_Z, KC_LBRC, KC_BSLS, KC_RBRC, KC_6, KC_MINS,
365 KC_GRV, KC_A, KC_B, KC_C, KC_D, KC_E, KC_F, KC_G,
366 KC_H, KC_I, KC_J, KC_K, KC_L, KC_M, KC_N, KC_O,
367 KC_P, KC_Q, KC_R, KC_S, KC_T, KC_U, KC_V, KC_W,
368 KC_X, KC_Y, KC_Z, KC_LBRC, KC_BSLS, KC_RBRC, KC_GRV, KC_DEL
371 /* for users whose OSes are set to Colemak */
373 #include "keymap_colemak.h"
375 const bool ascii_to_colemak_shift_lut[0x80] PROGMEM = {
376 0, 0, 0, 0, 0, 0, 0, 0,
377 0, 0, 0, 0, 0, 0, 0, 0,
378 0, 0, 0, 0, 0, 0, 0, 0,
379 0, 0, 0, 0, 0, 0, 0, 0,
380 0, 1, 1, 1, 1, 1, 1, 0,
381 1, 1, 1, 1, 0, 0, 0, 0,
382 0, 0, 0, 0, 0, 0, 0, 0,
383 0, 0, 1, 0, 1, 0, 1, 1,
384 1, 1, 1, 1, 1, 1, 1, 1,
385 1, 1, 1, 1, 1, 1, 1, 1,
386 1, 1, 1, 1, 1, 1, 1, 1,
387 1, 1, 1, 0, 0, 0, 1, 1,
388 0, 0, 0, 0, 0, 0, 0, 0,
389 0, 0, 0, 0, 0, 0, 0, 0,
390 0, 0, 0, 0, 0, 0, 0, 0,
391 0, 0, 0, 1, 1, 1, 1, 0
394 const uint8_t ascii_to_colemak_keycode_lut[0x80] PROGMEM = {
395 0, 0, 0, 0, 0, 0, 0, 0,
396 KC_BSPC, KC_TAB, KC_ENT, 0, 0, 0, 0, 0,
397 0, 0, 0, 0, 0, 0, 0, 0,
398 0, 0, 0, KC_ESC, 0, 0, 0, 0,
399 KC_SPC, KC_1, KC_QUOT, KC_3, KC_4, KC_5, KC_7, KC_QUOT,
400 KC_9, KC_0, KC_8, KC_EQL, KC_COMM, KC_MINS, KC_DOT, KC_SLSH,
401 KC_0, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7,
402 KC_8, KC_9, CM_SCLN, CM_SCLN, KC_COMM, KC_EQL, KC_DOT, KC_SLSH,
403 KC_2, CM_A, CM_B, CM_C, CM_D, CM_E, CM_F, CM_G,
404 CM_H, CM_I, CM_J, CM_K, CM_L, CM_M, CM_N, CM_O,
405 CM_P, CM_Q, CM_R, CM_S, CM_T, CM_U, CM_V, CM_W,
406 CM_X, CM_Y, CM_Z, KC_LBRC, KC_BSLS, KC_RBRC, KC_6, KC_MINS,
407 KC_GRV, CM_A, CM_B, CM_C, CM_D, CM_E, CM_F, CM_G,
408 CM_H, CM_I, CM_J, CM_K, CM_L, CM_M, CM_N, CM_O,
409 CM_P, CM_Q, CM_R, CM_S, CM_T, CM_U, CM_V, CM_W,
410 CM_X, CM_Y, CM_Z, KC_LBRC, KC_BSLS, KC_RBRC, KC_GRV, KC_DEL
415 void send_string(const char *str) {
418 uint8_t ascii_code = pgm_read_byte(str);
419 if (!ascii_code) break;
420 keycode = pgm_read_byte(&ascii_to_qwerty_keycode_lut[ascii_code]);
421 if (pgm_read_byte(&ascii_to_qwerty_shift_lut[ascii_code])) {
422 register_code(KC_LSFT);
423 register_code(keycode);
424 unregister_code(keycode);
425 unregister_code(KC_LSFT);
428 register_code(keycode);
429 unregister_code(keycode);
435 void update_tri_layer(uint8_t layer1, uint8_t layer2, uint8_t layer3) {
436 if (IS_LAYER_ON(layer1) && IS_LAYER_ON(layer2)) {
443 void tap_random_base64(void) {
444 #if defined(__AVR_ATmega32U4__)
445 uint8_t key = (TCNT0 + TCNT1 + TCNT3 + TCNT4) % 64;
447 uint8_t key = rand() % 64;
451 register_code(KC_LSFT);
452 register_code(key + KC_A);
453 unregister_code(key + KC_A);
454 unregister_code(KC_LSFT);
457 register_code(key - 26 + KC_A);
458 unregister_code(key - 26 + KC_A);
462 unregister_code(KC_0);
465 register_code(key - 53 + KC_1);
466 unregister_code(key - 53 + KC_1);
469 register_code(KC_LSFT);
470 register_code(KC_EQL);
471 unregister_code(KC_EQL);
472 unregister_code(KC_LSFT);
475 register_code(KC_SLSH);
476 unregister_code(KC_SLSH);
481 void matrix_init_quantum() {
482 #ifdef BACKLIGHT_ENABLE
483 backlight_init_ports();
488 void matrix_scan_quantum() {
493 #ifdef TAP_DANCE_ENABLE
494 matrix_scan_tap_dance();
499 #if defined(BACKLIGHT_ENABLE) && defined(BACKLIGHT_PIN)
501 static const uint8_t backlight_pin = BACKLIGHT_PIN;
503 #if BACKLIGHT_PIN == B7
504 # define COM1x1 COM1C1
506 #elif BACKLIGHT_PIN == B6
507 # define COM1x1 COM1B1
509 #elif BACKLIGHT_PIN == B5
510 # define COM1x1 COM1A1
513 # error "Backlight pin not supported - use B5, B6, or B7"
516 __attribute__ ((weak))
517 void backlight_init_ports(void)
520 // Setup backlight pin as output and output low.
522 _SFR_IO8((backlight_pin >> 4) + 1) |= _BV(backlight_pin & 0xF);
524 _SFR_IO8((backlight_pin >> 4) + 2) &= ~_BV(backlight_pin & 0xF);
526 // Use full 16-bit resolution.
529 // I could write a wall of text here to explain... but TL;DW
530 // Go read the ATmega32u4 datasheet.
531 // And this: http://blog.saikoled.com/post/43165849837/secret-konami-cheat-code-to-high-resolution-pwm-on
533 // Pin PB7 = OCR1C (Timer 1, Channel C)
534 // Compare Output Mode = Clear on compare match, Channel C = COM1C1=1 COM1C0=0
535 // (i.e. start high, go low when counter matches.)
536 // WGM Mode 14 (Fast PWM) = WGM13=1 WGM12=1 WGM11=1 WGM10=0
537 // Clock Select = clk/1 (no prescaling) = CS12=0 CS11=0 CS10=1
539 TCCR1A = _BV(COM1x1) | _BV(WGM11); // = 0b00001010;
540 TCCR1B = _BV(WGM13) | _BV(WGM12) | _BV(CS10); // = 0b00011001;
543 #ifdef BACKLIGHT_BREATHING
544 breathing_defaults();
548 __attribute__ ((weak))
549 void backlight_set(uint8_t level)
551 // Prevent backlight blink on lowest level
553 _SFR_IO8((backlight_pin >> 4) + 2) &= ~_BV(backlight_pin & 0xF);
556 // Turn off PWM control on backlight pin, revert to output low.
557 TCCR1A &= ~(_BV(COM1x1));
559 } else if ( level == BACKLIGHT_LEVELS ) {
560 // Turn on PWM control of backlight pin
561 TCCR1A |= _BV(COM1x1);
562 // Set the brightness
565 // Turn on PWM control of backlight pin
566 TCCR1A |= _BV(COM1x1);
567 // Set the brightness
568 OCR1x = 0xFFFF >> ((BACKLIGHT_LEVELS - level) * ((BACKLIGHT_LEVELS + 1) / 2));
571 #ifdef BACKLIGHT_BREATHING
572 breathing_intensity_default();
577 #ifdef BACKLIGHT_BREATHING
579 #define BREATHING_NO_HALT 0
580 #define BREATHING_HALT_OFF 1
581 #define BREATHING_HALT_ON 2
583 static uint8_t breath_intensity;
584 static uint8_t breath_speed;
585 static uint16_t breathing_index;
586 static uint8_t breathing_halt;
588 void breathing_enable(void)
590 if (get_backlight_level() == 0)
596 // Set breathing_index to be at the midpoint (brightest point)
597 breathing_index = 0x20 << breath_speed;
600 breathing_halt = BREATHING_NO_HALT;
602 // Enable breathing interrupt
603 TIMSK1 |= _BV(OCIE1A);
606 void breathing_pulse(void)
608 if (get_backlight_level() == 0)
614 // Set breathing_index to be at the midpoint + 1 (brightest point)
615 breathing_index = 0x21 << breath_speed;
618 breathing_halt = BREATHING_HALT_ON;
620 // Enable breathing interrupt
621 TIMSK1 |= _BV(OCIE1A);
624 void breathing_disable(void)
626 // Disable breathing interrupt
627 TIMSK1 &= ~_BV(OCIE1A);
628 backlight_set(get_backlight_level());
631 void breathing_self_disable(void)
633 if (get_backlight_level() == 0)
635 breathing_halt = BREATHING_HALT_OFF;
639 breathing_halt = BREATHING_HALT_ON;
642 //backlight_set(get_backlight_level());
645 void breathing_toggle(void)
649 if (get_backlight_level() == 0)
655 // Set breathing_index to be at the midpoint + 1 (brightest point)
656 breathing_index = 0x21 << breath_speed;
659 breathing_halt = BREATHING_NO_HALT;
662 // Toggle breathing interrupt
663 TIMSK1 ^= _BV(OCIE1A);
665 // Restore backlight level
668 backlight_set(get_backlight_level());
672 bool is_breathing(void)
674 return (TIMSK1 && _BV(OCIE1A));
677 void breathing_intensity_default(void)
679 //breath_intensity = (uint8_t)((uint16_t)100 * (uint16_t)get_backlight_level() / (uint16_t)BACKLIGHT_LEVELS);
680 breath_intensity = ((BACKLIGHT_LEVELS - get_backlight_level()) * ((BACKLIGHT_LEVELS + 1) / 2));
683 void breathing_intensity_set(uint8_t value)
685 breath_intensity = value;
688 void breathing_speed_default(void)
693 void breathing_speed_set(uint8_t value)
695 bool is_breathing_now = is_breathing();
696 uint8_t old_breath_speed = breath_speed;
698 if (is_breathing_now)
700 // Disable breathing interrupt
701 TIMSK1 &= ~_BV(OCIE1A);
704 breath_speed = value;
706 if (is_breathing_now)
708 // Adjust index to account for new speed
709 breathing_index = (( (uint8_t)( (breathing_index) >> old_breath_speed ) ) & 0x3F) << breath_speed;
711 // Enable breathing interrupt
712 TIMSK1 |= _BV(OCIE1A);
717 void breathing_speed_inc(uint8_t value)
719 if ((uint16_t)(breath_speed - value) > 10 )
721 breathing_speed_set(0);
725 breathing_speed_set(breath_speed - value);
729 void breathing_speed_dec(uint8_t value)
731 if ((uint16_t)(breath_speed + value) > 10 )
733 breathing_speed_set(10);
737 breathing_speed_set(breath_speed + value);
741 void breathing_defaults(void)
743 breathing_intensity_default();
744 breathing_speed_default();
745 breathing_halt = BREATHING_NO_HALT;
748 /* Breathing Sleep LED brighness(PWM On period) table
749 * (64[steps] * 4[duration]) / 64[PWM periods/s] = 4 second breath cycle
751 * http://www.wolframalpha.com/input/?i=%28sin%28+x%2F64*pi%29**8+*+255%2C+x%3D0+to+63
752 * (0..63).each {|x| p ((sin(x/64.0*PI)**8)*255).to_i }
754 static const uint8_t breathing_table[64] PROGMEM = {
755 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 4, 6, 10,
756 15, 23, 32, 44, 58, 74, 93, 113, 135, 157, 179, 199, 218, 233, 245, 252,
757 255, 252, 245, 233, 218, 199, 179, 157, 135, 113, 93, 74, 58, 44, 32, 23,
758 15, 10, 6, 4, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
761 ISR(TIMER1_COMPA_vect)
763 // OCR1x = (pgm_read_byte(&breathing_table[ ( (uint8_t)( (breathing_index++) >> breath_speed ) ) & 0x3F ] )) * breath_intensity;
766 uint8_t local_index = ( (uint8_t)( (breathing_index++) >> breath_speed ) ) & 0x3F;
768 if (((breathing_halt == BREATHING_HALT_ON) && (local_index == 0x20)) || ((breathing_halt == BREATHING_HALT_OFF) && (local_index == 0x3F)))
770 // Disable breathing interrupt
771 TIMSK1 &= ~_BV(OCIE1A);
774 OCR1x = (uint16_t)(((uint16_t)pgm_read_byte(&breathing_table[local_index]) * 257)) >> breath_intensity;
784 __attribute__ ((weak))
785 void backlight_init_ports(void)
790 __attribute__ ((weak))
791 void backlight_set(uint8_t level)
800 __attribute__ ((weak))
801 void led_set_user(uint8_t usb_led) {
805 __attribute__ ((weak))
806 void led_set_kb(uint8_t usb_led) {
807 led_set_user(usb_led);
810 __attribute__ ((weak))
811 void led_init_ports(void)
816 __attribute__ ((weak))
817 void led_set(uint8_t usb_led)
822 // // Using PE6 Caps Lock LED
823 // if (usb_led & (1<<USB_LED_CAPS_LOCK))
840 //------------------------------------------------------------------------------
841 // Override these functions in your keymap file to play different tunes on
842 // different events such as startup and bootloader jump
844 __attribute__ ((weak))
845 void startup_user() {}
847 __attribute__ ((weak))
848 void shutdown_user() {}
850 //------------------------------------------------------------------------------