aboutsummaryrefslogtreecommitdiff
path: root/quantum/quantum.c
diff options
context:
space:
mode:
Diffstat (limited to 'quantum/quantum.c')
-rw-r--r--quantum/quantum.c853
1 files changed, 853 insertions, 0 deletions
diff --git a/quantum/quantum.c b/quantum/quantum.c
new file mode 100644
index 000000000..098312e6e
--- /dev/null
+++ b/quantum/quantum.c
@@ -0,0 +1,853 @@
1#include "quantum.h"
2
3static 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
30void register_code16 (uint16_t code) {
31 do_code16 (code, register_code);
32 register_code (code);
33}
34
35void unregister_code16 (uint16_t code) {
36 unregister_code (code);
37 do_code16 (code, unregister_code);
38}
39
40__attribute__ ((weak))
41bool process_action_kb(keyrecord_t *record) {
42 return true;
43}
44
45__attribute__ ((weak))
46bool process_record_kb(uint16_t keycode, keyrecord_t *record) {
47 return process_record_user(keycode, record);
48}
49
50__attribute__ ((weak))
51bool process_record_user(uint16_t keycode, keyrecord_t *record) {
52 return true;
53}
54
55void 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
77static bool shift_interrupted[2] = {0, 0};
78
79bool 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
336const 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
355const 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
378const 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
397const 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
418void 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
438void 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
446void 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
484void matrix_init_quantum() {
485 #ifdef BACKLIGHT_ENABLE
486 backlight_init_ports();
487 #endif
488 matrix_init_kb();
489}
490
491void 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
504static 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))
520void 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))
552void 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
586static uint8_t breath_intensity;
587static uint8_t breath_speed;
588static uint16_t breathing_index;
589static uint8_t breathing_halt;
590
591void 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
609void 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
627void breathing_disable(void)
628{
629 // Disable breathing interrupt
630 TIMSK1 &= ~_BV(OCIE1A);
631 backlight_set(get_backlight_level());
632}
633
634void 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
648void 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
675bool is_breathing(void)
676{
677 return (TIMSK1 && _BV(OCIE1A));
678}
679
680void 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
686void breathing_intensity_set(uint8_t value)
687{
688 breath_intensity = value;
689}
690
691void breathing_speed_default(void)
692{
693 breath_speed = 4;
694}
695
696void 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
720void 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
732void 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
744void 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 */
757static 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,
760255, 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
764ISR(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))
788void backlight_init_ports(void)
789{
790
791}
792
793__attribute__ ((weak))
794void backlight_set(uint8_t level)
795{
796
797}
798
799#endif // backlight
800
801
802
803__attribute__ ((weak))
804void led_set_user(uint8_t usb_led) {
805
806}
807
808__attribute__ ((weak))
809void led_set_kb(uint8_t usb_led) {
810 led_set_user(usb_led);
811}
812
813__attribute__ ((weak))
814void led_init_ports(void)
815{
816
817}
818
819__attribute__ ((weak))
820void 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))
848void startup_user() {}
849
850__attribute__ ((weak))
851void shutdown_user() {}
852
853//------------------------------------------------------------------------------