fixed indentation.
[jackhill/qmk/firmware.git] / quantum / quantum.c
CommitLineData
1a8c0dd2
EZ
1#include "quantum.h"
2
3__attribute__ ((weak))
1a8c0dd2
EZ
4bool process_action_kb(keyrecord_t *record) {
5 return true;
6}
7
17977a7e
JH
8__attribute__ ((weak))
9bool process_record_kb(uint16_t keycode, keyrecord_t *record) {
10 return process_record_user(keycode, record);
11}
12
13__attribute__ ((weak))
14bool process_record_user(uint16_t keycode, keyrecord_t *record) {
15 return true;
16}
17
b70248fa
JH
18// Shift / paren setup
19
20#ifndef LSPO_KEY
21 #define LSPO_KEY KC_9
22#endif
23#ifndef RSPC_KEY
24 #define RSPC_KEY KC_0
25#endif
26
8bc69afc 27static bool shift_interrupted[2] = {0, 0};
12370259 28
bf5c2cce 29bool process_record_quantum(keyrecord_t *record) {
1a8c0dd2
EZ
30
31 /* This gets the keycode from the key pressed */
32 keypos_t key = record->event.key;
33 uint16_t keycode;
34
35 #if !defined(NO_ACTION_LAYER) && defined(PREVENT_STUCK_MODIFIERS)
36 uint8_t layer;
37
38 if (record->event.pressed) {
39 layer = layer_switch_get_layer(key);
40 update_source_layers_cache(key, layer);
41 } else {
42 layer = read_source_layers_cache(key);
43 }
44 keycode = keymap_key_to_keycode(layer, key);
45 #else
46 keycode = keymap_key_to_keycode(layer_switch_get_layer(key), key);
47 #endif
48
bf5c2cce
JH
49 // This is how you use actions here
50 // if (keycode == KC_LEAD) {
51 // action_t action;
52 // action.code = ACTION_DEFAULT_LAYER_SET(0);
53 // process_action(record, action);
54 // return false;
55 // }
56
65faab3b
JH
57 if (!(
58 process_record_kb(keycode, record) &&
fde477a9 59 #ifdef MIDI_ENABLE
65faab3b 60 process_midi(keycode, record) &&
fde477a9 61 #endif
1a8c0dd2 62 #ifdef AUDIO_ENABLE
65faab3b 63 process_music(keycode, record) &&
1a8c0dd2 64 #endif
65faab3b
JH
65 #ifdef TAP_DANCE_ENABLE
66 process_tap_dance(keycode, record) &&
67 #endif
68 #ifndef DISABLE_LEADER
69 process_leader(keycode, record) &&
70 #endif
71 #ifndef DISABLE_CHORDING
72 process_chording(keycode, record) &&
73 #endif
74 #ifdef UNICODE_ENABLE
75 process_unicode(keycode, record) &&
76 #endif
77 true)) {
78 return false;
b732b79b
JH
79 }
80
b70248fa
JH
81 // Shift / paren setup
82
12370259 83 switch(keycode) {
db32864c
JH
84 case RESET:
85 if (record->event.pressed) {
86 clear_keyboard();
87 #ifdef AUDIO_ENABLE
88 stop_all_notes();
89 shutdown_user();
90 #endif
4d4f7684 91 wait_ms(250);
db32864c
JH
92 #ifdef ATREUS_ASTAR
93 *(uint16_t *)0x0800 = 0x7777; // these two are a-star-specific
94 #endif
95 bootloader_jump();
96 return false;
97 }
98 break;
99 case DEBUG:
100 if (record->event.pressed) {
101 print("\nDEBUG: enabled.\n");
102 debug_enable = true;
103 return false;
104 }
105 break;
106 case MAGIC_SWAP_CONTROL_CAPSLOCK ... MAGIC_UNSWAP_ALT_GUI:
107 if (record->event.pressed) {
108 // MAGIC actions (BOOTMAGIC without the boot)
109 if (!eeconfig_is_enabled()) {
110 eeconfig_init();
111 }
112 /* keymap config */
113 keymap_config.raw = eeconfig_read_keymap();
114 if (keycode == MAGIC_SWAP_CONTROL_CAPSLOCK) {
115 keymap_config.swap_control_capslock = 1;
116 } else if (keycode == MAGIC_CAPSLOCK_TO_CONTROL) {
117 keymap_config.capslock_to_control = 1;
118 } else if (keycode == MAGIC_SWAP_LALT_LGUI) {
119 keymap_config.swap_lalt_lgui = 1;
120 } else if (keycode == MAGIC_SWAP_RALT_RGUI) {
121 keymap_config.swap_ralt_rgui = 1;
122 } else if (keycode == MAGIC_NO_GUI) {
123 keymap_config.no_gui = 1;
124 } else if (keycode == MAGIC_SWAP_GRAVE_ESC) {
125 keymap_config.swap_grave_esc = 1;
126 } else if (keycode == MAGIC_SWAP_BACKSLASH_BACKSPACE) {
127 keymap_config.swap_backslash_backspace = 1;
128 } else if (keycode == MAGIC_HOST_NKRO) {
129 keymap_config.nkro = 1;
130 } else if (keycode == MAGIC_SWAP_ALT_GUI) {
131 keymap_config.swap_lalt_lgui = 1;
132 keymap_config.swap_ralt_rgui = 1;
133 }
134 /* UNs */
135 else if (keycode == MAGIC_UNSWAP_CONTROL_CAPSLOCK) {
136 keymap_config.swap_control_capslock = 0;
137 } else if (keycode == MAGIC_UNCAPSLOCK_TO_CONTROL) {
138 keymap_config.capslock_to_control = 0;
139 } else if (keycode == MAGIC_UNSWAP_LALT_LGUI) {
140 keymap_config.swap_lalt_lgui = 0;
141 } else if (keycode == MAGIC_UNSWAP_RALT_RGUI) {
142 keymap_config.swap_ralt_rgui = 0;
143 } else if (keycode == MAGIC_UNNO_GUI) {
144 keymap_config.no_gui = 0;
145 } else if (keycode == MAGIC_UNSWAP_GRAVE_ESC) {
146 keymap_config.swap_grave_esc = 0;
147 } else if (keycode == MAGIC_UNSWAP_BACKSLASH_BACKSPACE) {
148 keymap_config.swap_backslash_backspace = 0;
149 } else if (keycode == MAGIC_UNHOST_NKRO) {
150 keymap_config.nkro = 0;
151 } else if (keycode == MAGIC_UNSWAP_ALT_GUI) {
152 keymap_config.swap_lalt_lgui = 0;
153 keymap_config.swap_ralt_rgui = 0;
154 }
155 eeconfig_update_keymap(keymap_config.raw);
156 return false;
157 }
158 break;
12370259 159 case KC_LSPO: {
db32864c
JH
160 if (record->event.pressed) {
161 shift_interrupted[0] = false;
76076db7 162 register_mods(MOD_BIT(KC_LSFT));
db32864c
JH
163 }
164 else {
6b0c9cc9
S
165 if (get_mods() & MOD_BIT(KC_RSFT)) {
166 shift_interrupted[0] = true;
167 shift_interrupted[1] = true;
168 }
db32864c
JH
169 if (!shift_interrupted[0]) {
170 register_code(LSPO_KEY);
171 unregister_code(LSPO_KEY);
172 }
76076db7 173 unregister_mods(MOD_BIT(KC_LSFT));
db32864c
JH
174 }
175 return false;
176 break;
177 }
12370259
EZ
178
179 case KC_RSPC: {
db32864c
JH
180 if (record->event.pressed) {
181 shift_interrupted[1] = false;
76076db7 182 register_mods(MOD_BIT(KC_RSFT));
db32864c
JH
183 }
184 else {
6b0c9cc9
S
185 if (get_mods() & MOD_BIT(KC_LSFT)) {
186 shift_interrupted[0] = true;
187 shift_interrupted[1] = true;
188 }
db32864c
JH
189 if (!shift_interrupted[1]) {
190 register_code(RSPC_KEY);
191 unregister_code(RSPC_KEY);
192 }
76076db7 193 unregister_mods(MOD_BIT(KC_RSFT));
db32864c
JH
194 }
195 return false;
196 break;
197 }
12370259 198 default: {
db32864c
JH
199 shift_interrupted[0] = true;
200 shift_interrupted[1] = true;
201 break;
202 }
12370259
EZ
203 }
204
1a8c0dd2
EZ
205 return process_action_kb(record);
206}
207
794aed37
ET
208const bool ascii_to_qwerty_shift_lut[0x80] PROGMEM = {
209 0, 0, 0, 0, 0, 0, 0, 0,
210 0, 0, 0, 0, 0, 0, 0, 0,
211 0, 0, 0, 0, 0, 0, 0, 0,
212 0, 0, 0, 0, 0, 0, 0, 0,
213 0, 1, 1, 1, 1, 1, 1, 0,
214 1, 1, 1, 1, 0, 0, 0, 0,
215 0, 0, 0, 0, 0, 0, 0, 0,
216 0, 0, 1, 0, 1, 0, 1, 1,
217 1, 1, 1, 1, 1, 1, 1, 1,
218 1, 1, 1, 1, 1, 1, 1, 1,
219 1, 1, 1, 1, 1, 1, 1, 1,
220 1, 1, 1, 0, 0, 0, 1, 1,
221 0, 0, 0, 0, 0, 0, 0, 0,
222 0, 0, 0, 0, 0, 0, 0, 0,
223 0, 0, 0, 0, 0, 0, 0, 0,
224 0, 0, 0, 1, 1, 1, 1, 0
1c9f33c0
JH
225};
226
794aed37
ET
227const uint8_t ascii_to_qwerty_keycode_lut[0x80] PROGMEM = {
228 0, 0, 0, 0, 0, 0, 0, 0,
229 KC_BSPC, KC_TAB, KC_ENT, 0, 0, 0, 0, 0,
230 0, 0, 0, 0, 0, 0, 0, 0,
231 0, 0, 0, KC_ESC, 0, 0, 0, 0,
232 KC_SPC, KC_1, KC_QUOT, KC_3, KC_4, KC_5, KC_7, KC_QUOT,
233 KC_9, KC_0, KC_8, KC_EQL, KC_COMM, KC_MINS, KC_DOT, KC_SLSH,
234 KC_0, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7,
235 KC_8, KC_9, KC_SCLN, KC_SCLN, KC_COMM, KC_EQL, KC_DOT, KC_SLSH,
236 KC_2, KC_A, KC_B, KC_C, KC_D, KC_E, KC_F, KC_G,
237 KC_H, KC_I, KC_J, KC_K, KC_L, KC_M, KC_N, KC_O,
238 KC_P, KC_Q, KC_R, KC_S, KC_T, KC_U, KC_V, KC_W,
239 KC_X, KC_Y, KC_Z, KC_LBRC, KC_BSLS, KC_RBRC, KC_6, KC_MINS,
240 KC_GRV, KC_A, KC_B, KC_C, KC_D, KC_E, KC_F, KC_G,
241 KC_H, KC_I, KC_J, KC_K, KC_L, KC_M, KC_N, KC_O,
242 KC_P, KC_Q, KC_R, KC_S, KC_T, KC_U, KC_V, KC_W,
243 KC_X, KC_Y, KC_Z, KC_LBRC, KC_BSLS, KC_RBRC, KC_GRV, KC_DEL
1c9f33c0
JH
244};
245
794aed37
ET
246/* for users whose OSes are set to Colemak */
247#if 0
248#include "keymap_colemak.h"
249
250const bool ascii_to_colemak_shift_lut[0x80] PROGMEM = {
251 0, 0, 0, 0, 0, 0, 0, 0,
252 0, 0, 0, 0, 0, 0, 0, 0,
253 0, 0, 0, 0, 0, 0, 0, 0,
254 0, 0, 0, 0, 0, 0, 0, 0,
255 0, 1, 1, 1, 1, 1, 1, 0,
256 1, 1, 1, 1, 0, 0, 0, 0,
257 0, 0, 0, 0, 0, 0, 0, 0,
258 0, 0, 1, 0, 1, 0, 1, 1,
259 1, 1, 1, 1, 1, 1, 1, 1,
260 1, 1, 1, 1, 1, 1, 1, 1,
261 1, 1, 1, 1, 1, 1, 1, 1,
262 1, 1, 1, 0, 0, 0, 1, 1,
263 0, 0, 0, 0, 0, 0, 0, 0,
264 0, 0, 0, 0, 0, 0, 0, 0,
265 0, 0, 0, 0, 0, 0, 0, 0,
266 0, 0, 0, 1, 1, 1, 1, 0
267};
268
269const uint8_t ascii_to_colemak_keycode_lut[0x80] PROGMEM = {
270 0, 0, 0, 0, 0, 0, 0, 0,
271 KC_BSPC, KC_TAB, KC_ENT, 0, 0, 0, 0, 0,
272 0, 0, 0, 0, 0, 0, 0, 0,
273 0, 0, 0, KC_ESC, 0, 0, 0, 0,
274 KC_SPC, KC_1, KC_QUOT, KC_3, KC_4, KC_5, KC_7, KC_QUOT,
275 KC_9, KC_0, KC_8, KC_EQL, KC_COMM, KC_MINS, KC_DOT, KC_SLSH,
276 KC_0, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7,
277 KC_8, KC_9, CM_SCLN, CM_SCLN, KC_COMM, KC_EQL, KC_DOT, KC_SLSH,
278 KC_2, CM_A, CM_B, CM_C, CM_D, CM_E, CM_F, CM_G,
279 CM_H, CM_I, CM_J, CM_K, CM_L, CM_M, CM_N, CM_O,
280 CM_P, CM_Q, CM_R, CM_S, CM_T, CM_U, CM_V, CM_W,
281 CM_X, CM_Y, CM_Z, KC_LBRC, KC_BSLS, KC_RBRC, KC_6, KC_MINS,
282 KC_GRV, CM_A, CM_B, CM_C, CM_D, CM_E, CM_F, CM_G,
283 CM_H, CM_I, CM_J, CM_K, CM_L, CM_M, CM_N, CM_O,
284 CM_P, CM_Q, CM_R, CM_S, CM_T, CM_U, CM_V, CM_W,
285 CM_X, CM_Y, CM_Z, KC_LBRC, KC_BSLS, KC_RBRC, KC_GRV, KC_DEL
286};
287
288#endif
289
290void send_string(const char *str) {
291 while (1) {
292 uint8_t keycode;
293 uint8_t ascii_code = pgm_read_byte(str);
294 if (!ascii_code) break;
295 keycode = pgm_read_byte(&ascii_to_qwerty_keycode_lut[ascii_code]);
296 if (pgm_read_byte(&ascii_to_qwerty_shift_lut[ascii_code])) {
297 register_code(KC_LSFT);
298 register_code(keycode);
299 unregister_code(keycode);
300 unregister_code(KC_LSFT);
301 }
302 else {
303 register_code(keycode);
304 unregister_code(keycode);
305 }
306 ++str;
1c9f33c0 307 }
1c9f33c0
JH
308}
309
db32864c
JH
310void update_tri_layer(uint8_t layer1, uint8_t layer2, uint8_t layer3) {
311 if (IS_LAYER_ON(layer1) && IS_LAYER_ON(layer2)) {
312 layer_on(layer3);
313 } else {
314 layer_off(layer3);
315 }
316}
1c9f33c0 317
197f152d 318void tap_random_base64(void) {
60fd885a
JH
319 #if defined(__AVR_ATmega32U4__)
320 uint8_t key = (TCNT0 + TCNT1 + TCNT3 + TCNT4) % 64;
321 #else
322 uint8_t key = rand() % 64;
323 #endif
197f152d
JH
324 switch (key) {
325 case 0 ... 25:
326 register_code(KC_LSFT);
327 register_code(key + KC_A);
328 unregister_code(key + KC_A);
329 unregister_code(KC_LSFT);
330 break;
331 case 26 ... 51:
332 register_code(key - 26 + KC_A);
333 unregister_code(key - 26 + KC_A);
334 break;
335 case 52:
336 register_code(KC_0);
337 unregister_code(KC_0);
338 break;
339 case 53 ... 61:
340 register_code(key - 53 + KC_1);
341 unregister_code(key - 53 + KC_1);
342 break;
343 case 62:
344 register_code(KC_LSFT);
345 register_code(KC_EQL);
346 unregister_code(KC_EQL);
347 unregister_code(KC_LSFT);
348 break;
349 case 63:
350 register_code(KC_SLSH);
351 unregister_code(KC_SLSH);
352 break;
353 }
354}
355
1a8c0dd2 356void matrix_init_quantum() {
13bb6b4b
JH
357 #ifdef BACKLIGHT_ENABLE
358 backlight_init_ports();
359 #endif
1a8c0dd2
EZ
360 matrix_init_kb();
361}
362
363void matrix_scan_quantum() {
15719f35 364 #ifdef AUDIO_ENABLE
65faab3b 365 matrix_scan_music();
15719f35 366 #endif
fde477a9 367
65faab3b
JH
368 #ifdef TAP_DANCE_ENABLE
369 matrix_scan_tap_dance();
370 #endif
1a8c0dd2 371 matrix_scan_kb();
0428214b 372}
13bb6b4b 373
13bb6b4b
JH
374#if defined(BACKLIGHT_ENABLE) && defined(BACKLIGHT_PIN)
375
376static const uint8_t backlight_pin = BACKLIGHT_PIN;
377
378#if BACKLIGHT_PIN == B7
379# define COM1x1 COM1C1
380# define OCR1x OCR1C
381#elif BACKLIGHT_PIN == B6
382# define COM1x1 COM1B1
383# define OCR1x OCR1B
384#elif BACKLIGHT_PIN == B5
385# define COM1x1 COM1A1
386# define OCR1x OCR1A
387#else
388# error "Backlight pin not supported - use B5, B6, or B7"
389#endif
390
391__attribute__ ((weak))
392void backlight_init_ports(void)
393{
394
395 // Setup backlight pin as output and output low.
396 // DDRx |= n
397 _SFR_IO8((backlight_pin >> 4) + 1) |= _BV(backlight_pin & 0xF);
398 // PORTx &= ~n
399 _SFR_IO8((backlight_pin >> 4) + 2) &= ~_BV(backlight_pin & 0xF);
400
401 // Use full 16-bit resolution.
402 ICR1 = 0xFFFF;
403
404 // I could write a wall of text here to explain... but TL;DW
405 // Go read the ATmega32u4 datasheet.
406 // And this: http://blog.saikoled.com/post/43165849837/secret-konami-cheat-code-to-high-resolution-pwm-on
407
408 // Pin PB7 = OCR1C (Timer 1, Channel C)
409 // Compare Output Mode = Clear on compare match, Channel C = COM1C1=1 COM1C0=0
410 // (i.e. start high, go low when counter matches.)
411 // WGM Mode 14 (Fast PWM) = WGM13=1 WGM12=1 WGM11=1 WGM10=0
412 // Clock Select = clk/1 (no prescaling) = CS12=0 CS11=0 CS10=1
413
414 TCCR1A = _BV(COM1x1) | _BV(WGM11); // = 0b00001010;
415 TCCR1B = _BV(WGM13) | _BV(WGM12) | _BV(CS10); // = 0b00011001;
416
417 backlight_init();
418 #ifdef BACKLIGHT_BREATHING
419 breathing_defaults();
420 #endif
421}
422
423__attribute__ ((weak))
424void backlight_set(uint8_t level)
425{
426 // Prevent backlight blink on lowest level
427 // PORTx &= ~n
428 _SFR_IO8((backlight_pin >> 4) + 2) &= ~_BV(backlight_pin & 0xF);
429
430 if ( level == 0 ) {
431 // Turn off PWM control on backlight pin, revert to output low.
432 TCCR1A &= ~(_BV(COM1x1));
433 OCR1x = 0x0;
434 } else if ( level == BACKLIGHT_LEVELS ) {
435 // Turn on PWM control of backlight pin
436 TCCR1A |= _BV(COM1x1);
437 // Set the brightness
438 OCR1x = 0xFFFF;
439 } else {
440 // Turn on PWM control of backlight pin
441 TCCR1A |= _BV(COM1x1);
442 // Set the brightness
443 OCR1x = 0xFFFF >> ((BACKLIGHT_LEVELS - level) * ((BACKLIGHT_LEVELS + 1) / 2));
444 }
445
446 #ifdef BACKLIGHT_BREATHING
447 breathing_intensity_default();
448 #endif
449}
450
451
452#ifdef BACKLIGHT_BREATHING
453
454#define BREATHING_NO_HALT 0
455#define BREATHING_HALT_OFF 1
456#define BREATHING_HALT_ON 2
457
458static uint8_t breath_intensity;
459static uint8_t breath_speed;
460static uint16_t breathing_index;
461static uint8_t breathing_halt;
462
463void breathing_enable(void)
464{
465 if (get_backlight_level() == 0)
466 {
467 breathing_index = 0;
468 }
469 else
470 {
471 // Set breathing_index to be at the midpoint (brightest point)
472 breathing_index = 0x20 << breath_speed;
473 }
474
475 breathing_halt = BREATHING_NO_HALT;
476
477 // Enable breathing interrupt
478 TIMSK1 |= _BV(OCIE1A);
479}
480
481void breathing_pulse(void)
482{
483 if (get_backlight_level() == 0)
484 {
485 breathing_index = 0;
486 }
487 else
488 {
489 // Set breathing_index to be at the midpoint + 1 (brightest point)
490 breathing_index = 0x21 << breath_speed;
491 }
492
493 breathing_halt = BREATHING_HALT_ON;
494
495 // Enable breathing interrupt
496 TIMSK1 |= _BV(OCIE1A);
497}
498
499void breathing_disable(void)
500{
501 // Disable breathing interrupt
502 TIMSK1 &= ~_BV(OCIE1A);
503 backlight_set(get_backlight_level());
504}
505
506void breathing_self_disable(void)
507{
508 if (get_backlight_level() == 0)
509 {
510 breathing_halt = BREATHING_HALT_OFF;
511 }
512 else
513 {
514 breathing_halt = BREATHING_HALT_ON;
515 }
516
517 //backlight_set(get_backlight_level());
518}
519
520void breathing_toggle(void)
521{
522 if (!is_breathing())
523 {
524 if (get_backlight_level() == 0)
525 {
526 breathing_index = 0;
527 }
528 else
529 {
530 // Set breathing_index to be at the midpoint + 1 (brightest point)
531 breathing_index = 0x21 << breath_speed;
532 }
533
534 breathing_halt = BREATHING_NO_HALT;
535 }
536
537 // Toggle breathing interrupt
538 TIMSK1 ^= _BV(OCIE1A);
539
540 // Restore backlight level
541 if (!is_breathing())
542 {
543 backlight_set(get_backlight_level());
544 }
545}
546
547bool is_breathing(void)
548{
549 return (TIMSK1 && _BV(OCIE1A));
550}
551
552void breathing_intensity_default(void)
553{
554 //breath_intensity = (uint8_t)((uint16_t)100 * (uint16_t)get_backlight_level() / (uint16_t)BACKLIGHT_LEVELS);
555 breath_intensity = ((BACKLIGHT_LEVELS - get_backlight_level()) * ((BACKLIGHT_LEVELS + 1) / 2));
556}
557
558void breathing_intensity_set(uint8_t value)
559{
560 breath_intensity = value;
561}
562
563void breathing_speed_default(void)
564{
565 breath_speed = 4;
566}
567
568void breathing_speed_set(uint8_t value)
569{
570 bool is_breathing_now = is_breathing();
571 uint8_t old_breath_speed = breath_speed;
572
573 if (is_breathing_now)
574 {
575 // Disable breathing interrupt
576 TIMSK1 &= ~_BV(OCIE1A);
577 }
578
579 breath_speed = value;
580
581 if (is_breathing_now)
582 {
583 // Adjust index to account for new speed
584 breathing_index = (( (uint8_t)( (breathing_index) >> old_breath_speed ) ) & 0x3F) << breath_speed;
585
586 // Enable breathing interrupt
587 TIMSK1 |= _BV(OCIE1A);
588 }
589
590}
591
592void breathing_speed_inc(uint8_t value)
593{
594 if ((uint16_t)(breath_speed - value) > 10 )
595 {
596 breathing_speed_set(0);
597 }
598 else
599 {
600 breathing_speed_set(breath_speed - value);
601 }
602}
603
604void breathing_speed_dec(uint8_t value)
605{
606 if ((uint16_t)(breath_speed + value) > 10 )
607 {
608 breathing_speed_set(10);
609 }
610 else
611 {
612 breathing_speed_set(breath_speed + value);
613 }
614}
615
616void breathing_defaults(void)
617{
618 breathing_intensity_default();
619 breathing_speed_default();
620 breathing_halt = BREATHING_NO_HALT;
621}
622
623/* Breathing Sleep LED brighness(PWM On period) table
624 * (64[steps] * 4[duration]) / 64[PWM periods/s] = 4 second breath cycle
625 *
626 * http://www.wolframalpha.com/input/?i=%28sin%28+x%2F64*pi%29**8+*+255%2C+x%3D0+to+63
627 * (0..63).each {|x| p ((sin(x/64.0*PI)**8)*255).to_i }
628 */
629static const uint8_t breathing_table[64] PROGMEM = {
630 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 4, 6, 10,
631 15, 23, 32, 44, 58, 74, 93, 113, 135, 157, 179, 199, 218, 233, 245, 252,
632255, 252, 245, 233, 218, 199, 179, 157, 135, 113, 93, 74, 58, 44, 32, 23,
633 15, 10, 6, 4, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
634};
635
636ISR(TIMER1_COMPA_vect)
637{
638 // OCR1x = (pgm_read_byte(&breathing_table[ ( (uint8_t)( (breathing_index++) >> breath_speed ) ) & 0x3F ] )) * breath_intensity;
639
640
641 uint8_t local_index = ( (uint8_t)( (breathing_index++) >> breath_speed ) ) & 0x3F;
642
643 if (((breathing_halt == BREATHING_HALT_ON) && (local_index == 0x20)) || ((breathing_halt == BREATHING_HALT_OFF) && (local_index == 0x3F)))
644 {
645 // Disable breathing interrupt
646 TIMSK1 &= ~_BV(OCIE1A);
647 }
648
649 OCR1x = (uint16_t)(((uint16_t)pgm_read_byte(&breathing_table[local_index]) * 257)) >> breath_intensity;
650
651}
652
653
654
655#endif // breathing
656
657#else // backlight
658
659__attribute__ ((weak))
660void backlight_init_ports(void)
661{
662
663}
664
665__attribute__ ((weak))
666void backlight_set(uint8_t level)
667{
668
669}
670
671#endif // backlight
672
673
674
675__attribute__ ((weak))
676void led_set_user(uint8_t usb_led) {
677
678}
679
680__attribute__ ((weak))
681void led_set_kb(uint8_t usb_led) {
682 led_set_user(usb_led);
683}
684
685__attribute__ ((weak))
686void led_init_ports(void)
687{
688
689}
690
691__attribute__ ((weak))
692void led_set(uint8_t usb_led)
693{
694
695 // Example LED Code
696 //
697 // // Using PE6 Caps Lock LED
698 // if (usb_led & (1<<USB_LED_CAPS_LOCK))
699 // {
700 // // Output high.
701 // DDRE |= (1<<6);
702 // PORTE |= (1<<6);
703 // }
704 // else
705 // {
706 // // Output low.
707 // DDRE &= ~(1<<6);
708 // PORTE &= ~(1<<6);
709 // }
710
711 led_set_kb(usb_led);
712}
713
714
287eb7ad 715//------------------------------------------------------------------------------
794aed37 716// Override these functions in your keymap file to play different tunes on
287eb7ad
JH
717// different events such as startup and bootloader jump
718
719__attribute__ ((weak))
720void startup_user() {}
721
722__attribute__ ((weak))
723void shutdown_user() {}
724
12370259 725//------------------------------------------------------------------------------