aboutsummaryrefslogtreecommitdiff
path: root/quantum
diff options
context:
space:
mode:
authorLuiz Ribeiro <luizribeiro@gmail.com>2017-07-04 11:17:28 -0400
committerLuiz Ribeiro <luizribeiro@gmail.com>2017-07-04 11:17:28 -0400
commitd5486265b8afcada68306c815b08c225fce287af (patch)
tree8fb7f8fee4aa3937003bd69d5c77ca867c010d12 /quantum
parent738b072bb0f25d0369a998c550c369e4f64cc7a5 (diff)
parent34c8bf47a76c8a2dcd3b1a19dd608f8fb2fafb31 (diff)
downloadqmk_firmware-d5486265b8afcada68306c815b08c225fce287af.tar.gz
qmk_firmware-d5486265b8afcada68306c815b08c225fce287af.zip
Merge branch 'master' into ps2avrGB
Diffstat (limited to 'quantum')
-rw-r--r--quantum/audio/audio.c317
-rw-r--r--quantum/audio/voices.c2
-rw-r--r--quantum/keycode_config.c28
-rw-r--r--quantum/keycode_config.h2
-rw-r--r--quantum/keymap_common.c3
-rw-r--r--quantum/keymap_extras/keymap_spanish.h6
-rw-r--r--quantum/keymap_extras/keymap_swedish.h52
-rw-r--r--quantum/quantum.c150
-rw-r--r--quantum/quantum_keycodes.h7
-rw-r--r--quantum/template/rules.mk2
-rw-r--r--quantum/visualizer/lcd_backlight.c4
-rw-r--r--quantum/visualizer/lcd_backlight.h3
-rw-r--r--quantum/visualizer/led_keyframes.c20
-rw-r--r--quantum/visualizer/led_keyframes.h3
-rw-r--r--quantum/visualizer/visualizer.c67
-rw-r--r--quantum/visualizer/visualizer.h10
-rw-r--r--quantum/visualizer/visualizer.mk29
17 files changed, 620 insertions, 85 deletions
diff --git a/quantum/audio/audio.c b/quantum/audio/audio.c
index 597073611..c924f2bd5 100644
--- a/quantum/audio/audio.c
+++ b/quantum/audio/audio.c
@@ -33,17 +33,41 @@
33 33
34// TIMSK3 - Timer/Counter #3 Interrupt Mask Register 34// TIMSK3 - Timer/Counter #3 Interrupt Mask Register
35// Turn on/off 3A interputs, stopping/enabling the ISR calls 35// Turn on/off 3A interputs, stopping/enabling the ISR calls
36#define ENABLE_AUDIO_COUNTER_3_ISR TIMSK3 |= _BV(OCIE3A) 36#ifdef C6_AUDIO
37#define DISABLE_AUDIO_COUNTER_3_ISR TIMSK3 &= ~_BV(OCIE3A) 37 #define ENABLE_AUDIO_COUNTER_3_ISR TIMSK3 |= _BV(OCIE3A)
38 #define DISABLE_AUDIO_COUNTER_3_ISR TIMSK3 &= ~_BV(OCIE3A)
39#endif
40
41#ifdef B5_AUDIO
42 #define ENABLE_AUDIO_COUNTER_1_ISR TIMSK1 |= _BV(OCIE1A)
43 #define DISABLE_AUDIO_COUNTER_1_ISR TIMSK1 &= ~_BV(OCIE1A)
44#endif
38 45
39// TCCR3A: Timer/Counter #3 Control Register 46// TCCR3A: Timer/Counter #3 Control Register
40// Compare Output Mode (COM3An) = 0b00 = Normal port operation, OC3A disconnected from PC6 47// Compare Output Mode (COM3An) = 0b00 = Normal port operation, OC3A disconnected from PC6
41#define ENABLE_AUDIO_COUNTER_3_OUTPUT TCCR3A |= _BV(COM3A1); 48
42#define DISABLE_AUDIO_COUNTER_3_OUTPUT TCCR3A &= ~(_BV(COM3A1) | _BV(COM3A0)); 49#ifdef C6_AUDIO
50 #define ENABLE_AUDIO_COUNTER_3_OUTPUT TCCR3A |= _BV(COM3A1);
51 #define DISABLE_AUDIO_COUNTER_3_OUTPUT TCCR3A &= ~(_BV(COM3A1) | _BV(COM3A0));
52#endif
53
54#ifdef B5_AUDIO
55 #define ENABLE_AUDIO_COUNTER_1_OUTPUT TCCR1A |= _BV(COM1A1);
56 #define DISABLE_AUDIO_COUNTER_1_OUTPUT TCCR1A &= ~(_BV(COM1A1) | _BV(COM1A0));
57#endif
43 58
44// Fast PWM Mode Controls 59// Fast PWM Mode Controls
45#define TIMER_3_PERIOD ICR3 60
46#define TIMER_3_DUTY_CYCLE OCR3A 61#ifdef C6_AUDIO
62 #define TIMER_3_PERIOD ICR3
63 #define TIMER_3_DUTY_CYCLE OCR3A
64#endif
65
66#ifdef B5_AUDIO
67 #define TIMER_1_PERIOD ICR1
68 #define TIMER_1_DUTY_CYCLE OCR1A
69#endif
70
47 71
48// ----------------------------------------------------------------------------- 72// -----------------------------------------------------------------------------
49 73
@@ -51,6 +75,7 @@
51int voices = 0; 75int voices = 0;
52int voice_place = 0; 76int voice_place = 0;
53float frequency = 0; 77float frequency = 0;
78float frequency_alt = 0;
54int volume = 0; 79int volume = 0;
55long position = 0; 80long position = 0;
56 81
@@ -105,16 +130,43 @@ void audio_init()
105 audio_config.raw = eeconfig_read_audio(); 130 audio_config.raw = eeconfig_read_audio();
106 131
107 // Set port PC6 (OC3A and /OC4A) as output 132 // Set port PC6 (OC3A and /OC4A) as output
108 DDRC |= _BV(PORTC6);
109 133
110 DISABLE_AUDIO_COUNTER_3_ISR; 134 #ifdef C6_AUDIO
135 DDRC |= _BV(PORTC6);
136 #else
137 DDRC |= _BV(PORTC6);
138 PORTC &= ~_BV(PORTC6);
139 #endif
140
141 #ifdef B5_AUDIO
142 DDRB |= _BV(PORTB5);
143 #else
144 DDRB |= _BV(PORTB5);
145 PORTB &= ~_BV(PORTB5);
146 #endif
147
148 #ifdef C6_AUDIO
149 DISABLE_AUDIO_COUNTER_3_ISR;
150 #endif
151
152 #ifdef B5_AUDIO
153 DISABLE_AUDIO_COUNTER_1_ISR;
154 #endif
111 155
112 // TCCR3A / TCCR3B: Timer/Counter #3 Control Registers 156 // TCCR3A / TCCR3B: Timer/Counter #3 Control Registers
113 // Compare Output Mode (COM3An) = 0b00 = Normal port operation, OC3A disconnected from PC6 157 // Compare Output Mode (COM3An) = 0b00 = Normal port operation, OC3A disconnected from PC6
114 // Waveform Generation Mode (WGM3n) = 0b1110 = Fast PWM Mode 14 (Period = ICR3, Duty Cycle = OCR3A) 158 // Waveform Generation Mode (WGM3n) = 0b1110 = Fast PWM Mode 14 (Period = ICR3, Duty Cycle = OCR3A)
115 // Clock Select (CS3n) = 0b010 = Clock / 8 159 // Clock Select (CS3n) = 0b010 = Clock / 8
116 TCCR3A = (0 << COM3A1) | (0 << COM3A0) | (1 << WGM31) | (0 << WGM30); 160
117 TCCR3B = (1 << WGM33) | (1 << WGM32) | (0 << CS32) | (1 << CS31) | (0 << CS30); 161 #ifdef C6_AUDIO
162 TCCR3A = (0 << COM3A1) | (0 << COM3A0) | (1 << WGM31) | (0 << WGM30);
163 TCCR3B = (1 << WGM33) | (1 << WGM32) | (0 << CS32) | (1 << CS31) | (0 << CS30);
164 #endif
165
166 #ifdef B5_AUDIO
167 TCCR1A = (0 << COM1A1) | (0 << COM1A0) | (1 << WGM11) | (0 << WGM10);
168 TCCR1B = (1 << WGM13) | (1 << WGM12) | (0 << CS12) | (1 << CS11) | (0 << CS10);
169 #endif
118 170
119 audio_initialized = true; 171 audio_initialized = true;
120} 172}
@@ -128,12 +180,21 @@ void stop_all_notes()
128 } 180 }
129 voices = 0; 181 voices = 0;
130 182
131 DISABLE_AUDIO_COUNTER_3_ISR; 183
132 DISABLE_AUDIO_COUNTER_3_OUTPUT; 184 #ifdef C6_AUDIO
185 DISABLE_AUDIO_COUNTER_3_ISR;
186 DISABLE_AUDIO_COUNTER_3_OUTPUT;
187 #endif
188
189 #ifdef B5_AUDIO
190 DISABLE_AUDIO_COUNTER_1_ISR;
191 DISABLE_AUDIO_COUNTER_1_OUTPUT;
192 #endif
133 193
134 playing_notes = false; 194 playing_notes = false;
135 playing_note = false; 195 playing_note = false;
136 frequency = 0; 196 frequency = 0;
197 frequency_alt = 0;
137 volume = 0; 198 volume = 0;
138 199
139 for (uint8_t i = 0; i < 8; i++) 200 for (uint8_t i = 0; i < 8; i++)
@@ -171,9 +232,16 @@ void stop_note(float freq)
171 voice_place = 0; 232 voice_place = 0;
172 } 233 }
173 if (voices == 0) { 234 if (voices == 0) {
174 DISABLE_AUDIO_COUNTER_3_ISR; 235 #ifdef C6_AUDIO
175 DISABLE_AUDIO_COUNTER_3_OUTPUT; 236 DISABLE_AUDIO_COUNTER_3_ISR;
237 DISABLE_AUDIO_COUNTER_3_OUTPUT;
238 #endif
239 #ifdef B5_AUDIO
240 DISABLE_AUDIO_COUNTER_1_ISR;
241 DISABLE_AUDIO_COUNTER_1_OUTPUT;
242 #endif
176 frequency = 0; 243 frequency = 0;
244 frequency_alt = 0;
177 volume = 0; 245 volume = 0;
178 playing_note = false; 246 playing_note = false;
179 } 247 }
@@ -200,12 +268,56 @@ float vibrato(float average_freq) {
200 268
201#endif 269#endif
202 270
271#ifdef C6_AUDIO
203ISR(TIMER3_COMPA_vect) 272ISR(TIMER3_COMPA_vect)
204{ 273{
205 float freq; 274 float freq;
206 275
207 if (playing_note) { 276 if (playing_note) {
208 if (voices > 0) { 277 if (voices > 0) {
278
279 #ifdef B5_AUDIO
280 float freq_alt = 0;
281 if (voices > 1) {
282 if (polyphony_rate == 0) {
283 if (glissando) {
284 if (frequency_alt != 0 && frequency_alt < frequencies[voices - 2] && frequency_alt < frequencies[voices - 2] * pow(2, -440/frequencies[voices - 2]/12/2)) {
285 frequency_alt = frequency_alt * pow(2, 440/frequency_alt/12/2);
286 } else if (frequency_alt != 0 && frequency_alt > frequencies[voices - 2] && frequency_alt > frequencies[voices - 2] * pow(2, 440/frequencies[voices - 2]/12/2)) {
287 frequency_alt = frequency_alt * pow(2, -440/frequency_alt/12/2);
288 } else {
289 frequency_alt = frequencies[voices - 2];
290 }
291 } else {
292 frequency_alt = frequencies[voices - 2];
293 }
294
295 #ifdef VIBRATO_ENABLE
296 if (vibrato_strength > 0) {
297 freq_alt = vibrato(frequency_alt);
298 } else {
299 freq_alt = frequency_alt;
300 }
301 #else
302 freq_alt = frequency_alt;
303 #endif
304 }
305
306 if (envelope_index < 65535) {
307 envelope_index++;
308 }
309
310 freq_alt = voice_envelope(freq_alt);
311
312 if (freq_alt < 30.517578125) {
313 freq_alt = 30.52;
314 }
315
316 TIMER_1_PERIOD = (uint16_t)(((float)F_CPU) / (freq_alt * CPU_PRESCALER));
317 TIMER_1_DUTY_CYCLE = (uint16_t)((((float)F_CPU) / (freq_alt * CPU_PRESCALER)) * note_timbre);
318 }
319 #endif
320
209 if (polyphony_rate > 0) { 321 if (polyphony_rate > 0) {
210 if (voices > 1) { 322 if (voices > 1) {
211 voice_place %= voices; 323 voice_place %= voices;
@@ -328,6 +440,140 @@ ISR(TIMER3_COMPA_vect)
328 playing_note = false; 440 playing_note = false;
329 } 441 }
330} 442}
443#endif
444
445#ifdef B5_AUDIO
446ISR(TIMER1_COMPA_vect)
447{
448 #if defined(B5_AUDIO) && !defined(C6_AUDIO)
449 float freq = 0;
450
451 if (playing_note) {
452 if (voices > 0) {
453 if (polyphony_rate > 0) {
454 if (voices > 1) {
455 voice_place %= voices;
456 if (place++ > (frequencies[voice_place] / polyphony_rate / CPU_PRESCALER)) {
457 voice_place = (voice_place + 1) % voices;
458 place = 0.0;
459 }
460 }
461
462 #ifdef VIBRATO_ENABLE
463 if (vibrato_strength > 0) {
464 freq = vibrato(frequencies[voice_place]);
465 } else {
466 freq = frequencies[voice_place];
467 }
468 #else
469 freq = frequencies[voice_place];
470 #endif
471 } else {
472 if (glissando) {
473 if (frequency != 0 && frequency < frequencies[voices - 1] && frequency < frequencies[voices - 1] * pow(2, -440/frequencies[voices - 1]/12/2)) {
474 frequency = frequency * pow(2, 440/frequency/12/2);
475 } else if (frequency != 0 && frequency > frequencies[voices - 1] && frequency > frequencies[voices - 1] * pow(2, 440/frequencies[voices - 1]/12/2)) {
476 frequency = frequency * pow(2, -440/frequency/12/2);
477 } else {
478 frequency = frequencies[voices - 1];
479 }
480 } else {
481 frequency = frequencies[voices - 1];
482 }
483
484 #ifdef VIBRATO_ENABLE
485 if (vibrato_strength > 0) {
486 freq = vibrato(frequency);
487 } else {
488 freq = frequency;
489 }
490 #else
491 freq = frequency;
492 #endif
493 }
494
495 if (envelope_index < 65535) {
496 envelope_index++;
497 }
498
499 freq = voice_envelope(freq);
500
501 if (freq < 30.517578125) {
502 freq = 30.52;
503 }
504
505 TIMER_1_PERIOD = (uint16_t)(((float)F_CPU) / (freq * CPU_PRESCALER));
506 TIMER_1_DUTY_CYCLE = (uint16_t)((((float)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre);
507 }
508 }
509
510 if (playing_notes) {
511 if (note_frequency > 0) {
512 #ifdef VIBRATO_ENABLE
513 if (vibrato_strength > 0) {
514 freq = vibrato(note_frequency);
515 } else {
516 freq = note_frequency;
517 }
518 #else
519 freq = note_frequency;
520 #endif
521
522 if (envelope_index < 65535) {
523 envelope_index++;
524 }
525 freq = voice_envelope(freq);
526
527 TIMER_1_PERIOD = (uint16_t)(((float)F_CPU) / (freq * CPU_PRESCALER));
528 TIMER_1_DUTY_CYCLE = (uint16_t)((((float)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre);
529 } else {
530 TIMER_1_PERIOD = 0;
531 TIMER_1_DUTY_CYCLE = 0;
532 }
533
534 note_position++;
535 bool end_of_note = false;
536 if (TIMER_1_PERIOD > 0) {
537 end_of_note = (note_position >= (note_length / TIMER_1_PERIOD * 0xFFFF));
538 } else {
539 end_of_note = (note_position >= (note_length * 0x7FF));
540 }
541
542 if (end_of_note) {
543 current_note++;
544 if (current_note >= notes_count) {
545 if (notes_repeat) {
546 current_note = 0;
547 } else {
548 DISABLE_AUDIO_COUNTER_1_ISR;
549 DISABLE_AUDIO_COUNTER_1_OUTPUT;
550 playing_notes = false;
551 return;
552 }
553 }
554 if (!note_resting && (notes_rest > 0)) {
555 note_resting = true;
556 note_frequency = 0;
557 note_length = notes_rest;
558 current_note--;
559 } else {
560 note_resting = false;
561 envelope_index = 0;
562 note_frequency = (*notes_pointer)[current_note][0];
563 note_length = ((*notes_pointer)[current_note][1] / 4) * (((float)note_tempo) / 100);
564 }
565
566 note_position = 0;
567 }
568 }
569
570 if (!audio_config.enable) {
571 playing_notes = false;
572 playing_note = false;
573 }
574#endif
575}
576#endif
331 577
332void play_note(float freq, int vol) { 578void play_note(float freq, int vol) {
333 579
@@ -338,7 +584,12 @@ void play_note(float freq, int vol) {
338 } 584 }
339 585
340 if (audio_config.enable && voices < 8) { 586 if (audio_config.enable && voices < 8) {
341 DISABLE_AUDIO_COUNTER_3_ISR; 587 #ifdef C6_AUDIO
588 DISABLE_AUDIO_COUNTER_3_ISR;
589 #endif
590 #ifdef B5_AUDIO
591 DISABLE_AUDIO_COUNTER_1_ISR;
592 #endif
342 593
343 // Cancel notes if notes are playing 594 // Cancel notes if notes are playing
344 if (playing_notes) 595 if (playing_notes)
@@ -354,8 +605,21 @@ void play_note(float freq, int vol) {
354 voices++; 605 voices++;
355 } 606 }
356 607
357 ENABLE_AUDIO_COUNTER_3_ISR; 608 #ifdef C6_AUDIO
358 ENABLE_AUDIO_COUNTER_3_OUTPUT; 609 ENABLE_AUDIO_COUNTER_3_ISR;
610 ENABLE_AUDIO_COUNTER_3_OUTPUT;
611 #endif
612 #ifdef B5_AUDIO
613 #ifdef C6_AUDIO
614 if (voices > 1) {
615 ENABLE_AUDIO_COUNTER_1_ISR;
616 ENABLE_AUDIO_COUNTER_1_OUTPUT;
617 }
618 #else
619 ENABLE_AUDIO_COUNTER_1_ISR;
620 ENABLE_AUDIO_COUNTER_1_OUTPUT;
621 #endif
622 #endif
359 } 623 }
360 624
361} 625}
@@ -369,7 +633,12 @@ void play_notes(float (*np)[][2], uint16_t n_count, bool n_repeat, float n_rest)
369 633
370 if (audio_config.enable) { 634 if (audio_config.enable) {
371 635
372 DISABLE_AUDIO_COUNTER_3_ISR; 636 #ifdef C6_AUDIO
637 DISABLE_AUDIO_COUNTER_3_ISR;
638 #endif
639 #ifdef B5_AUDIO
640 DISABLE_AUDIO_COUNTER_1_ISR;
641 #endif
373 642
374 // Cancel note if a note is playing 643 // Cancel note if a note is playing
375 if (playing_note) 644 if (playing_note)
@@ -390,8 +659,16 @@ void play_notes(float (*np)[][2], uint16_t n_count, bool n_repeat, float n_rest)
390 note_position = 0; 659 note_position = 0;
391 660
392 661
393 ENABLE_AUDIO_COUNTER_3_ISR; 662 #ifdef C6_AUDIO
394 ENABLE_AUDIO_COUNTER_3_OUTPUT; 663 ENABLE_AUDIO_COUNTER_3_ISR;
664 ENABLE_AUDIO_COUNTER_3_OUTPUT;
665 #endif
666 #ifdef B5_AUDIO
667 #ifndef C6_AUDIO
668 ENABLE_AUDIO_COUNTER_1_ISR;
669 ENABLE_AUDIO_COUNTER_1_OUTPUT;
670 #endif
671 #endif
395 } 672 }
396 673
397} 674}
diff --git a/quantum/audio/voices.c b/quantum/audio/voices.c
index 54ebd423b..94147ccb6 100644
--- a/quantum/audio/voices.c
+++ b/quantum/audio/voices.c
@@ -44,7 +44,7 @@ float voice_envelope(float frequency) {
44 44
45 switch (voice) { 45 switch (voice) {
46 case default_voice: 46 case default_voice:
47 glissando = true; 47 glissando = false;
48 note_timbre = TIMBRE_50; 48 note_timbre = TIMBRE_50;
49 polyphony_rate = 0; 49 polyphony_rate = 0;
50 break; 50 break;
diff --git a/quantum/keycode_config.c b/quantum/keycode_config.c
index 4f7bc525e..eb39c8fe0 100644
--- a/quantum/keycode_config.c
+++ b/quantum/keycode_config.c
@@ -88,3 +88,31 @@ uint16_t keycode_config(uint16_t keycode) {
88 return keycode; 88 return keycode;
89 } 89 }
90} 90}
91
92uint8_t mod_config(uint8_t mod) {
93 keymap_config.raw = eeconfig_read_keymap();
94 if (keymap_config.swap_lalt_lgui) {
95 if ((mod & MOD_RGUI) == MOD_LGUI) {
96 mod &= ~MOD_LGUI;
97 mod |= MOD_LALT;
98 } else if ((mod & MOD_RALT) == MOD_LALT) {
99 mod &= ~MOD_LALT;
100 mod |= MOD_LGUI;
101 }
102 }
103 if (keymap_config.swap_ralt_rgui) {
104 if ((mod & MOD_RGUI) == MOD_RGUI) {
105 mod &= ~MOD_RGUI;
106 mod |= MOD_RALT;
107 } else if ((mod & MOD_RALT) == MOD_RALT) {
108 mod &= ~MOD_RALT;
109 mod |= MOD_RGUI;
110 }
111 }
112 if (keymap_config.no_gui) {
113 mod &= ~MOD_LGUI;
114 mod &= ~MOD_RGUI;
115 }
116
117 return mod;
118} \ No newline at end of file
diff --git a/quantum/keycode_config.h b/quantum/keycode_config.h
index 293fefecf..022f4bd19 100644
--- a/quantum/keycode_config.h
+++ b/quantum/keycode_config.h
@@ -16,11 +16,13 @@
16 16
17#include "eeconfig.h" 17#include "eeconfig.h"
18#include "keycode.h" 18#include "keycode.h"
19#include "action_code.h"
19 20
20#ifndef KEYCODE_CONFIG_H 21#ifndef KEYCODE_CONFIG_H
21#define KEYCODE_CONFIG_H 22#define KEYCODE_CONFIG_H
22 23
23uint16_t keycode_config(uint16_t keycode); 24uint16_t keycode_config(uint16_t keycode);
25uint8_t mod_config(uint8_t mod);
24 26
25/* NOTE: Not portable. Bit field order depends on implementation */ 27/* NOTE: Not portable. Bit field order depends on implementation */
26typedef union { 28typedef union {
diff --git a/quantum/keymap_common.c b/quantum/keymap_common.c
index 9dafc8b51..b1460c53c 100644
--- a/quantum/keymap_common.c
+++ b/quantum/keymap_common.c
@@ -123,7 +123,8 @@ action_t action_for_key(uint8_t layer, keypos_t key)
123 action.code = ACTION_LAYER_TAP_TOGGLE(keycode & 0xFF); 123 action.code = ACTION_LAYER_TAP_TOGGLE(keycode & 0xFF);
124 break; 124 break;
125 case QK_MOD_TAP ... QK_MOD_TAP_MAX: 125 case QK_MOD_TAP ... QK_MOD_TAP_MAX:
126 action.code = ACTION_MODS_TAP_KEY((keycode >> 0x8) & 0x1F, keycode & 0xFF); 126 mod = mod_config((keycode >> 0x8) & 0x1F);
127 action.code = ACTION_MODS_TAP_KEY(mod, keycode & 0xFF);
127 break; 128 break;
128 #ifdef BACKLIGHT_ENABLE 129 #ifdef BACKLIGHT_ENABLE
129 case BL_0 ... BL_15: 130 case BL_0 ... BL_15:
diff --git a/quantum/keymap_extras/keymap_spanish.h b/quantum/keymap_extras/keymap_spanish.h
index 3a5787e9c..224db7be1 100644
--- a/quantum/keymap_extras/keymap_spanish.h
+++ b/quantum/keymap_extras/keymap_spanish.h
@@ -55,8 +55,8 @@
55#define ES_UMLT LSFT(ES_GRV) 55#define ES_UMLT LSFT(ES_GRV)
56 56
57#define ES_GRTR LSFT(ES_LESS) 57#define ES_GRTR LSFT(ES_LESS)
58#define ES_SCLN LSFT(ES_COMM) 58#define ES_SCLN LSFT(KC_COMM)
59#define ES_COLN LSFT(ES_DOT) 59#define ES_COLN LSFT(KC_DOT)
60#define ES_UNDS LSFT(ES_MINS) 60#define ES_UNDS LSFT(ES_MINS)
61 61
62// Alt Gr-ed characters 62// Alt Gr-ed characters
@@ -72,6 +72,6 @@
72#define ES_RBRC ALGR(ES_PLUS) 72#define ES_RBRC ALGR(ES_PLUS)
73 73
74#define ES_LCBR ALGR(ES_ACUT) 74#define ES_LCBR ALGR(ES_ACUT)
75#define ES_RCRB ALGR(ES_CCED) 75#define ES_RCBR ALGR(ES_CCED)
76 76
77#endif 77#endif
diff --git a/quantum/keymap_extras/keymap_swedish.h b/quantum/keymap_extras/keymap_swedish.h
new file mode 100644
index 000000000..dcfad720d
--- /dev/null
+++ b/quantum/keymap_extras/keymap_swedish.h
@@ -0,0 +1,52 @@
1/* Copyright 2017 Andreas Lindhé
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#ifndef KEYMAP_SWEDISH_H
18#define KEYMAP_SWEDISH_H
19
20#include "keymap_nordic.h"
21
22// There are slight differrences in the keyboards in the nordic contries
23
24// Swedish redifinitions from the nordic keyset
25#undef NO_AE
26#define NO_AE KC_QUOT // ä
27#undef NO_CIRC
28#define NO_CIRC LSFT(KC_RBRC) // ^
29#undef NO_GRV
30#define NO_GRV LSFT(NO_BSLS) //
31#undef NO_OSLH
32#define NO_OSLH KC_SCLN // ö
33
34// Additional Swedish keys not defined in the nordic keyset
35#define NO_AA KC_LBRC // å
36#define NO_ASTR LSFT(KC_BSLS) // *
37
38// Norwegian unique MAC characters (not vetted for Swedish)
39#define NO_ACUT_MAC KC_EQL // =
40#define NO_APOS_MAC KC_NUBS // '
41#define NO_AT_MAC KC_BSLS // @
42#define NO_BSLS_MAC ALGR(LSFT(KC_7)) // '\'
43#define NO_DLR_MAC LSFT(KC_4) // $
44#define NO_GRV_MAC ALGR(NO_BSLS) // `
45#define NO_GRTR_MAC LSFT(KC_GRV) // >
46#define NO_LCBR_MAC ALGR(LSFT(KC_8)) // }
47#define NO_LESS_MAC KC_GRV // >
48#define NO_PIPE_MAC ALGR(KC_7) // |
49#define NO_RCBR_MAC ALGR(LSFT(KC_9)) // }
50
51#endif
52
diff --git a/quantum/quantum.c b/quantum/quantum.c
index 4f4cee4e9..5bb7b04d5 100644
--- a/quantum/quantum.c
+++ b/quantum/quantum.c
@@ -437,6 +437,14 @@ bool process_record_quantum(keyrecord_t *record) {
437 return false; 437 return false;
438 // break; 438 // break;
439 } 439 }
440 case GRAVE_ESC: {
441 void (*method)(uint8_t) = (record->event.pressed) ? &add_key : &del_key;
442 uint8_t shifted = get_mods() & ((MOD_BIT(KC_LSHIFT)|MOD_BIT(KC_RSHIFT)
443 |MOD_BIT(KC_LGUI)|MOD_BIT(KC_RGUI)));
444
445 method(shifted ? KC_GRAVE : KC_ESCAPE);
446 send_keyboard_report();
447 }
440 default: { 448 default: {
441 shift_interrupted[0] = true; 449 shift_interrupted[0] = true;
442 shift_interrupted[1] = true; 450 shift_interrupted[1] = true;
@@ -447,7 +455,103 @@ bool process_record_quantum(keyrecord_t *record) {
447 return process_action_kb(record); 455 return process_action_kb(record);
448} 456}
449 457
450const bool ascii_to_qwerty_shift_lut[0x80] PROGMEM = { 458#ifdef JIS_KEYCODE
459static const uint16_t ascii_to_shift_lut[8] PROGMEM = {
460 0x0000, /*0, 0, 0, 0, 0, 0, 0, 0,
461 0, 0, 0, 0, 0, 0, 0, 0,*/
462 0x0000, /*0, 0, 0, 0, 0, 0, 0, 0,
463 0, 0, 0, 0, 0, 0, 0, 0,*/
464 0x7ff0, /*0, 1, 1, 1, 1, 1, 1, 1,
465 1, 1, 1, 1, 0, 0, 0, 0,*/
466 0x000f, /*0, 0, 0, 0, 0, 0, 0, 0,
467 0, 0, 0, 0, 1, 1, 1, 1,*/
468 0x7fff, /*0, 1, 1, 1, 1, 1, 1, 1,
469 1, 1, 1, 1, 1, 1, 1, 1,*/
470 0xffe1, /*1, 1, 1, 1, 1, 1, 1, 1,
471 1, 1, 1, 0, 0, 0, 0, 1,*/
472 0x8000, /*1, 0, 0, 0, 0, 0, 0, 0,
473 0, 0, 0, 0, 0, 0, 0, 0,*/
474 0x001e, /*0, 0, 0, 0, 0, 0, 0, 0,
475 0, 0, 0, 1, 1, 1, 1, 0*/
476};
477
478static const struct {
479 uint8_t controls_0[16],
480 controls_1[16],
481 numerics[16],
482 alphabets_0[16],
483 alphabets_1[16];
484} lower_to_keycode PROGMEM = {
485 .controls_0 = {
486 0, 0, 0, 0, 0, 0, 0, 0,
487 KC_BSPC, KC_TAB, KC_ENT, 0, 0, 0, 0, 0,
488 },
489 .controls_1 = {
490 0, 0, 0, 0, 0, 0, 0, 0,
491 0, 0, 0, KC_ESC, 0, 0, 0, 0,
492 },
493 .numerics = {
494 KC_0, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7,
495 KC_8, KC_9, KC_QUOT, KC_SCLN, KC_COMM, KC_MINS, KC_DOT, KC_SLSH,
496 },
497 .alphabets_0 = {
498 KC_LBRC, KC_A, KC_B, KC_C, KC_D, KC_E, KC_F, KC_G,
499 KC_H, KC_I, KC_J, KC_K, KC_L, KC_M, KC_N, KC_O,
500 },
501 .alphabets_1 = {
502 KC_P, KC_Q, KC_R, KC_S, KC_T, KC_U, KC_V, KC_W,
503 KC_X, KC_Y, KC_Z, KC_RBRC, KC_JYEN, KC_BSLS, KC_EQL, KC_RO,
504 },
505};
506static const uint8_t* ascii_to_keycode_lut[8] = {
507 lower_to_keycode.controls_0,
508 lower_to_keycode.controls_1,
509 lower_to_keycode.numerics,
510 lower_to_keycode.numerics,
511 lower_to_keycode.alphabets_0,
512 lower_to_keycode.alphabets_1,
513 lower_to_keycode.alphabets_0,
514 lower_to_keycode.alphabets_1
515};
516
517void send_string(const char *str) {
518 while (1) {
519 uint8_t keycode;
520 bool shift;
521 uint8_t ascii_code = pgm_read_byte(str);
522
523 if ( ascii_code == 0x00u ){ break; }
524 else if (ascii_code == 0x20u) {
525 keycode = KC_SPC;
526 shift = false;
527 }
528 else if (ascii_code == 0x7Fu) {
529 keycode = KC_DEL;
530 shift = false;
531 }
532 else {
533 int hi = ascii_code>>4 & 0x0f,
534 lo = ascii_code & 0x0f;
535 keycode = pgm_read_byte(&ascii_to_keycode_lut[hi][lo]);
536 shift = !!( pgm_read_word(&ascii_to_shift_lut[hi]) & (0x8000u>>lo) );
537 }
538
539 if (shift) {
540 register_code(KC_LSFT);
541 register_code(keycode);
542 unregister_code(keycode);
543 unregister_code(KC_LSFT);
544 }
545 else {
546 register_code(keycode);
547 unregister_code(keycode);
548 }
549 ++str;
550 }
551}
552
553#else
554static const bool ascii_to_qwerty_shift_lut[0x80] PROGMEM = {
451 0, 0, 0, 0, 0, 0, 0, 0, 555 0, 0, 0, 0, 0, 0, 0, 0,
452 0, 0, 0, 0, 0, 0, 0, 0, 556 0, 0, 0, 0, 0, 0, 0, 0,
453 0, 0, 0, 0, 0, 0, 0, 0, 557 0, 0, 0, 0, 0, 0, 0, 0,
@@ -466,7 +570,7 @@ const bool ascii_to_qwerty_shift_lut[0x80] PROGMEM = {
466 0, 0, 0, 1, 1, 1, 1, 0 570 0, 0, 0, 1, 1, 1, 1, 0
467}; 571};
468 572
469const uint8_t ascii_to_qwerty_keycode_lut[0x80] PROGMEM = { 573static const uint8_t ascii_to_qwerty_keycode_lut[0x80] PROGMEM = {
470 0, 0, 0, 0, 0, 0, 0, 0, 574 0, 0, 0, 0, 0, 0, 0, 0,
471 KC_BSPC, KC_TAB, KC_ENT, 0, 0, 0, 0, 0, 575 KC_BSPC, KC_TAB, KC_ENT, 0, 0, 0, 0, 0,
472 0, 0, 0, 0, 0, 0, 0, 0, 576 0, 0, 0, 0, 0, 0, 0, 0,
@@ -485,6 +589,28 @@ const uint8_t ascii_to_qwerty_keycode_lut[0x80] PROGMEM = {
485 KC_X, KC_Y, KC_Z, KC_LBRC, KC_BSLS, KC_RBRC, KC_GRV, KC_DEL 589 KC_X, KC_Y, KC_Z, KC_LBRC, KC_BSLS, KC_RBRC, KC_GRV, KC_DEL
486}; 590};
487 591
592void send_string(const char *str) {
593 while (1) {
594 uint8_t keycode;
595 uint8_t ascii_code = pgm_read_byte(str);
596 if (!ascii_code) break;
597 keycode = pgm_read_byte(&ascii_to_qwerty_keycode_lut[ascii_code]);
598 if (pgm_read_byte(&ascii_to_qwerty_shift_lut[ascii_code])) {
599 register_code(KC_LSFT);
600 register_code(keycode);
601 unregister_code(keycode);
602 unregister_code(KC_LSFT);
603 }
604 else {
605 register_code(keycode);
606 unregister_code(keycode);
607 }
608 ++str;
609 }
610}
611
612#endif
613
488/* for users whose OSes are set to Colemak */ 614/* for users whose OSes are set to Colemak */
489#if 0 615#if 0
490#include "keymap_colemak.h" 616#include "keymap_colemak.h"
@@ -529,26 +655,6 @@ const uint8_t ascii_to_colemak_keycode_lut[0x80] PROGMEM = {
529 655
530#endif 656#endif
531 657
532void send_string(const char *str) {
533 while (1) {
534 uint8_t keycode;
535 uint8_t ascii_code = pgm_read_byte(str);
536 if (!ascii_code) break;
537 keycode = pgm_read_byte(&ascii_to_qwerty_keycode_lut[ascii_code]);
538 if (pgm_read_byte(&ascii_to_qwerty_shift_lut[ascii_code])) {
539 register_code(KC_LSFT);
540 register_code(keycode);
541 unregister_code(keycode);
542 unregister_code(KC_LSFT);
543 }
544 else {
545 register_code(keycode);
546 unregister_code(keycode);
547 }
548 ++str;
549 }
550}
551
552void update_tri_layer(uint8_t layer1, uint8_t layer2, uint8_t layer3) { 658void update_tri_layer(uint8_t layer1, uint8_t layer2, uint8_t layer3) {
553 if (IS_LAYER_ON(layer1) && IS_LAYER_ON(layer2)) { 659 if (IS_LAYER_ON(layer1) && IS_LAYER_ON(layer2)) {
554 layer_on(layer3); 660 layer_on(layer3);
diff --git a/quantum/quantum_keycodes.h b/quantum/quantum_keycodes.h
index 7354ae0da..6038e31c4 100644
--- a/quantum/quantum_keycodes.h
+++ b/quantum/quantum_keycodes.h
@@ -104,6 +104,7 @@ enum quantum_keycodes {
104 MAGIC_UNHOST_NKRO, 104 MAGIC_UNHOST_NKRO,
105 MAGIC_UNSWAP_ALT_GUI, 105 MAGIC_UNSWAP_ALT_GUI,
106 MAGIC_TOGGLE_NKRO, 106 MAGIC_TOGGLE_NKRO,
107 GRAVE_ESC,
107 108
108 // Leader key 109 // Leader key
109#ifndef DISABLE_LEADER 110#ifndef DISABLE_LEADER
@@ -514,6 +515,8 @@ enum quantum_keycodes {
514#define MACROTAP(kc) (kc | QK_MACRO | FUNC_TAP<<8) 515#define MACROTAP(kc) (kc | QK_MACRO | FUNC_TAP<<8)
515#define MACRODOWN(...) (record->event.pressed ? MACRO(__VA_ARGS__) : MACRO_NONE) 516#define MACRODOWN(...) (record->event.pressed ? MACRO(__VA_ARGS__) : MACRO_NONE)
516 517
518#define KC_GESC GRAVE_ESC
519
517 520
518// L-ayer, T-ap - 256 keycode max, 16 layer max 521// L-ayer, T-ap - 256 keycode max, 16 layer max
519#define LT(layer, kc) (kc | QK_LAYER_TAP | ((layer & 0xF) << 8)) 522#define LT(layer, kc) (kc | QK_LAYER_TAP | ((layer & 0xF) << 8))
@@ -547,13 +550,13 @@ enum quantum_keycodes {
547#define OSL(layer) (layer | QK_ONE_SHOT_LAYER) 550#define OSL(layer) (layer | QK_ONE_SHOT_LAYER)
548 551
549// One-shot mod 552// One-shot mod
550#define OSM(mod) (mod | QK_ONE_SHOT_MOD) 553#define OSM(mod) ((mod) | QK_ONE_SHOT_MOD)
551 554
552// Layer tap-toggle 555// Layer tap-toggle
553#define TT(layer) (layer | QK_LAYER_TAP_TOGGLE) 556#define TT(layer) (layer | QK_LAYER_TAP_TOGGLE)
554 557
555// M-od, T-ap - 256 keycode max 558// M-od, T-ap - 256 keycode max
556#define MT(mod, kc) (kc | QK_MOD_TAP | ((mod & 0x1F) << 8)) 559#define MT(mod, kc) (kc | QK_MOD_TAP | (((mod) & 0x1F) << 8))
557 560
558#define CTL_T(kc) MT(MOD_LCTL, kc) 561#define CTL_T(kc) MT(MOD_LCTL, kc)
559#define LCTL_T(kc) MT(MOD_LCTL, kc) 562#define LCTL_T(kc) MT(MOD_LCTL, kc)
diff --git a/quantum/template/rules.mk b/quantum/template/rules.mk
index a1f9377d8..a3571e8de 100644
--- a/quantum/template/rules.mk
+++ b/quantum/template/rules.mk
@@ -1,5 +1,5 @@
1# MCU name 1# MCU name
2#MCU = at90usb1287 2#MCU = at90usb1286
3MCU = atmega32u4 3MCU = atmega32u4
4 4
5# Processor frequency. 5# Processor frequency.
diff --git a/quantum/visualizer/lcd_backlight.c b/quantum/visualizer/lcd_backlight.c
index 00de3fab5..6cd996f75 100644
--- a/quantum/visualizer/lcd_backlight.c
+++ b/quantum/visualizer/lcd_backlight.c
@@ -83,3 +83,7 @@ void lcd_backlight_brightness(uint8_t b) {
83 current_brightness = b; 83 current_brightness = b;
84 lcd_backlight_color(current_hue, current_saturation, current_intensity); 84 lcd_backlight_color(current_hue, current_saturation, current_intensity);
85} 85}
86
87uint8_t lcd_get_backlight_brightness(void) {
88 return current_brightness;
89}
diff --git a/quantum/visualizer/lcd_backlight.h b/quantum/visualizer/lcd_backlight.h
index 14dde64a1..95d7a07b4 100644
--- a/quantum/visualizer/lcd_backlight.h
+++ b/quantum/visualizer/lcd_backlight.h
@@ -32,13 +32,14 @@ SOFTWARE.
32#define LCD_SAT(color) ((color >> 8) & 0xFF) 32#define LCD_SAT(color) ((color >> 8) & 0xFF)
33#define LCD_INT(color) (color & 0xFF) 33#define LCD_INT(color) (color & 0xFF)
34 34
35inline uint32_t change_lcd_color_intensity(uint32_t color, uint8_t new_intensity) { 35static inline uint32_t change_lcd_color_intensity(uint32_t color, uint8_t new_intensity) {
36 return (color & 0xFFFFFF00) | new_intensity; 36 return (color & 0xFFFFFF00) | new_intensity;
37} 37}
38 38
39void lcd_backlight_init(void); 39void lcd_backlight_init(void);
40void lcd_backlight_color(uint8_t hue, uint8_t saturation, uint8_t intensity); 40void lcd_backlight_color(uint8_t hue, uint8_t saturation, uint8_t intensity);
41void lcd_backlight_brightness(uint8_t b); 41void lcd_backlight_brightness(uint8_t b);
42uint8_t lcd_get_backlight_brightness(void);
42 43
43void lcd_backlight_hal_init(void); 44void lcd_backlight_hal_init(void);
44void lcd_backlight_hal_color(uint16_t r, uint16_t g, uint16_t b); 45void lcd_backlight_hal_color(uint16_t r, uint16_t g, uint16_t b);
diff --git a/quantum/visualizer/led_keyframes.c b/quantum/visualizer/led_keyframes.c
index 2dacd990d..7e6e5d1ab 100644
--- a/quantum/visualizer/led_keyframes.c
+++ b/quantum/visualizer/led_keyframes.c
@@ -41,14 +41,14 @@ static void keyframe_fade_all_leds_from_to(keyframe_animation_t* animation, uint
41} 41}
42 42
43// TODO: Should be customizable per keyboard 43// TODO: Should be customizable per keyboard
44#define NUM_ROWS 7 44#define NUM_ROWS LED_NUM_ROWS
45#define NUM_COLS 7 45#define NUM_COLS LED_NUM_COLS
46 46
47static uint8_t crossfade_start_frame[NUM_ROWS][NUM_COLS]; 47static uint8_t crossfade_start_frame[NUM_ROWS][NUM_COLS];
48static uint8_t crossfade_end_frame[NUM_ROWS][NUM_COLS]; 48static uint8_t crossfade_end_frame[NUM_ROWS][NUM_COLS];
49 49
50static uint8_t compute_gradient_color(float t, float index, float num) { 50static uint8_t compute_gradient_color(float t, float index, float num) {
51 const float two_pi = M_2_PI; 51 const float two_pi = M_PI * 2.0f;
52 float normalized_index = (1.0f - index / (num - 1.0f)) * two_pi; 52 float normalized_index = (1.0f - index / (num - 1.0f)) * two_pi;
53 float x = t * two_pi + normalized_index; 53 float x = t * two_pi + normalized_index;
54 float v = 0.5 * (cosf(x) + 1.0f); 54 float v = 0.5 * (cosf(x) + 1.0f);
@@ -127,3 +127,17 @@ bool led_keyframe_normal_orientation(keyframe_animation_t* animation, visualizer
127 gdispGSetOrientation(LED_DISPLAY, GDISP_ROTATE_0); 127 gdispGSetOrientation(LED_DISPLAY, GDISP_ROTATE_0);
128 return false; 128 return false;
129} 129}
130
131bool led_keyframe_disable(keyframe_animation_t* animation, visualizer_state_t* state) {
132 (void)state;
133 (void)animation;
134 gdispGSetPowerMode(LED_DISPLAY, powerOff);
135 return false;
136}
137
138bool led_keyframe_enable(keyframe_animation_t* animation, visualizer_state_t* state) {
139 (void)state;
140 (void)animation;
141 gdispGSetPowerMode(LED_DISPLAY, powerOn);
142 return false;
143}
diff --git a/quantum/visualizer/led_keyframes.h b/quantum/visualizer/led_keyframes.h
index a68943041..a59a4f37d 100644
--- a/quantum/visualizer/led_keyframes.h
+++ b/quantum/visualizer/led_keyframes.h
@@ -35,6 +35,9 @@ bool led_keyframe_crossfade(keyframe_animation_t* animation, visualizer_state_t*
35bool led_keyframe_mirror_orientation(keyframe_animation_t* animation, visualizer_state_t* state); 35bool led_keyframe_mirror_orientation(keyframe_animation_t* animation, visualizer_state_t* state);
36bool led_keyframe_normal_orientation(keyframe_animation_t* animation, visualizer_state_t* state); 36bool led_keyframe_normal_orientation(keyframe_animation_t* animation, visualizer_state_t* state);
37 37
38bool led_keyframe_disable(keyframe_animation_t* animation, visualizer_state_t* state);
39bool led_keyframe_enable(keyframe_animation_t* animation, visualizer_state_t* state);
40
38extern keyframe_animation_t led_test_animation; 41extern keyframe_animation_t led_test_animation;
39 42
40 43
diff --git a/quantum/visualizer/visualizer.c b/quantum/visualizer/visualizer.c
index 6f134097f..cc99d1e3b 100644
--- a/quantum/visualizer/visualizer.c
+++ b/quantum/visualizer/visualizer.c
@@ -22,8 +22,8 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22SOFTWARE. 22SOFTWARE.
23*/ 23*/
24 24
25#include "visualizer.h"
26#include "config.h" 25#include "config.h"
26#include "visualizer.h"
27#include <string.h> 27#include <string.h>
28#ifdef PROTOCOL_CHIBIOS 28#ifdef PROTOCOL_CHIBIOS
29#include "ch.h" 29#include "ch.h"
@@ -58,8 +58,11 @@ SOFTWARE.
58static visualizer_keyboard_status_t current_status = { 58static visualizer_keyboard_status_t current_status = {
59 .layer = 0xFFFFFFFF, 59 .layer = 0xFFFFFFFF,
60 .default_layer = 0xFFFFFFFF, 60 .default_layer = 0xFFFFFFFF,
61 .mods = 0xFF,
62 .leds = 0xFFFFFFFF, 61 .leds = 0xFFFFFFFF,
62#ifdef BACKLIGHT_ENABLE
63 .backlight_level = 0,
64#endif
65 .mods = 0xFF,
63 .suspended = false, 66 .suspended = false,
64#ifdef VISUALIZER_USER_DATA_SIZE 67#ifdef VISUALIZER_USER_DATA_SIZE
65 .user_data = {0} 68 .user_data = {0}
@@ -72,6 +75,9 @@ static bool same_status(visualizer_keyboard_status_t* status1, visualizer_keyboa
72 status1->mods == status2->mods && 75 status1->mods == status2->mods &&
73 status1->leds == status2->leds && 76 status1->leds == status2->leds &&
74 status1->suspended == status2->suspended 77 status1->suspended == status2->suspended
78#ifdef BACKLIGHT_ENABLE
79 && status1->backlight_level == status2->backlight_level
80#endif
75#ifdef VISUALIZER_USER_DATA_SIZE 81#ifdef VISUALIZER_USER_DATA_SIZE
76 && memcmp(status1->user_data, status2->user_data, VISUALIZER_USER_DATA_SIZE) == 0 82 && memcmp(status1->user_data, status2->user_data, VISUALIZER_USER_DATA_SIZE) == 0
77#endif 83#endif
@@ -99,15 +105,19 @@ static remote_object_t* remote_objects[] = {
99GDisplay* LCD_DISPLAY = 0; 105GDisplay* LCD_DISPLAY = 0;
100GDisplay* LED_DISPLAY = 0; 106GDisplay* LED_DISPLAY = 0;
101 107
108#ifdef LCD_DISPLAY_NUMBER
102__attribute__((weak)) 109__attribute__((weak))
103GDisplay* get_lcd_display(void) { 110GDisplay* get_lcd_display(void) {
104 return gdispGetDisplay(0); 111 return gdispGetDisplay(LCD_DISPLAY_NUMBER);
105} 112}
113#endif
106 114
115#ifdef LED_DISPLAY_NUMBER
107__attribute__((weak)) 116__attribute__((weak))
108GDisplay* get_led_display(void) { 117GDisplay* get_led_display(void) {
109 return gdispGetDisplay(1); 118 return gdispGetDisplay(LED_DISPLAY_NUMBER);
110} 119}
120#endif
111 121
112void start_keyframe_animation(keyframe_animation_t* animation) { 122void start_keyframe_animation(keyframe_animation_t* animation) {
113 animation->current_frame = -1; 123 animation->current_frame = -1;
@@ -245,9 +255,9 @@ static DECLARE_THREAD_FUNCTION(visualizerThread, arg) {
245 .mods = 0xFF, 255 .mods = 0xFF,
246 .leds = 0xFFFFFFFF, 256 .leds = 0xFFFFFFFF,
247 .suspended = false, 257 .suspended = false,
248#ifdef VISUALIZER_USER_DATA_SIZE 258 #ifdef VISUALIZER_USER_DATA_SIZE
249 .user_data = {0}, 259 .user_data = {0},
250#endif 260 #endif
251 }; 261 };
252 262
253 visualizer_state_t state = { 263 visualizer_state_t state = {
@@ -279,6 +289,18 @@ static DECLARE_THREAD_FUNCTION(visualizerThread, arg) {
279 bool enabled = visualizer_enabled; 289 bool enabled = visualizer_enabled;
280 if (force_update || !same_status(&state.status, &current_status)) { 290 if (force_update || !same_status(&state.status, &current_status)) {
281 force_update = false; 291 force_update = false;
292 #if BACKLIGHT_ENABLE
293 if(current_status.backlight_level != state.status.backlight_level) {
294 if (current_status.backlight_level != 0) {
295 gdispGSetPowerMode(LED_DISPLAY, powerOn);
296 uint16_t percent = (uint16_t)current_status.backlight_level * 100 / BACKLIGHT_LEVELS;
297 gdispGSetBacklight(LED_DISPLAY, percent);
298 }
299 else {
300 gdispGSetPowerMode(LED_DISPLAY, powerOff);
301 }
302 }
303 #endif
282 if (visualizer_enabled) { 304 if (visualizer_enabled) {
283 if (current_status.suspended) { 305 if (current_status.suspended) {
284 stop_all_keyframe_animations(); 306 stop_all_keyframe_animations();
@@ -309,7 +331,7 @@ static DECLARE_THREAD_FUNCTION(visualizerThread, arg) {
309 update_keyframe_animation(animations[i], &state, delta, &sleep_time); 331 update_keyframe_animation(animations[i], &state, delta, &sleep_time);
310 } 332 }
311 } 333 }
312#ifdef LED_ENABLE 334#ifdef BACKLIGHT_ENABLE
313 gdispGFlush(LED_DISPLAY); 335 gdispGFlush(LED_DISPLAY);
314#endif 336#endif
315 337
@@ -361,25 +383,26 @@ static DECLARE_THREAD_FUNCTION(visualizerThread, arg) {
361void visualizer_init(void) { 383void visualizer_init(void) {
362 gfxInit(); 384 gfxInit();
363 385
364#ifdef LCD_BACKLIGHT_ENABLE 386 #ifdef LCD_BACKLIGHT_ENABLE
365 lcd_backlight_init(); 387 lcd_backlight_init();
366#endif 388 #endif
367 389
368#ifdef SERIAL_LINK_ENABLE 390 #ifdef SERIAL_LINK_ENABLE
369 add_remote_objects(remote_objects, sizeof(remote_objects) / sizeof(remote_object_t*) ); 391 add_remote_objects(remote_objects, sizeof(remote_objects) / sizeof(remote_object_t*) );
370#endif 392 #endif
371 393
372#ifdef LCD_ENABLE 394 #ifdef LCD_ENABLE
373 LCD_DISPLAY = get_lcd_display(); 395 LCD_DISPLAY = get_lcd_display();
374#endif 396 #endif
375#ifdef LED_ENABLE 397
398 #ifdef BACKLIGHT_ENABLE
376 LED_DISPLAY = get_led_display(); 399 LED_DISPLAY = get_led_display();
377#endif 400 #endif
378 401
379 // We are using a low priority thread, the idea is to have it run only 402 // We are using a low priority thread, the idea is to have it run only
380 // when the main thread is sleeping during the matrix scanning 403 // when the main thread is sleeping during the matrix scanning
381 gfxThreadCreate(visualizerThreadStack, sizeof(visualizerThreadStack), 404 gfxThreadCreate(visualizerThreadStack, sizeof(visualizerThreadStack),
382 VISUALIZER_THREAD_PRIORITY, visualizerThread, NULL); 405 VISUALIZER_THREAD_PRIORITY, visualizerThread, NULL);
383} 406}
384 407
385void update_status(bool changed) { 408void update_status(bool changed) {
@@ -445,6 +468,9 @@ void visualizer_update(uint32_t default_state, uint32_t state, uint8_t mods, uin
445 .default_layer = default_state, 468 .default_layer = default_state,
446 .mods = mods, 469 .mods = mods,
447 .leds = leds, 470 .leds = leds,
471#ifdef BACKLIGHT_ENABLE
472 .backlight_level = current_status.backlight_level,
473#endif
448 .suspended = current_status.suspended, 474 .suspended = current_status.suspended,
449 }; 475 };
450#ifdef VISUALIZER_USER_DATA_SIZE 476#ifdef VISUALIZER_USER_DATA_SIZE
@@ -467,3 +493,10 @@ void visualizer_resume(void) {
467 current_status.suspended = false; 493 current_status.suspended = false;
468 update_status(true); 494 update_status(true);
469} 495}
496
497#ifdef BACKLIGHT_ENABLE
498void backlight_set(uint8_t level) {
499 current_status.backlight_level = level;
500 update_status(true);
501}
502#endif
diff --git a/quantum/visualizer/visualizer.h b/quantum/visualizer/visualizer.h
index d6f279e10..90ecdcbae 100644
--- a/quantum/visualizer/visualizer.h
+++ b/quantum/visualizer/visualizer.h
@@ -28,12 +28,17 @@ SOFTWARE.
28#include <stdint.h> 28#include <stdint.h>
29#include <stdbool.h> 29#include <stdbool.h>
30 30
31#include "config.h"
31#include "gfx.h" 32#include "gfx.h"
32 33
33#ifdef LCD_BACKLIGHT_ENABLE 34#ifdef LCD_BACKLIGHT_ENABLE
34#include "lcd_backlight.h" 35#include "lcd_backlight.h"
35#endif 36#endif
36 37
38#ifdef BACKLIGHT_ENABLE
39#include "backlight.h"
40#endif
41
37// use this function to merge both real_mods and oneshot_mods in a uint16_t 42// use this function to merge both real_mods and oneshot_mods in a uint16_t
38uint8_t visualizer_get_mods(void); 43uint8_t visualizer_get_mods(void);
39 44
@@ -65,9 +70,12 @@ struct keyframe_animation_t;
65typedef struct { 70typedef struct {
66 uint32_t layer; 71 uint32_t layer;
67 uint32_t default_layer; 72 uint32_t default_layer;
68 uint8_t mods;
69 uint32_t leds; // See led.h for available statuses 73 uint32_t leds; // See led.h for available statuses
74 uint8_t mods;
70 bool suspended; 75 bool suspended;
76#ifdef BACKLIGHT_ENABLE
77 uint8_t backlight_level;
78#endif
71#ifdef VISUALIZER_USER_DATA_SIZE 79#ifdef VISUALIZER_USER_DATA_SIZE
72 uint8_t user_data[VISUALIZER_USER_DATA_SIZE]; 80 uint8_t user_data[VISUALIZER_USER_DATA_SIZE];
73#endif 81#endif
diff --git a/quantum/visualizer/visualizer.mk b/quantum/visualizer/visualizer.mk
index 5f710124b..0f7d8636c 100644
--- a/quantum/visualizer/visualizer.mk
+++ b/quantum/visualizer/visualizer.mk
@@ -42,9 +42,8 @@ SRC += $(VISUALIZER_DIR)/resources/lcd_logo.c
42OPT_DEFS += -DLCD_BACKLIGHT_ENABLE 42OPT_DEFS += -DLCD_BACKLIGHT_ENABLE
43endif 43endif
44 44
45ifeq ($(strip $(LED_ENABLE)), yes) 45ifeq ($(strip $(BACKLIGHT_ENABLE)), yes)
46SRC += $(VISUALIZER_DIR)/led_keyframes.c 46SRC += $(VISUALIZER_DIR)/led_keyframes.c
47OPT_DEFS += -DLED_ENABLE
48endif 47endif
49 48
50include $(GFXLIB)/gfx.mk 49include $(GFXLIB)/gfx.mk
@@ -52,19 +51,23 @@ GFXSRC := $(patsubst $(TOP_DIR)/%,%,$(GFXSRC))
52GFXDEFS := $(patsubst %,-D%,$(patsubst -D%,%,$(GFXDEFS))) 51GFXDEFS := $(patsubst %,-D%,$(patsubst -D%,%,$(GFXDEFS)))
53 52
54ifneq ("$(wildcard $(KEYMAP_PATH)/visualizer.c)","") 53ifneq ("$(wildcard $(KEYMAP_PATH)/visualizer.c)","")
55 SRC += keyboards/$(KEYBOARD)/keymaps/$(KEYMAP)/visualizer.c 54 SRC += keyboards/$(KEYBOARD)/keymaps/$(KEYMAP)/visualizer.c
56else 55else
57 ifeq ("$(wildcard $(SUBPROJECT_PATH)/keymaps/$(KEYMAP)/visualizer.c)","") 56 ifeq ("$(wildcard $(SUBPROJECT_PATH)/keymaps/$(KEYMAP)/visualizer.c)","")
58 ifeq ("$(wildcard $(SUBPROJECT_PATH)/visualizer.c)","") 57 ifeq ("$(wildcard $(SUBPROJECT_PATH)/visualizer.c)","")
59$(error "$(KEYMAP_PATH)/visualizer.c" does not exist) 58 ifeq ("$(wildcard $(KEYBOARD_PATH)/visualizer.c)","")
60 else 59$(error "visualizer.c" not found")
61 SRC += keyboards/$(KEYBOARD)/$(SUBPROJECT)/visualizer.c 60 else
62 endif 61 SRC += keyboards/$(KEYBOARD)/visualizer.c
63 else 62 endif
64 SRC += keyboards/$(KEYBOARD)/$(SUBPROJECT)/keymaps/$(KEYMAP)/visualizer.c 63 else
65 endif 64 SRC += keyboards/$(KEYBOARD)/$(SUBPROJECT)/visualizer.c
65 endif
66 else
67 SRC += keyboards/$(KEYBOARD)/$(SUBPROJECT)/keymaps/$(KEYMAP)/visualizer.c
68 endif
66endif 69endif
67 70
68ifdef EMULATOR 71ifdef EMULATOR
69UINCDIR += $(TMK_DIR)/common 72UINCDIR += $(TMK_DIR)/common
70endif \ No newline at end of file 73endif