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