aboutsummaryrefslogtreecommitdiff
path: root/quantum
diff options
context:
space:
mode:
Diffstat (limited to 'quantum')
-rw-r--r--quantum/analog.c69
-rw-r--r--quantum/analog.h52
-rw-r--r--quantum/audio/audio.c133
-rw-r--r--quantum/audio/audio.h8
-rw-r--r--quantum/audio/musical_notes.h7
-rw-r--r--quantum/audio/song_list.h84
-rw-r--r--quantum/config_common.h2
-rw-r--r--quantum/keymap_extras/keymap_steno.h76
-rw-r--r--quantum/keymap_extras/sendstring_colemak.h41
-rw-r--r--quantum/keymap_extras/sendstring_dvorak.h41
-rw-r--r--quantum/keymap_extras/sendstring_jis.h58
-rwxr-xr-xquantum/light_ws2812.c342
-rwxr-xr-xquantum/light_ws2812.h75
-rw-r--r--quantum/process_keycode/process_audio.c22
-rw-r--r--quantum/process_keycode/process_key_lock.c138
-rw-r--r--quantum/process_keycode/process_key_lock.h24
-rw-r--r--quantum/process_keycode/process_leader.c4
-rw-r--r--quantum/process_keycode/process_music.c153
-rw-r--r--quantum/process_keycode/process_music.h9
-rw-r--r--quantum/process_keycode/process_steno.c165
-rw-r--r--quantum/process_keycode/process_steno.h31
-rw-r--r--quantum/process_keycode/process_tap_dance.c18
-rw-r--r--quantum/process_keycode/process_tap_dance.h14
-rw-r--r--quantum/process_keycode/process_terminal.c252
-rw-r--r--quantum/process_keycode/process_terminal.h27
-rw-r--r--quantum/process_keycode/process_terminal_nop.h25
-rw-r--r--quantum/process_keycode/process_unicode_common.c6
-rw-r--r--quantum/process_keycode/process_unicode_common.h1
-rw-r--r--quantum/process_keycode/process_unicodemap.c4
-rw-r--r--quantum/quantum.c463
-rw-r--r--quantum/quantum.h39
-rw-r--r--quantum/quantum_keycodes.h38
-rw-r--r--quantum/rgblight.c81
-rw-r--r--quantum/rgblight.h14
-rw-r--r--quantum/send_string_keycodes.h168
-rw-r--r--quantum/template/config.h5
-rw-r--r--quantum/template/readme.md20
-rw-r--r--quantum/visualizer/common_gfxconf.h325
-rw-r--r--quantum/visualizer/default_animations.c176
-rw-r--r--quantum/visualizer/default_animations.h (renamed from quantum/visualizer/lcd_backlight_keyframes.h)18
-rw-r--r--quantum/visualizer/lcd_backlight_keyframes.c8
-rw-r--r--quantum/visualizer/lcd_keyframes.c4
-rw-r--r--quantum/visualizer/led_backlight_keyframes.c (renamed from quantum/visualizer/led_keyframes.c)24
-rw-r--r--quantum/visualizer/led_backlight_keyframes.h (renamed from quantum/visualizer/led_keyframes.h)22
-rw-r--r--quantum/visualizer/visualizer.c7
-rw-r--r--quantum/visualizer/visualizer.mk44
46 files changed, 2362 insertions, 975 deletions
diff --git a/quantum/analog.c b/quantum/analog.c
deleted file mode 100644
index 1ec38df75..000000000
--- a/quantum/analog.c
+++ /dev/null
@@ -1,69 +0,0 @@
1/* Copyright 2015 Jack Humbert
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// Simple analog to digitial conversion
18
19#include <avr/io.h>
20#include <avr/pgmspace.h>
21#include <stdint.h>
22#include "analog.h"
23
24
25static uint8_t aref = (1<<REFS0); // default to AREF = Vcc
26
27
28void analogReference(uint8_t mode)
29{
30 aref = mode & 0xC0;
31}
32
33
34// Arduino compatible pin input
35int16_t analogRead(uint8_t pin)
36{
37#if defined(__AVR_ATmega32U4__)
38 static const uint8_t PROGMEM pin_to_mux[] = {
39 0x00, 0x01, 0x04, 0x05, 0x06, 0x07,
40 0x25, 0x24, 0x23, 0x22, 0x21, 0x20};
41 if (pin >= 12) return 0;
42 return adc_read(pgm_read_byte(pin_to_mux + pin));
43#elif defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__)
44 if (pin >= 8) return 0;
45 return adc_read(pin);
46#else
47 return 0;
48#endif
49}
50
51// Mux input
52int16_t adc_read(uint8_t mux)
53{
54#if defined(__AVR_AT90USB162__)
55 return 0;
56#else
57 uint8_t low;
58
59 ADCSRA = (1<<ADEN) | ADC_PRESCALER; // enable ADC
60 ADCSRB = (1<<ADHSM) | (mux & 0x20); // high speed mode
61 ADMUX = aref | (mux & 0x1F); // configure mux input
62 ADCSRA = (1<<ADEN) | ADC_PRESCALER | (1<<ADSC); // start the conversion
63 while (ADCSRA & (1<<ADSC)) ; // wait for result
64 low = ADCL; // must read LSB first
65 return (ADCH << 8) | low; // must read MSB only once!
66#endif
67}
68
69
diff --git a/quantum/analog.h b/quantum/analog.h
deleted file mode 100644
index 8d93de7dc..000000000
--- a/quantum/analog.h
+++ /dev/null
@@ -1,52 +0,0 @@
1/* Copyright 2015 Jack Humbert
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 _analog_h_included__
18#define _analog_h_included__
19
20#include <stdint.h>
21
22void analogReference(uint8_t mode);
23int16_t analogRead(uint8_t pin);
24int16_t adc_read(uint8_t mux);
25
26#define ADC_REF_POWER (1<<REFS0)
27#define ADC_REF_INTERNAL ((1<<REFS1) | (1<<REFS0))
28#define ADC_REF_EXTERNAL (0)
29
30// These prescaler values are for high speed mode, ADHSM = 1
31#if F_CPU == 16000000L
32#define ADC_PRESCALER ((1<<ADPS2) | (1<<ADPS1))
33#elif F_CPU == 8000000L
34#define ADC_PRESCALER ((1<<ADPS2) | (1<<ADPS0))
35#elif F_CPU == 4000000L
36#define ADC_PRESCALER ((1<<ADPS2))
37#elif F_CPU == 2000000L
38#define ADC_PRESCALER ((1<<ADPS1) | (1<<ADPS0))
39#elif F_CPU == 1000000L
40#define ADC_PRESCALER ((1<<ADPS1))
41#else
42#define ADC_PRESCALER ((1<<ADPS0))
43#endif
44
45// some avr-libc versions do not properly define ADHSM
46#if defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__)
47#if !defined(ADHSM)
48#define ADHSM (7)
49#endif
50#endif
51
52#endif
diff --git a/quantum/audio/audio.c b/quantum/audio/audio.c
index c924f2bd5..e85326ff4 100644
--- a/quantum/audio/audio.c
+++ b/quantum/audio/audio.c
@@ -13,6 +13,7 @@
13 * You should have received a copy of the GNU General Public License 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/>. 14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */ 15 */
16
16#include <stdio.h> 17#include <stdio.h>
17#include <string.h> 18#include <string.h>
18//#include <math.h> 19//#include <math.h>
@@ -22,6 +23,7 @@
22#include "print.h" 23#include "print.h"
23#include "audio.h" 24#include "audio.h"
24#include "keymap.h" 25#include "keymap.h"
26#include "wait.h"
25 27
26#include "eeconfig.h" 28#include "eeconfig.h"
27 29
@@ -98,7 +100,6 @@ uint16_t note_position = 0;
98float (* notes_pointer)[][2]; 100float (* notes_pointer)[][2];
99uint16_t notes_count; 101uint16_t notes_count;
100bool notes_repeat; 102bool notes_repeat;
101float notes_rest;
102bool note_resting = false; 103bool note_resting = false;
103 104
104uint8_t current_note = 0; 105uint8_t current_note = 0;
@@ -119,6 +120,19 @@ audio_config_t audio_config;
119uint16_t envelope_index = 0; 120uint16_t envelope_index = 0;
120bool glissando = true; 121bool glissando = true;
121 122
123#ifndef STARTUP_SONG
124 #define STARTUP_SONG SONG(STARTUP_SOUND)
125#endif
126#ifndef AUDIO_ON_SONG
127 #define AUDIO_ON_SONG SONG(AUDIO_ON_SOUND)
128#endif
129#ifndef AUDIO_OFF_SONG
130 #define AUDIO_OFF_SONG SONG(AUDIO_OFF_SOUND)
131#endif
132float startup_song[][2] = STARTUP_SONG;
133float audio_on_song[][2] = AUDIO_ON_SONG;
134float audio_off_song[][2] = AUDIO_OFF_SONG;
135
122void audio_init() 136void audio_init()
123{ 137{
124 138
@@ -129,46 +143,54 @@ void audio_init()
129 } 143 }
130 audio_config.raw = eeconfig_read_audio(); 144 audio_config.raw = eeconfig_read_audio();
131 145
132 // Set port PC6 (OC3A and /OC4A) as output 146 if (!audio_initialized) {
133 147
134 #ifdef C6_AUDIO 148 // Set port PC6 (OC3A and /OC4A) as output
135 DDRC |= _BV(PORTC6);
136 #else
137 DDRC |= _BV(PORTC6);
138 PORTC &= ~_BV(PORTC6);
139 #endif
140 149
141 #ifdef B5_AUDIO 150 #ifdef C6_AUDIO
142 DDRB |= _BV(PORTB5); 151 DDRC |= _BV(PORTC6);
143 #else 152 #else
144 DDRB |= _BV(PORTB5); 153 DDRC |= _BV(PORTC6);
145 PORTB &= ~_BV(PORTB5); 154 PORTC &= ~_BV(PORTC6);
146 #endif 155 #endif
147 156
148 #ifdef C6_AUDIO 157 #ifdef B5_AUDIO
149 DISABLE_AUDIO_COUNTER_3_ISR; 158 DDRB |= _BV(PORTB5);
150 #endif 159 #else
151 160 DDRB |= _BV(PORTB5);
152 #ifdef B5_AUDIO 161 PORTB &= ~_BV(PORTB5);
153 DISABLE_AUDIO_COUNTER_1_ISR; 162 #endif
154 #endif 163
164 #ifdef C6_AUDIO
165 DISABLE_AUDIO_COUNTER_3_ISR;
166 #endif
167
168 #ifdef B5_AUDIO
169 DISABLE_AUDIO_COUNTER_1_ISR;
170 #endif
155 171
156 // TCCR3A / TCCR3B: Timer/Counter #3 Control Registers 172 // TCCR3A / TCCR3B: Timer/Counter #3 Control Registers
157 // Compare Output Mode (COM3An) = 0b00 = Normal port operation, OC3A disconnected from PC6 173 // Compare Output Mode (COM3An) = 0b00 = Normal port operation, OC3A disconnected from PC6
158 // Waveform Generation Mode (WGM3n) = 0b1110 = Fast PWM Mode 14 (Period = ICR3, Duty Cycle = OCR3A) 174 // Waveform Generation Mode (WGM3n) = 0b1110 = Fast PWM Mode 14 (Period = ICR3, Duty Cycle = OCR3A)
159 // Clock Select (CS3n) = 0b010 = Clock / 8 175 // Clock Select (CS3n) = 0b010 = Clock / 8
160 176
161 #ifdef C6_AUDIO 177 #ifdef C6_AUDIO
162 TCCR3A = (0 << COM3A1) | (0 << COM3A0) | (1 << WGM31) | (0 << WGM30); 178 TCCR3A = (0 << COM3A1) | (0 << COM3A0) | (1 << WGM31) | (0 << WGM30);
163 TCCR3B = (1 << WGM33) | (1 << WGM32) | (0 << CS32) | (1 << CS31) | (0 << CS30); 179 TCCR3B = (1 << WGM33) | (1 << WGM32) | (0 << CS32) | (1 << CS31) | (0 << CS30);
164 #endif 180 #endif
165 181
166 #ifdef B5_AUDIO 182 #ifdef B5_AUDIO
167 TCCR1A = (0 << COM1A1) | (0 << COM1A0) | (1 << WGM11) | (0 << WGM10); 183 TCCR1A = (0 << COM1A1) | (0 << COM1A0) | (1 << WGM11) | (0 << WGM10);
168 TCCR1B = (1 << WGM13) | (1 << WGM12) | (0 << CS12) | (1 << CS11) | (0 << CS10); 184 TCCR1B = (1 << WGM13) | (1 << WGM12) | (0 << CS12) | (1 << CS11) | (0 << CS10);
169 #endif 185 #endif
186
187 audio_initialized = true;
188 }
189
190 if (audio_config.enable) {
191 PLAY_SONG(startup_song);
192 }
170 193
171 audio_initialized = true;
172} 194}
173 195
174void stop_all_notes() 196void stop_all_notes()
@@ -402,9 +424,12 @@ ISR(TIMER3_COMPA_vect)
402 note_position++; 424 note_position++;
403 bool end_of_note = false; 425 bool end_of_note = false;
404 if (TIMER_3_PERIOD > 0) { 426 if (TIMER_3_PERIOD > 0) {
405 end_of_note = (note_position >= (note_length / TIMER_3_PERIOD * 0xFFFF)); 427 if (!note_resting)
428 end_of_note = (note_position >= (note_length / TIMER_3_PERIOD * 0xFFFF - 1));
429 else
430 end_of_note = (note_position >= (note_length));
406 } else { 431 } else {
407 end_of_note = (note_position >= (note_length * 0x7FF)); 432 end_of_note = (note_position >= (note_length));
408 } 433 }
409 434
410 if (end_of_note) { 435 if (end_of_note) {
@@ -419,11 +444,16 @@ ISR(TIMER3_COMPA_vect)
419 return; 444 return;
420 } 445 }
421 } 446 }
422 if (!note_resting && (notes_rest > 0)) { 447 if (!note_resting) {
423 note_resting = true; 448 note_resting = true;
424 note_frequency = 0;
425 note_length = notes_rest;
426 current_note--; 449 current_note--;
450 if ((*notes_pointer)[current_note][0] == (*notes_pointer)[current_note + 1][0]) {
451 note_frequency = 0;
452 note_length = 1;
453 } else {
454 note_frequency = (*notes_pointer)[current_note][0];
455 note_length = 1;
456 }
427 } else { 457 } else {
428 note_resting = false; 458 note_resting = false;
429 envelope_index = 0; 459 envelope_index = 0;
@@ -534,9 +564,12 @@ ISR(TIMER1_COMPA_vect)
534 note_position++; 564 note_position++;
535 bool end_of_note = false; 565 bool end_of_note = false;
536 if (TIMER_1_PERIOD > 0) { 566 if (TIMER_1_PERIOD > 0) {
537 end_of_note = (note_position >= (note_length / TIMER_1_PERIOD * 0xFFFF)); 567 if (!note_resting)
568 end_of_note = (note_position >= (note_length / TIMER_1_PERIOD * 0xFFFF - 1));
569 else
570 end_of_note = (note_position >= (note_length));
538 } else { 571 } else {
539 end_of_note = (note_position >= (note_length * 0x7FF)); 572 end_of_note = (note_position >= (note_length));
540 } 573 }
541 574
542 if (end_of_note) { 575 if (end_of_note) {
@@ -551,11 +584,16 @@ ISR(TIMER1_COMPA_vect)
551 return; 584 return;
552 } 585 }
553 } 586 }
554 if (!note_resting && (notes_rest > 0)) { 587 if (!note_resting) {
555 note_resting = true; 588 note_resting = true;
556 note_frequency = 0;
557 note_length = notes_rest;
558 current_note--; 589 current_note--;
590 if ((*notes_pointer)[current_note][0] == (*notes_pointer)[current_note + 1][0]) {
591 note_frequency = 0;
592 note_length = 1;
593 } else {
594 note_frequency = (*notes_pointer)[current_note][0];
595 note_length = 1;
596 }
559 } else { 597 } else {
560 note_resting = false; 598 note_resting = false;
561 envelope_index = 0; 599 envelope_index = 0;
@@ -624,7 +662,7 @@ void play_note(float freq, int vol) {
624 662
625} 663}
626 664
627void play_notes(float (*np)[][2], uint16_t n_count, bool n_repeat, float n_rest) 665void play_notes(float (*np)[][2], uint16_t n_count, bool n_repeat)
628{ 666{
629 667
630 if (!audio_initialized) { 668 if (!audio_initialized) {
@@ -649,7 +687,6 @@ void play_notes(float (*np)[][2], uint16_t n_count, bool n_repeat, float n_rest)
649 notes_pointer = np; 687 notes_pointer = np;
650 notes_count = n_count; 688 notes_count = n_count;
651 notes_repeat = n_repeat; 689 notes_repeat = n_repeat;
652 notes_rest = n_rest;
653 690
654 place = 0; 691 place = 0;
655 current_note = 0; 692 current_note = 0;
@@ -692,9 +729,13 @@ void audio_on(void) {
692 audio_config.enable = 1; 729 audio_config.enable = 1;
693 eeconfig_update_audio(audio_config.raw); 730 eeconfig_update_audio(audio_config.raw);
694 audio_on_user(); 731 audio_on_user();
732 PLAY_SONG(audio_on_song);
695} 733}
696 734
697void audio_off(void) { 735void audio_off(void) {
736 PLAY_SONG(audio_off_song);
737 wait_ms(100);
738 stop_all_notes();
698 audio_config.enable = 0; 739 audio_config.enable = 0;
699 eeconfig_update_audio(audio_config.raw); 740 eeconfig_update_audio(audio_config.raw);
700} 741}
diff --git a/quantum/audio/audio.h b/quantum/audio/audio.h
index 27fdc2ab6..79e0da229 100644
--- a/quantum/audio/audio.h
+++ b/quantum/audio/audio.h
@@ -86,7 +86,7 @@ void play_sample(uint8_t * s, uint16_t l, bool r);
86void play_note(float freq, int vol); 86void play_note(float freq, int vol);
87void stop_note(float freq); 87void stop_note(float freq);
88void stop_all_notes(void); 88void stop_all_notes(void);
89void play_notes(float (*np)[][2], uint16_t n_count, bool n_repeat, float n_rest); 89void play_notes(float (*np)[][2], uint16_t n_count, bool n_repeat);
90 90
91#define SCALE (int8_t []){ 0 + (12*0), 2 + (12*0), 4 + (12*0), 5 + (12*0), 7 + (12*0), 9 + (12*0), 11 + (12*0), \ 91#define SCALE (int8_t []){ 0 + (12*0), 2 + (12*0), 4 + (12*0), 5 + (12*0), 7 + (12*0), 9 + (12*0), 11 + (12*0), \
92 0 + (12*1), 2 + (12*1), 4 + (12*1), 5 + (12*1), 7 + (12*1), 9 + (12*1), 11 + (12*1), \ 92 0 + (12*1), 2 + (12*1), 4 + (12*1), 5 + (12*1), 7 + (12*1), 9 + (12*1), 11 + (12*1), \
@@ -98,8 +98,10 @@ void play_notes(float (*np)[][2], uint16_t n_count, bool n_repeat, float n_rest)
98// length. This works around the limitation of C's sizeof operation on pointers. 98// length. This works around the limitation of C's sizeof operation on pointers.
99// The global float array for the song must be used here. 99// The global float array for the song must be used here.
100#define NOTE_ARRAY_SIZE(x) ((int16_t)(sizeof(x) / (sizeof(x[0])))) 100#define NOTE_ARRAY_SIZE(x) ((int16_t)(sizeof(x) / (sizeof(x[0]))))
101#define PLAY_NOTE_ARRAY(note_array, note_repeat, note_rest_style) play_notes(&note_array, NOTE_ARRAY_SIZE((note_array)), (note_repeat), (note_rest_style)); 101#define PLAY_NOTE_ARRAY(note_array, note_repeat, deprecated_arg) play_notes(&note_array, NOTE_ARRAY_SIZE((note_array)), (note_repeat)); \
102 102 _Pragma ("message \"'PLAY_NOTE_ARRAY' macro is deprecated\"")
103#define PLAY_SONG(note_array) play_notes(&note_array, NOTE_ARRAY_SIZE((note_array)), false)
104#define PLAY_LOOP(note_array) play_notes(&note_array, NOTE_ARRAY_SIZE((note_array)), true)
103 105
104bool is_playing_notes(void); 106bool is_playing_notes(void);
105 107
diff --git a/quantum/audio/musical_notes.h b/quantum/audio/musical_notes.h
index a3aaa2f19..647b69564 100644
--- a/quantum/audio/musical_notes.h
+++ b/quantum/audio/musical_notes.h
@@ -51,12 +51,6 @@
51#define ED_NOTE(n) EIGHTH_DOT_NOTE(n) 51#define ED_NOTE(n) EIGHTH_DOT_NOTE(n)
52#define SD_NOTE(n) SIXTEENTH_DOT_NOTE(n) 52#define SD_NOTE(n) SIXTEENTH_DOT_NOTE(n)
53 53
54// Note Styles
55// Staccato makes sure there is a rest between each note. Think: TA TA TA
56// Legato makes notes flow together. Think: TAAA
57#define STACCATO 0.01
58#define LEGATO 0
59
60// Note Timbre 54// Note Timbre
61// Changes how the notes sound 55// Changes how the notes sound
62#define TIMBRE_12 0.125 56#define TIMBRE_12 0.125
@@ -65,7 +59,6 @@
65#define TIMBRE_75 0.750 59#define TIMBRE_75 0.750
66#define TIMBRE_DEFAULT TIMBRE_50 60#define TIMBRE_DEFAULT TIMBRE_50
67 61
68
69// Notes - # = Octave 62// Notes - # = Octave
70 63
71#define NOTE_REST 0.00 64#define NOTE_REST 0.00
diff --git a/quantum/audio/song_list.h b/quantum/audio/song_list.h
index db2d1a94c..afb82a298 100644
--- a/quantum/audio/song_list.h
+++ b/quantum/audio/song_list.h
@@ -18,9 +18,7 @@
18#ifndef SONG_LIST_H 18#ifndef SONG_LIST_H
19#define SONG_LIST_H 19#define SONG_LIST_H
20 20
21#define COIN_SOUND \ 21#define NO_SOUND
22 E__NOTE(_A5 ),\
23 HD_NOTE(_E6 ),
24 22
25#define ODE_TO_JOY \ 23#define ODE_TO_JOY \
26 Q__NOTE(_E4), Q__NOTE(_E4), Q__NOTE(_F4), Q__NOTE(_G4), \ 24 Q__NOTE(_E4), Q__NOTE(_E4), Q__NOTE(_F4), Q__NOTE(_G4), \
@@ -55,18 +53,29 @@
55 E__NOTE(_CS4), E__NOTE(_B4), QD_NOTE(_AS4), \ 53 E__NOTE(_CS4), E__NOTE(_B4), QD_NOTE(_AS4), \
56 E__NOTE(_AS4), E__NOTE(_AS4), QD_NOTE(_B4), 54 E__NOTE(_AS4), E__NOTE(_AS4), QD_NOTE(_B4),
57 55
56#define STARTUP_SOUND \
57 E__NOTE(_E6), \
58 E__NOTE(_A6), \
59 ED_NOTE(_E7),
60
58#define GOODBYE_SOUND \ 61#define GOODBYE_SOUND \
59 E__NOTE(_E7), \ 62 E__NOTE(_E7), \
60 E__NOTE(_A6), \ 63 E__NOTE(_A6), \
61 ED_NOTE(_E6), 64 ED_NOTE(_E6),
62 65
63#define STARTUP_SOUND \ 66#define PLANCK_SOUND \
64 ED_NOTE(_E7 ), \ 67 ED_NOTE(_E7 ), \
65 E__NOTE(_CS7), \ 68 E__NOTE(_CS7), \
66 E__NOTE(_E6 ), \ 69 E__NOTE(_E6 ), \
67 E__NOTE(_A6 ), \ 70 E__NOTE(_A6 ), \
68 M__NOTE(_CS7, 20), 71 M__NOTE(_CS7, 20),
69 72
73#define PREONIC_SOUND \
74 M__NOTE(_B5, 20), \
75 E__NOTE(_B6), \
76 M__NOTE(_DS6, 20), \
77 E__NOTE(_B6),
78
70#define QWERTY_SOUND \ 79#define QWERTY_SOUND \
71 E__NOTE(_GS6 ), \ 80 E__NOTE(_GS6 ), \
72 E__NOTE(_A6 ), \ 81 E__NOTE(_A6 ), \
@@ -107,7 +116,7 @@
107 S__NOTE(_REST), \ 116 S__NOTE(_REST), \
108 ED_NOTE(_E7 ), 117 ED_NOTE(_E7 ),
109 118
110#define MUSIC_SCALE_SOUND \ 119#define MUSIC_ON_SOUND \
111 E__NOTE(_A5 ), \ 120 E__NOTE(_A5 ), \
112 E__NOTE(_B5 ), \ 121 E__NOTE(_B5 ), \
113 E__NOTE(_CS6), \ 122 E__NOTE(_CS6), \
@@ -117,6 +126,58 @@
117 E__NOTE(_GS6), \ 126 E__NOTE(_GS6), \
118 E__NOTE(_A6 ), 127 E__NOTE(_A6 ),
119 128
129#define AUDIO_ON_SOUND \
130 E__NOTE(_A5 ), \
131 E__NOTE(_A6 ),
132
133#define AUDIO_OFF_SOUND \
134 E__NOTE(_A6 ), \
135 E__NOTE(_A5 ),
136
137#define MUSIC_SCALE_SOUND MUSIC_ON_SOUND
138
139#define MUSIC_OFF_SOUND \
140 E__NOTE(_A6 ), \
141 E__NOTE(_GS6 ), \
142 E__NOTE(_FS6), \
143 E__NOTE(_E6 ), \
144 E__NOTE(_D6 ), \
145 E__NOTE(_CS6), \
146 E__NOTE(_B5), \
147 E__NOTE(_A5 ),
148
149#define VOICE_CHANGE_SOUND \
150 Q__NOTE(_A5 ), \
151 Q__NOTE(_CS6), \
152 Q__NOTE(_E6 ), \
153 Q__NOTE(_A6 ),
154
155#define CHROMATIC_SOUND \
156 Q__NOTE(_A5 ), \
157 Q__NOTE(_AS5 ), \
158 Q__NOTE(_B5), \
159 Q__NOTE(_C6 ), \
160 Q__NOTE(_CS6 ),
161
162#define MAJOR_SOUND \
163 Q__NOTE(_A5 ), \
164 Q__NOTE(_B5 ), \
165 Q__NOTE(_CS6), \
166 Q__NOTE(_D6 ), \
167 Q__NOTE(_E6 ),
168
169#define GUITAR_SOUND \
170 Q__NOTE(_E5 ), \
171 Q__NOTE(_A5), \
172 Q__NOTE(_D6 ), \
173 Q__NOTE(_G6 ),
174
175#define VIOLIN_SOUND \
176 Q__NOTE(_G5 ), \
177 Q__NOTE(_D6), \
178 Q__NOTE(_A6 ), \
179 Q__NOTE(_E7 ),
180
120#define CAPS_LOCK_ON_SOUND \ 181#define CAPS_LOCK_ON_SOUND \
121 E__NOTE(_A3), \ 182 E__NOTE(_A3), \
122 E__NOTE(_B3), 183 E__NOTE(_B3),
@@ -141,6 +202,16 @@
141 E__NOTE(_E5), \ 202 E__NOTE(_E5), \
142 E__NOTE(_D5), 203 E__NOTE(_D5),
143 204
205#define AG_NORM_SOUND \
206 E__NOTE(_A5), \
207 E__NOTE(_A5),
208
209#define AG_SWAP_SOUND \
210 SD_NOTE(_B5), \
211 SD_NOTE(_A5), \
212 SD_NOTE(_B5), \
213 SD_NOTE(_A5),
214
144#define UNICODE_WINDOWS \ 215#define UNICODE_WINDOWS \
145 E__NOTE(_B5), \ 216 E__NOTE(_B5), \
146 S__NOTE(_E6), 217 S__NOTE(_E6),
@@ -176,4 +247,7 @@
176 Q__NOTE(_GS5), \ 247 Q__NOTE(_GS5), \
177 HD_NOTE(_C6), 248 HD_NOTE(_C6),
178 249
250#define TERMINAL_SOUND \
251 E__NOTE(_C5 )
252
179#endif 253#endif
diff --git a/quantum/config_common.h b/quantum/config_common.h
index c88e02d91..4c6a702af 100644
--- a/quantum/config_common.h
+++ b/quantum/config_common.h
@@ -100,4 +100,6 @@
100 100
101#define API_SYSEX_MAX_SIZE 32 101#define API_SYSEX_MAX_SIZE 32
102 102
103#include "song_list.h"
104
103#endif 105#endif
diff --git a/quantum/keymap_extras/keymap_steno.h b/quantum/keymap_extras/keymap_steno.h
new file mode 100644
index 000000000..4ce91cc13
--- /dev/null
+++ b/quantum/keymap_extras/keymap_steno.h
@@ -0,0 +1,76 @@
1/* Copyright 2017 Joseph Wasson
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#ifndef KEYMAP_STENO_H
17#define KEYMAP_STENO_H
18
19#include "keymap.h"
20
21// List of keycodes for the steno keyboard. To prevent
22// errors, this must be <= 42 total entries in order to
23// support the GeminiPR protocol.
24enum steno_keycodes {
25 STN__MIN = QK_STENO,
26 STN_FN = STN__MIN,
27 STN_NUM,
28 STN_N1 = STN_NUM,
29 STN_N2,
30 STN_N3,
31 STN_N4,
32 STN_N5,
33 STN_N6,
34 STN_SL,
35 STN_S1 = STN_SL,
36 STN_S2,
37 STN_TL,
38 STN_KL,
39 STN_PL,
40 STN_WL,
41 STN_HL,
42 STN_RL,
43 STN_A,
44 STN_O,
45 STN_STR,
46 STN_ST1 = STN_STR,
47 STN_ST2,
48 STN_RES1,
49 STN_RE1 = STN_RES1,
50 STN_RES2,
51 STN_RE2 = STN_RES2,
52 STN_PWR,
53 STN_ST3,
54 STN_ST4,
55 STN_E,
56 STN_U,
57 STN_FR,
58 STN_RR,
59 STN_PR,
60 STN_BR,
61 STN_LR,
62 STN_GR,
63 STN_TR,
64 STN_SR,
65 STN_DR,
66 STN_N7,
67 STN_N8,
68 STN_N9,
69 STN_NA,
70 STN_NB,
71 STN_NC,
72 STN_ZR,
73 STN__MAX = STN_ZR, // must be less than QK_STENO_BOLT
74};
75
76#endif
diff --git a/quantum/keymap_extras/sendstring_colemak.h b/quantum/keymap_extras/sendstring_colemak.h
new file mode 100644
index 000000000..fa9ace929
--- /dev/null
+++ b/quantum/keymap_extras/sendstring_colemak.h
@@ -0,0 +1,41 @@
1/* Copyright 2016 Jack Humbert
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/* Sendstring definitions for the Colemak layout */
17#ifndef SENDSTRING_COLEMAK
18#define SENDSTRING_COLEMAK
19
20#include "keymap_colemak.h"
21
22const uint8_t ascii_to_keycode_lut[0x80] PROGMEM = {
23 0, 0, 0, 0, 0, 0, 0, 0,
24 KC_BSPC, KC_TAB, KC_ENT, 0, 0, 0, 0, 0,
25 0, 0, 0, 0, 0, 0, 0, 0,
26 0, 0, 0, KC_ESC, 0, 0, 0, 0,
27 KC_SPC, KC_1, KC_QUOT, KC_3, KC_4, KC_5, KC_7, KC_QUOT,
28 KC_9, KC_0, KC_8, KC_EQL, KC_COMM, KC_MINS, KC_DOT, KC_SLSH,
29 KC_0, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7,
30 KC_8, KC_9, CM_SCLN, CM_SCLN, KC_COMM, KC_EQL, KC_DOT, KC_SLSH,
31 KC_2, CM_A, CM_B, CM_C, CM_D, CM_E, CM_F, CM_G,
32 CM_H, CM_I, CM_J, CM_K, CM_L, CM_M, CM_N, CM_O,
33 CM_P, CM_Q, CM_R, CM_S, CM_T, CM_U, CM_V, CM_W,
34 CM_X, CM_Y, CM_Z, KC_LBRC, KC_BSLS, KC_RBRC, KC_6, KC_MINS,
35 KC_GRV, CM_A, CM_B, CM_C, CM_D, CM_E, CM_F, CM_G,
36 CM_H, CM_I, CM_J, CM_K, CM_L, CM_M, CM_N, CM_O,
37 CM_P, CM_Q, CM_R, CM_S, CM_T, CM_U, CM_V, CM_W,
38 CM_X, CM_Y, CM_Z, KC_LBRC, KC_BSLS, KC_RBRC, KC_GRV, KC_DEL
39};
40
41#endif
diff --git a/quantum/keymap_extras/sendstring_dvorak.h b/quantum/keymap_extras/sendstring_dvorak.h
new file mode 100644
index 000000000..f5c5c818b
--- /dev/null
+++ b/quantum/keymap_extras/sendstring_dvorak.h
@@ -0,0 +1,41 @@
1/* Copyright 2016 Jack Humbert
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/* Sendstring definitions for the Dvorak layout */
17#ifndef SENDSTRING_DVORAK
18#define SENDSTRING_DVORAK
19
20#include "keymap_dvorak.h"
21
22const uint8_t ascii_to_keycode_lut[0x80] PROGMEM = {
23 0, 0, 0, 0, 0, 0, 0, 0,
24 KC_BSPC, KC_TAB, KC_ENT, 0, 0, 0, 0, 0,
25 0, 0, 0, 0, 0, 0, 0, 0,
26 0, 0, 0, KC_ESC, 0, 0, 0, 0,
27 KC_SPC, DV_1, DV_QUOT, DV_3, DV_4, DV_5, DV_7, DV_QUOT,
28 DV_9, DV_0, DV_8, DV_EQL, DV_COMM, DV_MINS, DV_DOT, DV_SLSH,
29 DV_0, DV_1, DV_2, DV_3, DV_4, DV_5, DV_6, DV_7,
30 DV_8, DV_9, DV_SCLN, DV_SCLN, DV_COMM, DV_EQL, DV_DOT, DV_SLSH,
31 DV_2, DV_A, DV_B, DV_C, DV_D, DV_E, DV_F, DV_G,
32 DV_H, DV_I, DV_J, DV_K, DV_L, DV_M, DV_N, DV_O,
33 DV_P, DV_Q, DV_R, DV_S, DV_T, DV_U, DV_V, DV_W,
34 DV_X, DV_Y, DV_Z, DV_LBRC, DV_BSLS, DV_RBRC, DV_6, DV_MINS,
35 DV_GRV, DV_A, DV_B, DV_C, DV_D, DV_E, DV_F, DV_G,
36 DV_H, DV_I, DV_J, DV_K, DV_L, DV_M, DV_N, DV_O,
37 DV_P, DV_Q, DV_R, DV_S, DV_T, DV_U, DV_V, DV_W,
38 DV_X, DV_Y, DV_Z, DV_LBRC, DV_BSLS, DV_RBRC, DV_GRV, KC_DEL
39};
40
41#endif
diff --git a/quantum/keymap_extras/sendstring_jis.h b/quantum/keymap_extras/sendstring_jis.h
new file mode 100644
index 000000000..c5a38c6a5
--- /dev/null
+++ b/quantum/keymap_extras/sendstring_jis.h
@@ -0,0 +1,58 @@
1/* Copyright 2016 Jack Humbert
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/* Sendstring definitions for the JIS keyboard layout */
17#ifndef SENDSTRING_JIS
18#define SENDSTRING_JIS
19
20const bool ascii_to_shift_lut[0x80] PROGMEM = {
21 0, 0, 0, 0, 0, 0, 0, 0,
22 0, 0, 0, 0, 0, 0, 0, 0,
23 0, 0, 0, 0, 0, 0, 0, 0,
24 0, 0, 0, 0, 0, 0, 0, 0,
25 0, 1, 1, 1, 1, 1, 1, 1,
26 1, 1, 1, 1, 0, 0, 0, 0,
27 0, 0, 0, 0, 0, 0, 0, 0,
28 0, 0, 0, 0, 1, 1, 1, 1,
29 0, 1, 1, 1, 1, 1, 1, 1,
30 1, 1, 1, 1, 1, 1, 1, 1,
31 1, 1, 1, 1, 1, 1, 1, 1,
32 1, 1, 1, 0, 0, 0, 0, 1,
33 1, 0, 0, 0, 0, 0, 0, 0,
34 0, 0, 0, 0, 0, 0, 0, 0,
35 0, 0, 0, 0, 0, 0, 0, 0,
36 0, 0, 0, 1, 1, 1, 1, 0
37};
38
39const uint8_t ascii_to_keycode_lut[0x80] PROGMEM = {
40 0, 0, 0, 0, 0, 0, 0, 0,
41 KC_BSPC, KC_TAB, KC_ENT, 0, 0, 0, 0, 0,
42 0, 0, 0, 0, 0, 0, 0, 0,
43 0, 0, 0, KC_ESC, 0, 0, 0, 0,
44 KC_SPC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7,
45 KC_8, KC_9, KC_QUOT, KC_SCLN, KC_COMM, KC_MINS, KC_DOT, KC_SLSH,
46 KC_0, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7,
47 KC_8, KC_9, KC_QUOT, KC_SCLN, KC_COMM, KC_MINS, KC_DOT, KC_SLSH,
48 KC_LBRC, KC_A, KC_B, KC_C, KC_D, KC_E, KC_F, KC_G,
49 KC_H, KC_I, KC_J, KC_K, KC_L, KC_M, KC_N, KC_O,
50 KC_P, KC_Q, KC_R, KC_S, KC_T, KC_U, KC_V, KC_W,
51 KC_X, KC_Y, KC_Z, KC_RBRC, KC_JYEN, KC_BSLS, KC_EQL, KC_RO,
52 KC_LBRC, KC_A, KC_B, KC_C, KC_D, KC_E, KC_F, KC_G,
53 KC_H, KC_I, KC_J, KC_K, KC_L, KC_M, KC_N, KC_O,
54 KC_P, KC_Q, KC_R, KC_S, KC_T, KC_U, KC_V, KC_W,
55 KC_X, KC_Y, KC_Z, KC_RBRC, KC_JYEN, KC_BSLS, KC_EQL, KC_DEL,
56};
57
58#endif
diff --git a/quantum/light_ws2812.c b/quantum/light_ws2812.c
deleted file mode 100755
index 2506e3d8e..000000000
--- a/quantum/light_ws2812.c
+++ /dev/null
@@ -1,342 +0,0 @@
1/*
2* light weight WS2812 lib V2.0b
3*
4* Controls WS2811/WS2812/WS2812B RGB-LEDs
5* Author: Tim (cpldcpu@gmail.com)
6*
7* Jan 18th, 2014 v2.0b Initial Version
8* Nov 29th, 2015 v2.3 Added SK6812RGBW support
9*
10* This program is free software: you can redistribute it and/or modify
11* it under the terms of the GNU General Public License as published by
12* the Free Software Foundation, either version 2 of the License, or
13* (at your option) any later version.
14*
15* This program is distributed in the hope that it will be useful,
16* but WITHOUT ANY WARRANTY; without even the implied warranty of
17* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18* GNU General Public License for more details.
19*
20* You should have received a copy of the GNU General Public License
21* along with this program. If not, see <http://www.gnu.org/licenses/>.
22*/
23
24#include "light_ws2812.h"
25#include <avr/interrupt.h>
26#include <avr/io.h>
27#include <util/delay.h>
28#include "debug.h"
29
30#ifdef RGBW_BB_TWI
31
32// Port for the I2C
33#define I2C_DDR DDRD
34#define I2C_PIN PIND
35#define I2C_PORT PORTD
36
37// Pins to be used in the bit banging
38#define I2C_CLK 0
39#define I2C_DAT 1
40
41#define I2C_DATA_HI()\
42I2C_DDR &= ~ (1 << I2C_DAT);\
43I2C_PORT |= (1 << I2C_DAT);
44#define I2C_DATA_LO()\
45I2C_DDR |= (1 << I2C_DAT);\
46I2C_PORT &= ~ (1 << I2C_DAT);
47
48#define I2C_CLOCK_HI()\
49I2C_DDR &= ~ (1 << I2C_CLK);\
50I2C_PORT |= (1 << I2C_CLK);
51#define I2C_CLOCK_LO()\
52I2C_DDR |= (1 << I2C_CLK);\
53I2C_PORT &= ~ (1 << I2C_CLK);
54
55#define I2C_DELAY 1
56
57void I2C_WriteBit(unsigned char c)
58{
59 if (c > 0)
60 {
61 I2C_DATA_HI();
62 }
63 else
64 {
65 I2C_DATA_LO();
66 }
67
68 I2C_CLOCK_HI();
69 _delay_us(I2C_DELAY);
70
71 I2C_CLOCK_LO();
72 _delay_us(I2C_DELAY);
73
74 if (c > 0)
75 {
76 I2C_DATA_LO();
77 }
78
79 _delay_us(I2C_DELAY);
80}
81
82// Inits bitbanging port, must be called before using the functions below
83//
84void I2C_Init(void)
85{
86 I2C_PORT &= ~ ((1 << I2C_DAT) | (1 << I2C_CLK));
87
88 I2C_CLOCK_HI();
89 I2C_DATA_HI();
90
91 _delay_us(I2C_DELAY);
92}
93
94// Send a START Condition
95//
96void I2C_Start(void)
97{
98 // set both to high at the same time
99 I2C_DDR &= ~ ((1 << I2C_DAT) | (1 << I2C_CLK));
100 _delay_us(I2C_DELAY);
101
102 I2C_DATA_LO();
103 _delay_us(I2C_DELAY);
104
105 I2C_CLOCK_LO();
106 _delay_us(I2C_DELAY);
107}
108
109// Send a STOP Condition
110//
111void I2C_Stop(void)
112{
113 I2C_CLOCK_HI();
114 _delay_us(I2C_DELAY);
115
116 I2C_DATA_HI();
117 _delay_us(I2C_DELAY);
118}
119
120// write a byte to the I2C slave device
121//
122unsigned char I2C_Write(unsigned char c)
123{
124 for (char i = 0; i < 8; i++)
125 {
126 I2C_WriteBit(c & 128);
127
128 c <<= 1;
129 }
130
131
132 I2C_WriteBit(0);
133 _delay_us(I2C_DELAY);
134 _delay_us(I2C_DELAY);
135
136 // _delay_us(I2C_DELAY);
137 //return I2C_ReadBit();
138 return 0;
139}
140
141
142#endif
143
144// Setleds for standard RGB
145void inline ws2812_setleds(LED_TYPE *ledarray, uint16_t leds)
146{
147 // ws2812_setleds_pin(ledarray,leds, _BV(ws2812_pin));
148 ws2812_setleds_pin(ledarray,leds, _BV(RGB_DI_PIN & 0xF));
149}
150
151void inline ws2812_setleds_pin(LED_TYPE *ledarray, uint16_t leds, uint8_t pinmask)
152{
153 // ws2812_DDRREG |= pinmask; // Enable DDR
154 // new universal format (DDR)
155 _SFR_IO8((RGB_DI_PIN >> 4) + 1) |= pinmask;
156
157 ws2812_sendarray_mask((uint8_t*)ledarray,leds+leds+leds,pinmask);
158 _delay_us(50);
159}
160
161// Setleds for SK6812RGBW
162void inline ws2812_setleds_rgbw(LED_TYPE *ledarray, uint16_t leds)
163{
164
165 #ifdef RGBW_BB_TWI
166 uint8_t sreg_prev, twcr_prev;
167 sreg_prev=SREG;
168 twcr_prev=TWCR;
169 cli();
170 TWCR &= ~(1<<TWEN);
171 I2C_Init();
172 I2C_Start();
173 I2C_Write(0x84);
174 uint16_t datlen = leds<<2;
175 uint8_t curbyte;
176 uint8_t * data = (uint8_t*)ledarray;
177 while (datlen--) {
178 curbyte=*data++;
179 I2C_Write(curbyte);
180 }
181 I2C_Stop();
182 SREG=sreg_prev;
183 TWCR=twcr_prev;
184 #endif
185
186
187 // ws2812_DDRREG |= _BV(ws2812_pin); // Enable DDR
188 // new universal format (DDR)
189 _SFR_IO8((RGB_DI_PIN >> 4) + 1) |= _BV(RGB_DI_PIN & 0xF);
190
191 ws2812_sendarray_mask((uint8_t*)ledarray,leds<<2,_BV(RGB_DI_PIN & 0xF));
192
193
194 #ifndef RGBW_BB_TWI
195 _delay_us(80);
196 #endif
197}
198
199void ws2812_sendarray(uint8_t *data,uint16_t datlen)
200{
201 ws2812_sendarray_mask(data,datlen,_BV(RGB_DI_PIN & 0xF));
202}
203
204/*
205 This routine writes an array of bytes with RGB values to the Dataout pin
206 using the fast 800kHz clockless WS2811/2812 protocol.
207*/
208
209// Timing in ns
210#define w_zeropulse 350
211#define w_onepulse 900
212#define w_totalperiod 1250
213
214// Fixed cycles used by the inner loop
215#define w_fixedlow 2
216#define w_fixedhigh 4
217#define w_fixedtotal 8
218
219// Insert NOPs to match the timing, if possible
220#define w_zerocycles (((F_CPU/1000)*w_zeropulse )/1000000)
221#define w_onecycles (((F_CPU/1000)*w_onepulse +500000)/1000000)
222#define w_totalcycles (((F_CPU/1000)*w_totalperiod +500000)/1000000)
223
224// w1 - nops between rising edge and falling edge - low
225#define w1 (w_zerocycles-w_fixedlow)
226// w2 nops between fe low and fe high
227#define w2 (w_onecycles-w_fixedhigh-w1)
228// w3 nops to complete loop
229#define w3 (w_totalcycles-w_fixedtotal-w1-w2)
230
231#if w1>0
232 #define w1_nops w1
233#else
234 #define w1_nops 0
235#endif
236
237// The only critical timing parameter is the minimum pulse length of the "0"
238// Warn or throw error if this timing can not be met with current F_CPU settings.
239#define w_lowtime ((w1_nops+w_fixedlow)*1000000)/(F_CPU/1000)
240#if w_lowtime>550
241 #error "Light_ws2812: Sorry, the clock speed is too low. Did you set F_CPU correctly?"
242#elif w_lowtime>450
243 #warning "Light_ws2812: The timing is critical and may only work on WS2812B, not on WS2812(S)."
244 #warning "Please consider a higher clockspeed, if possible"
245#endif
246
247#if w2>0
248#define w2_nops w2
249#else
250#define w2_nops 0
251#endif
252
253#if w3>0
254#define w3_nops w3
255#else
256#define w3_nops 0
257#endif
258
259#define w_nop1 "nop \n\t"
260#define w_nop2 "rjmp .+0 \n\t"
261#define w_nop4 w_nop2 w_nop2
262#define w_nop8 w_nop4 w_nop4
263#define w_nop16 w_nop8 w_nop8
264
265void inline ws2812_sendarray_mask(uint8_t *data,uint16_t datlen,uint8_t maskhi)
266{
267 uint8_t curbyte,ctr,masklo;
268 uint8_t sreg_prev;
269
270 // masklo =~maskhi&ws2812_PORTREG;
271 // maskhi |= ws2812_PORTREG;
272 masklo =~maskhi&_SFR_IO8((RGB_DI_PIN >> 4) + 2);
273 maskhi |= _SFR_IO8((RGB_DI_PIN >> 4) + 2);
274 sreg_prev=SREG;
275 cli();
276
277 while (datlen--) {
278 curbyte=(*data++);
279
280 asm volatile(
281 " ldi %0,8 \n\t"
282 "loop%=: \n\t"
283 " out %2,%3 \n\t" // '1' [01] '0' [01] - re
284#if (w1_nops&1)
285w_nop1
286#endif
287#if (w1_nops&2)
288w_nop2
289#endif
290#if (w1_nops&4)
291w_nop4
292#endif
293#if (w1_nops&8)
294w_nop8
295#endif
296#if (w1_nops&16)
297w_nop16
298#endif
299 " sbrs %1,7 \n\t" // '1' [03] '0' [02]
300 " out %2,%4 \n\t" // '1' [--] '0' [03] - fe-low
301 " lsl %1 \n\t" // '1' [04] '0' [04]
302#if (w2_nops&1)
303 w_nop1
304#endif
305#if (w2_nops&2)
306 w_nop2
307#endif
308#if (w2_nops&4)
309 w_nop4
310#endif
311#if (w2_nops&8)
312 w_nop8
313#endif
314#if (w2_nops&16)
315 w_nop16
316#endif
317 " out %2,%4 \n\t" // '1' [+1] '0' [+1] - fe-high
318#if (w3_nops&1)
319w_nop1
320#endif
321#if (w3_nops&2)
322w_nop2
323#endif
324#if (w3_nops&4)
325w_nop4
326#endif
327#if (w3_nops&8)
328w_nop8
329#endif
330#if (w3_nops&16)
331w_nop16
332#endif
333
334 " dec %0 \n\t" // '1' [+2] '0' [+2]
335 " brne loop%=\n\t" // '1' [+3] '0' [+4]
336 : "=&d" (ctr)
337 : "r" (curbyte), "I" (_SFR_IO_ADDR(_SFR_IO8((RGB_DI_PIN >> 4) + 2))), "r" (maskhi), "r" (masklo)
338 );
339 }
340
341 SREG=sreg_prev;
342}
diff --git a/quantum/light_ws2812.h b/quantum/light_ws2812.h
deleted file mode 100755
index f7e0c3144..000000000
--- a/quantum/light_ws2812.h
+++ /dev/null
@@ -1,75 +0,0 @@
1/*
2 * light weight WS2812 lib include
3 *
4 * Version 2.3 - Nev 29th 2015
5 * Author: Tim (cpldcpu@gmail.com)
6 *
7 * Please do not change this file! All configuration is handled in "ws2812_config.h"
8 *
9 * This program is free software: you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation, either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 */
22
23#ifndef LIGHT_WS2812_H_
24#define LIGHT_WS2812_H_
25
26#include <avr/io.h>
27#include <avr/interrupt.h>
28//#include "ws2812_config.h"
29//#include "i2cmaster.h"
30
31#include "rgblight_types.h"
32
33
34/* User Interface
35 *
36 * Input:
37 * ledarray: An array of GRB data describing the LED colors
38 * number_of_leds: The number of LEDs to write
39 * pinmask (optional): Bitmask describing the output bin. e.g. _BV(PB0)
40 *
41 * The functions will perform the following actions:
42 * - Set the data-out pin as output
43 * - Send out the LED data
44 * - Wait 50�s to reset the LEDs
45 */
46
47void ws2812_setleds (LED_TYPE *ledarray, uint16_t number_of_leds);
48void ws2812_setleds_pin (LED_TYPE *ledarray, uint16_t number_of_leds,uint8_t pinmask);
49void ws2812_setleds_rgbw(LED_TYPE *ledarray, uint16_t number_of_leds);
50
51/*
52 * Old interface / Internal functions
53 *
54 * The functions take a byte-array and send to the data output as WS2812 bitstream.
55 * The length is the number of bytes to send - three per LED.
56 */
57
58void ws2812_sendarray (uint8_t *array,uint16_t length);
59void ws2812_sendarray_mask(uint8_t *array,uint16_t length, uint8_t pinmask);
60
61
62/*
63 * Internal defines
64 */
65#ifndef CONCAT
66#define CONCAT(a, b) a ## b
67#endif
68#ifndef CONCAT_EXP
69#define CONCAT_EXP(a, b) CONCAT(a, b)
70#endif
71
72// #define ws2812_PORTREG CONCAT_EXP(PORT,ws2812_port)
73// #define ws2812_DDRREG CONCAT_EXP(DDR,ws2812_port)
74
75#endif /* LIGHT_WS2812_H_ */
diff --git a/quantum/process_keycode/process_audio.c b/quantum/process_keycode/process_audio.c
index 0b6380ed3..32057ae8d 100644
--- a/quantum/process_keycode/process_audio.c
+++ b/quantum/process_keycode/process_audio.c
@@ -1,10 +1,19 @@
1#include "audio.h" 1#include "audio.h"
2#include "process_audio.h" 2#include "process_audio.h"
3 3
4#ifndef VOICE_CHANGE_SONG
5 #define VOICE_CHANGE_SONG SONG(VOICE_CHANGE_SOUND)
6#endif
7float voice_change_song[][2] = VOICE_CHANGE_SONG;
8
9#ifndef PITCH_STANDARD_A
10 #define PITCH_STANDARD_A 440.0f
11#endif
12
4static float compute_freq_for_midi_note(uint8_t note) 13static float compute_freq_for_midi_note(uint8_t note)
5{ 14{
6 // https://en.wikipedia.org/wiki/MIDI_tuning_standard 15 // https://en.wikipedia.org/wiki/MIDI_tuning_standard
7 return pow(2.0, (note - 69) / 12.0) * 440.0f; 16 return pow(2.0, (note - 69) / 12.0) * PITCH_STANDARD_A;
8} 17}
9 18
10bool process_audio(uint16_t keycode, keyrecord_t *record) { 19bool process_audio(uint16_t keycode, keyrecord_t *record) {
@@ -20,12 +29,9 @@ bool process_audio(uint16_t keycode, keyrecord_t *record) {
20 } 29 }
21 30
22 if (keycode == AU_TOG && record->event.pressed) { 31 if (keycode == AU_TOG && record->event.pressed) {
23 if (is_audio_on()) 32 if (is_audio_on()) {
24 {
25 audio_off(); 33 audio_off();
26 } 34 } else {
27 else
28 {
29 audio_on(); 35 audio_on();
30 } 36 }
31 return false; 37 return false;
@@ -33,13 +39,13 @@ bool process_audio(uint16_t keycode, keyrecord_t *record) {
33 39
34 if (keycode == MUV_IN && record->event.pressed) { 40 if (keycode == MUV_IN && record->event.pressed) {
35 voice_iterate(); 41 voice_iterate();
36 music_scale_user(); 42 PLAY_SONG(voice_change_song);
37 return false; 43 return false;
38 } 44 }
39 45
40 if (keycode == MUV_DE && record->event.pressed) { 46 if (keycode == MUV_DE && record->event.pressed) {
41 voice_deiterate(); 47 voice_deiterate();
42 music_scale_user(); 48 PLAY_SONG(voice_change_song);
43 return false; 49 return false;
44 } 50 }
45 51
diff --git a/quantum/process_keycode/process_key_lock.c b/quantum/process_keycode/process_key_lock.c
new file mode 100644
index 000000000..d7978f91c
--- /dev/null
+++ b/quantum/process_keycode/process_key_lock.c
@@ -0,0 +1,138 @@
1/* Copyright 2017 Fredric Silberberg
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#include "inttypes.h"
18#include "stdint.h"
19#include "process_key_lock.h"
20
21#define BV_64(shift) (((uint64_t)1) << (shift))
22#define GET_KEY_ARRAY(code) (((code) < 0x40) ? key_state[0] : \
23 ((code) < 0x80) ? key_state[1] : \
24 ((code) < 0xC0) ? key_state[2] : key_state[3])
25#define GET_CODE_INDEX(code) (((code) < 0x40) ? (code) : \
26 ((code) < 0x80) ? (code) - 0x40 : \
27 ((code) < 0xC0) ? (code) - 0x80 : (code) - 0xC0)
28#define KEY_STATE(code) (GET_KEY_ARRAY(code) & BV_64(GET_CODE_INDEX(code))) == BV_64(GET_CODE_INDEX(code))
29#define SET_KEY_ARRAY_STATE(code, val) do { \
30 switch (code) { \
31 case 0x00 ... 0x3F: \
32 key_state[0] = (val); \
33 break; \
34 case 0x40 ... 0x7F: \
35 key_state[1] = (val); \
36 break; \
37 case 0x80 ... 0xBF: \
38 key_state[2] = (val); \
39 break; \
40 case 0xC0 ... 0xFF: \
41 key_state[3] = (val); \
42 break; \
43 } \
44} while(0)
45#define SET_KEY_STATE(code) SET_KEY_ARRAY_STATE(code, (GET_KEY_ARRAY(code) | BV_64(GET_CODE_INDEX(code))))
46#define UNSET_KEY_STATE(code) SET_KEY_ARRAY_STATE(code, (GET_KEY_ARRAY(code)) & ~(BV_64(GET_CODE_INDEX(code))))
47#define IS_STANDARD_KEYCODE(code) ((code) <= 0xFF)
48
49// Locked key state. This is an array of 256 bits, one for each of the standard keys supported qmk.
50uint64_t key_state[4] = { 0x0, 0x0, 0x0, 0x0 };
51bool watching = false;
52
53// Translate any OSM keycodes back to their unmasked versions.
54uint16_t inline translate_keycode(uint16_t keycode) {
55 if (keycode > QK_ONE_SHOT_MOD && keycode <= QK_ONE_SHOT_MOD_MAX) {
56 return keycode ^ QK_ONE_SHOT_MOD;
57 } else {
58 return keycode;
59 }
60}
61
62bool process_key_lock(uint16_t *keycode, keyrecord_t *record) {
63 // We start by categorizing the keypress event. In the event of a down
64 // event, there are several possibilities:
65 // 1. The key is not being locked, and we are not watching for new keys.
66 // In this case, we bail immediately. This is the common case for down events.
67 // 2. The key was locked, and we need to unlock it. In this case, we will
68 // reset the state in our map and return false. When the user releases the
69 // key, the up event will no longer be masked and the OS will observe the
70 // released key.
71 // 3. KC_LOCK was just pressed. In this case, we set up the state machine
72 // to watch for the next key down event, and finish processing
73 // 4. The keycode is below 0xFF, and we are watching for new keys. In this case,
74 // we will send the key down event to the os, and set the key_state for that
75 // key to mask the up event.
76 // 5. The keycode is above 0xFF, and we're wathing for new keys. In this case,
77 // the user pressed a key that we cannot "lock", as it's a series of keys,
78 // or a macro invocation, or a layer transition, or a custom-defined key, or
79 // or some other arbitrary code. In this case, we bail immediately, reset
80 // our watch state, and return true.
81 //
82 // In the event of an up event, there are these possibilities:
83 // 1. The key is not being locked. In this case, we return true and bail
84 // immediately. This is the common case.
85 // 2. The key is being locked. In this case, we will mask the up event
86 // by returning false, so the OS never sees that the key was released
87 // until the user pressed the key again.
88
89 // We translate any OSM keycodes back to their original keycodes, so that if the key being
90 // one-shot modded is a standard keycode, we can handle it. This is the only set of special
91 // keys that we handle
92 uint16_t translated_keycode = translate_keycode(*keycode);
93
94 if (record->event.pressed) {
95 // Non-standard keycode, reset and return
96 if (!(IS_STANDARD_KEYCODE(translated_keycode) || translated_keycode == KC_LOCK)) {
97 watching = false;
98 return true;
99 }
100
101 // If we're already watching, turn off the watch.
102 if (translated_keycode == KC_LOCK) {
103 watching = !watching;
104 return false;
105 }
106
107 if (IS_STANDARD_KEYCODE(translated_keycode)) {
108 // We check watching first. This is so that in the following scenario, we continue to
109 // hold the key: KC_LOCK, KC_F, KC_LOCK, KC_F
110 // If we checked in reverse order, we'd end up holding the key pressed after the second
111 // KC_F press is registered, when the user likely meant to hold F
112 if (watching) {
113 watching = false;
114 SET_KEY_STATE(translated_keycode);
115 // We need to set the keycode passed in to be the translated keycode, in case we
116 // translated a OSM back to the original keycode.
117 *keycode = translated_keycode;
118 // Let the standard keymap send the keycode down event. The up event will be masked.
119 return true;
120 }
121
122 if (KEY_STATE(translated_keycode)) {
123 UNSET_KEY_STATE(translated_keycode);
124 // The key is already held, stop this process. The up event will be sent when the user
125 // releases the key.
126 return false;
127 }
128 }
129
130 // Either the key isn't a standard key, or we need to send the down event. Continue standard
131 // processing
132 return true;
133 } else {
134 // Stop processing if it's a standard key and we're masking up.
135 return !(IS_STANDARD_KEYCODE(translated_keycode) && KEY_STATE(translated_keycode));
136 }
137}
138
diff --git a/quantum/process_keycode/process_key_lock.h b/quantum/process_keycode/process_key_lock.h
new file mode 100644
index 000000000..876db4a32
--- /dev/null
+++ b/quantum/process_keycode/process_key_lock.h
@@ -0,0 +1,24 @@
1/* Copyright 2017 Fredric Silberberg
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 PROCESS_KEY_LOCK_H
18#define PROCESS_KEY_LOCK_H
19
20#include "quantum.h"
21
22bool process_key_lock(uint16_t *keycode, keyrecord_t *record);
23
24#endif // PROCESS_KEY_LOCK_H
diff --git a/quantum/process_keycode/process_leader.c b/quantum/process_keycode/process_leader.c
index 473906d65..e0fe47654 100644
--- a/quantum/process_keycode/process_leader.c
+++ b/quantum/process_keycode/process_leader.c
@@ -14,6 +14,8 @@
14 * along with this program. If not, see <http://www.gnu.org/licenses/>. 14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */ 15 */
16 16
17#ifndef DISABLE_LEADER
18
17#include "process_leader.h" 19#include "process_leader.h"
18 20
19__attribute__ ((weak)) 21__attribute__ ((weak))
@@ -52,3 +54,5 @@ bool process_leader(uint16_t keycode, keyrecord_t *record) {
52 } 54 }
53 return true; 55 return true;
54} 56}
57
58#endif
diff --git a/quantum/process_keycode/process_music.c b/quantum/process_keycode/process_music.c
index 217dca280..63841d1e8 100644
--- a/quantum/process_keycode/process_music.c
+++ b/quantum/process_keycode/process_music.c
@@ -27,6 +27,7 @@
27bool music_activated = false; 27bool music_activated = false;
28uint8_t music_starting_note = 0x0C; 28uint8_t music_starting_note = 0x0C;
29int music_offset = 7; 29int music_offset = 7;
30uint8_t music_mode = MUSIC_MODE_CHROMATIC;
30 31
31// music sequencer 32// music sequencer
32static bool music_sequence_recording = false; 33static bool music_sequence_recording = false;
@@ -39,6 +40,39 @@ static uint8_t music_sequence_position = 0;
39static uint16_t music_sequence_timer = 0; 40static uint16_t music_sequence_timer = 0;
40static uint16_t music_sequence_interval = 100; 41static uint16_t music_sequence_interval = 100;
41 42
43#ifdef AUDIO_ENABLE
44 #ifndef MUSIC_ON_SONG
45 #define MUSIC_ON_SONG SONG(MUSIC_ON_SOUND)
46 #endif
47 #ifndef MUSIC_OFF_SONG
48 #define MUSIC_OFF_SONG SONG(MUSIC_OFF_SOUND)
49 #endif
50 #ifndef CHROMATIC_SONG
51 #define CHROMATIC_SONG SONG(CHROMATIC_SOUND)
52 #endif
53 #ifndef GUITAR_SONG
54 #define GUITAR_SONG SONG(GUITAR_SOUND)
55 #endif
56 #ifndef VIOLIN_SONG
57 #define VIOLIN_SONG SONG(VIOLIN_SOUND)
58 #endif
59 #ifndef MAJOR_SONG
60 #define MAJOR_SONG SONG(MAJOR_SOUND)
61 #endif
62 float music_mode_songs[NUMBER_OF_MODES][5][2] = {
63 CHROMATIC_SONG,
64 GUITAR_SONG,
65 VIOLIN_SONG,
66 MAJOR_SONG
67 };
68 float music_on_song[][2] = MUSIC_ON_SONG;
69 float music_off_song[][2] = MUSIC_OFF_SONG;
70#endif
71
72#ifndef MUSIC_MASK
73 #define MUSIC_MASK keycode < 0xFF
74#endif
75
42static void music_noteon(uint8_t note) { 76static void music_noteon(uint8_t note) {
43 #ifdef AUDIO_ENABLE 77 #ifdef AUDIO_ENABLE
44 process_audio_noteon(note); 78 process_audio_noteon(note);
@@ -79,70 +113,71 @@ bool process_music(uint16_t keycode, keyrecord_t *record) {
79 } 113 }
80 114
81 if (keycode == MU_TOG && record->event.pressed) { 115 if (keycode == MU_TOG && record->event.pressed) {
82 if (music_activated) 116 if (music_activated) {
83 {
84 music_off(); 117 music_off();
85 } 118 } else {
86 else
87 {
88 music_on(); 119 music_on();
89 } 120 }
90 return false; 121 return false;
91 } 122 }
92 123
93 if (music_activated) { 124 if (keycode == MU_MOD && record->event.pressed) {
125 music_mode_cycle();
126 return false;
127 }
94 128
95 if (keycode == KC_LCTL && record->event.pressed) { // Start recording 129 if (music_activated) {
96 music_all_notes_off(); 130 if (record->event.pressed) {
97 music_sequence_recording = true; 131 if (keycode == KC_LCTL) { // Start recording
98 music_sequence_recorded = false; 132 music_all_notes_off();
99 music_sequence_playing = false; 133 music_sequence_recording = true;
100 music_sequence_count = 0; 134 music_sequence_recorded = false;
101 return false; 135 music_sequence_playing = false;
102 } 136 music_sequence_count = 0;
137 return false;
138 }
103 139
104 if (keycode == KC_LALT && record->event.pressed) { // Stop recording/playing 140 if (keycode == KC_LALT) { // Stop recording/playing
105 music_all_notes_off(); 141 music_all_notes_off();
106 if (music_sequence_recording) { // was recording 142 if (music_sequence_recording) { // was recording
107 music_sequence_recorded = true; 143 music_sequence_recorded = true;
144 }
145 music_sequence_recording = false;
146 music_sequence_playing = false;
147 return false;
108 } 148 }
109 music_sequence_recording = false;
110 music_sequence_playing = false;
111 return false;
112 }
113 149
114 if (keycode == KC_LGUI && record->event.pressed && music_sequence_recorded) { // Start playing 150 if (keycode == KC_LGUI && music_sequence_recorded) { // Start playing
115 music_all_notes_off(); 151 music_all_notes_off();
116 music_sequence_recording = false; 152 music_sequence_recording = false;
117 music_sequence_playing = true; 153 music_sequence_playing = true;
118 music_sequence_position = 0; 154 music_sequence_position = 0;
119 music_sequence_timer = 0; 155 music_sequence_timer = 0;
120 return false; 156 return false;
121 } 157 }
122 158
123 if (keycode == KC_UP) { 159 if (keycode == KC_UP) {
124 if (record->event.pressed) 160 music_sequence_interval-=10;
125 music_sequence_interval-=10; 161 return false;
126 return false; 162 }
127 }
128 163
129 if (keycode == KC_DOWN) { 164 if (keycode == KC_DOWN) {
130 if (record->event.pressed) 165 music_sequence_interval+=10;
131 music_sequence_interval+=10; 166 return false;
132 return false; 167 }
133 } 168 }
134 169
135 #define MUSIC_MODE_GUITAR 170 uint8_t note;
136 171 if (music_mode == MUSIC_MODE_CHROMATIC)
137 #ifdef MUSIC_MODE_CHROMATIC 172 note = (music_starting_note + record->event.key.col + music_offset - 3)+12*(MATRIX_ROWS - record->event.key.row);
138 uint8_t note = (music_starting_note + record->event.key.col + music_offset - 3)+12*(MATRIX_ROWS - record->event.key.row); 173 else if (music_mode == MUSIC_MODE_GUITAR)
139 #elif defined(MUSIC_MODE_GUITAR) 174 note = (music_starting_note + record->event.key.col + music_offset + 32)+5*(MATRIX_ROWS - record->event.key.row);
140 uint8_t note = (music_starting_note + record->event.key.col + music_offset + 32)+5*(MATRIX_ROWS - record->event.key.row); 175 else if (music_mode == MUSIC_MODE_VIOLIN)
141 #elif defined(MUSIC_MODE_VIOLIN) 176 note = (music_starting_note + record->event.key.col + music_offset + 32)+7*(MATRIX_ROWS - record->event.key.row);
142 uint8_t note = (music_starting_note + record->event.key.col + music_offset + 32)+7*(MATRIX_ROWS - record->event.key.row); 177 else if (music_mode == MUSIC_MODE_MAJOR)
143 #else 178 note = (music_starting_note + SCALE[record->event.key.col + music_offset] - 3)+12*(MATRIX_ROWS - record->event.key.row);
144 uint8_t note = (music_starting_note + SCALE[record->event.key.col + music_offset] - 3)+12*(MATRIX_ROWS - record->event.key.row); 179 else
145 #endif 180 note = music_starting_note;
146 181
147 if (record->event.pressed) { 182 if (record->event.pressed) {
148 music_noteon(note); 183 music_noteon(note);
@@ -154,7 +189,7 @@ bool process_music(uint16_t keycode, keyrecord_t *record) {
154 music_noteoff(note); 189 music_noteoff(note);
155 } 190 }
156 191
157 if (keycode < 0xFF) // ignores all normal keycodes, but lets RAISE, LOWER, etc through 192 if (MUSIC_MASK)
158 return false; 193 return false;
159 } 194 }
160 195
@@ -175,12 +210,26 @@ void music_toggle(void) {
175 210
176void music_on(void) { 211void music_on(void) {
177 music_activated = 1; 212 music_activated = 1;
213 #ifdef AUDIO_ENABLE
214 PLAY_SONG(music_on_song);
215 #endif
178 music_on_user(); 216 music_on_user();
179} 217}
180 218
181void music_off(void) { 219void music_off(void) {
182 music_activated = 0;
183 music_all_notes_off(); 220 music_all_notes_off();
221 music_activated = 0;
222 #ifdef AUDIO_ENABLE
223 PLAY_SONG(music_off_song);
224 #endif
225}
226
227void music_mode_cycle(void) {
228 music_all_notes_off();
229 music_mode = (music_mode + 1) % NUMBER_OF_MODES;
230 #ifdef AUDIO_ENABLE
231 PLAY_SONG(music_mode_songs[music_mode]);
232 #endif
184} 233}
185 234
186void matrix_scan_music(void) { 235void matrix_scan_music(void) {
diff --git a/quantum/process_keycode/process_music.h b/quantum/process_keycode/process_music.h
index 8dfbf041f..ee027197c 100644
--- a/quantum/process_keycode/process_music.h
+++ b/quantum/process_keycode/process_music.h
@@ -21,6 +21,14 @@
21 21
22#if defined(AUDIO_ENABLE) || (defined(MIDI_ENABLE) && defined(MIDI_BASIC)) 22#if defined(AUDIO_ENABLE) || (defined(MIDI_ENABLE) && defined(MIDI_BASIC))
23 23
24enum music_modes {
25 MUSIC_MODE_CHROMATIC,
26 MUSIC_MODE_GUITAR,
27 MUSIC_MODE_VIOLIN,
28 MUSIC_MODE_MAJOR,
29 NUMBER_OF_MODES
30};
31
24bool process_music(uint16_t keycode, keyrecord_t *record); 32bool process_music(uint16_t keycode, keyrecord_t *record);
25 33
26bool is_music_on(void); 34bool is_music_on(void);
@@ -31,6 +39,7 @@ void music_off(void);
31void music_on_user(void); 39void music_on_user(void);
32void music_scale_user(void); 40void music_scale_user(void);
33void music_all_notes_off(void); 41void music_all_notes_off(void);
42void music_mode_cycle(void);
34 43
35void matrix_scan_music(void); 44void matrix_scan_music(void);
36 45
diff --git a/quantum/process_keycode/process_steno.c b/quantum/process_keycode/process_steno.c
new file mode 100644
index 000000000..16bbf154f
--- /dev/null
+++ b/quantum/process_keycode/process_steno.c
@@ -0,0 +1,165 @@
1/* Copyright 2017 Joseph Wasson
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#include "process_steno.h"
17#include "quantum_keycodes.h"
18#include "eeprom.h"
19#include "keymap_steno.h"
20#include "virtser.h"
21
22// TxBolt Codes
23#define TXB_NUL 0
24#define TXB_S_L 0b00000001
25#define TXB_T_L 0b00000010
26#define TXB_K_L 0b00000100
27#define TXB_P_L 0b00001000
28#define TXB_W_L 0b00010000
29#define TXB_H_L 0b00100000
30#define TXB_R_L 0b01000001
31#define TXB_A_L 0b01000010
32#define TXB_O_L 0b01000100
33#define TXB_STR 0b01001000
34#define TXB_E_R 0b01010000
35#define TXB_U_R 0b01100000
36#define TXB_F_R 0b10000001
37#define TXB_R_R 0b10000010
38#define TXB_P_R 0b10000100
39#define TXB_B_R 0b10001000
40#define TXB_L_R 0b10010000
41#define TXB_G_R 0b10100000
42#define TXB_T_R 0b11000001
43#define TXB_S_R 0b11000010
44#define TXB_D_R 0b11000100
45#define TXB_Z_R 0b11001000
46#define TXB_NUM 0b11010000
47
48#define TXB_GRP0 0b00000000
49#define TXB_GRP1 0b01000000
50#define TXB_GRP2 0b10000000
51#define TXB_GRP3 0b11000000
52#define TXB_GRPMASK 0b11000000
53
54#define TXB_GET_GROUP(code) ((code & TXB_GRPMASK) >> 6)
55
56#define BOLT_STATE_SIZE 4
57#define GEMINI_STATE_SIZE 6
58#define MAX_STATE_SIZE GEMINI_STATE_SIZE
59
60uint8_t state[MAX_STATE_SIZE] = {0};
61uint8_t pressed = 0;
62steno_mode_t mode;
63
64uint8_t boltmap[64] = {
65 TXB_NUL, TXB_NUM, TXB_NUM, TXB_NUM, TXB_NUM, TXB_NUM, TXB_NUM,
66 TXB_S_L, TXB_S_L, TXB_T_L, TXB_K_L, TXB_P_L, TXB_W_L, TXB_H_L,
67 TXB_R_L, TXB_A_L, TXB_O_L, TXB_STR, TXB_STR, TXB_NUL, TXB_NUL,
68 TXB_NUL, TXB_STR, TXB_STR, TXB_E_R, TXB_U_R, TXB_F_R, TXB_R_R,
69 TXB_P_R, TXB_B_R, TXB_L_R, TXB_G_R, TXB_T_R, TXB_S_R, TXB_D_R,
70 TXB_NUM, TXB_NUM, TXB_NUM, TXB_NUM, TXB_NUM, TXB_NUM, TXB_Z_R
71};
72
73void steno_clear_state(void) {
74 __builtin_memset(state, 0, sizeof(state));
75}
76
77void steno_init() {
78 if (!eeconfig_is_enabled()) {
79 eeconfig_init();
80 }
81 mode = eeprom_read_byte(EECONFIG_STENOMODE);
82}
83
84void steno_set_mode(steno_mode_t new_mode) {
85 steno_clear_state();
86 mode = new_mode;
87 eeprom_update_byte(EECONFIG_STENOMODE, mode);
88}
89
90void send_steno_state(uint8_t size, bool send_empty) {
91 for (uint8_t i = 0; i < size; ++i) {
92 if (state[i] || send_empty) {
93 virtser_send(state[i]);
94 }
95 }
96 steno_clear_state();
97}
98
99bool update_state_bolt(uint8_t key) {
100 uint8_t boltcode = boltmap[key];
101 state[TXB_GET_GROUP(boltcode)] |= boltcode;
102 return false;
103}
104
105bool send_state_bolt(void) {
106 send_steno_state(BOLT_STATE_SIZE, false);
107 virtser_send(0); // terminating byte
108 return false;
109}
110
111bool update_state_gemini(uint8_t key) {
112 state[key / 7] |= 1 << (6 - (key % 7));
113 return false;
114}
115
116bool send_state_gemini(void) {
117 state[0] |= 0x80; // Indicate start of packet
118 send_steno_state(GEMINI_STATE_SIZE, true);
119 return false;
120}
121
122bool process_steno(uint16_t keycode, keyrecord_t *record) {
123 switch (keycode) {
124 case QK_STENO_BOLT:
125 if (IS_PRESSED(record->event)) {
126 steno_set_mode(STENO_MODE_BOLT);
127 }
128 return false;
129
130 case QK_STENO_GEMINI:
131 if (IS_PRESSED(record->event)) {
132 steno_set_mode(STENO_MODE_GEMINI);
133 }
134 return false;
135
136 case STN__MIN...STN__MAX:
137 if (IS_PRESSED(record->event)) {
138 uint8_t key = keycode - QK_STENO;
139 ++pressed;
140 switch(mode) {
141 case STENO_MODE_BOLT:
142 return update_state_bolt(key);
143 case STENO_MODE_GEMINI:
144 return update_state_gemini(key);
145 default:
146 return false;
147 }
148 } else {
149 --pressed;
150 if (pressed <= 0) {
151 pressed = 0;
152 switch(mode) {
153 case STENO_MODE_BOLT:
154 return send_state_bolt();
155 case STENO_MODE_GEMINI:
156 return send_state_gemini();
157 default:
158 return false;
159 }
160 }
161 }
162
163 }
164 return true;
165}
diff --git a/quantum/process_keycode/process_steno.h b/quantum/process_keycode/process_steno.h
new file mode 100644
index 000000000..3bbcbeaaf
--- /dev/null
+++ b/quantum/process_keycode/process_steno.h
@@ -0,0 +1,31 @@
1/* Copyright 2017 Joseph Wasson
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#ifndef PROCESS_STENO_H
17#define PROCESS_STENO_H
18
19#include "quantum.h"
20
21#if defined(STENO_ENABLE) && !defined(VIRTSER_ENABLE)
22 #error "must have virtser enabled to use steno"
23#endif
24
25typedef enum { STENO_MODE_BOLT, STENO_MODE_GEMINI } steno_mode_t;
26
27bool process_steno(uint16_t keycode, keyrecord_t *record);
28void steno_init(void);
29void steno_set_mode(steno_mode_t mode);
30
31#endif \ No newline at end of file
diff --git a/quantum/process_keycode/process_tap_dance.c b/quantum/process_keycode/process_tap_dance.c
index 4fd45810b..f1f28e016 100644
--- a/quantum/process_keycode/process_tap_dance.c
+++ b/quantum/process_keycode/process_tap_dance.c
@@ -41,6 +41,24 @@ void qk_tap_dance_pair_reset (qk_tap_dance_state_t *state, void *user_data) {
41 } 41 }
42} 42}
43 43
44void qk_tap_dance_dual_role_finished (qk_tap_dance_state_t *state, void *user_data) {
45 qk_tap_dance_dual_role_t *pair = (qk_tap_dance_dual_role_t *)user_data;
46
47 if (state->count == 1) {
48 register_code16 (pair->kc);
49 } else if (state->count == 2) {
50 layer_move (pair->layer);
51 }
52}
53
54void qk_tap_dance_dual_role_reset (qk_tap_dance_state_t *state, void *user_data) {
55 qk_tap_dance_dual_role_t *pair = (qk_tap_dance_dual_role_t *)user_data;
56
57 if (state->count == 1) {
58 unregister_code16 (pair->kc);
59 }
60}
61
44static inline void _process_tap_dance_action_fn (qk_tap_dance_state_t *state, 62static inline void _process_tap_dance_action_fn (qk_tap_dance_state_t *state,
45 void *user_data, 63 void *user_data,
46 qk_tap_dance_user_fn_t fn) 64 qk_tap_dance_user_fn_t fn)
diff --git a/quantum/process_keycode/process_tap_dance.h b/quantum/process_keycode/process_tap_dance.h
index f42c154a0..37a27c536 100644
--- a/quantum/process_keycode/process_tap_dance.h
+++ b/quantum/process_keycode/process_tap_dance.h
@@ -54,11 +54,22 @@ typedef struct
54 uint16_t kc2; 54 uint16_t kc2;
55} qk_tap_dance_pair_t; 55} qk_tap_dance_pair_t;
56 56
57typedef struct
58{
59 uint16_t kc;
60 uint8_t layer;
61} qk_tap_dance_dual_role_t;
62
57#define ACTION_TAP_DANCE_DOUBLE(kc1, kc2) { \ 63#define ACTION_TAP_DANCE_DOUBLE(kc1, kc2) { \
58 .fn = { NULL, qk_tap_dance_pair_finished, qk_tap_dance_pair_reset }, \ 64 .fn = { NULL, qk_tap_dance_pair_finished, qk_tap_dance_pair_reset }, \
59 .user_data = (void *)&((qk_tap_dance_pair_t) { kc1, kc2 }), \ 65 .user_data = (void *)&((qk_tap_dance_pair_t) { kc1, kc2 }), \
60 } 66 }
61 67
68#define ACTION_TAP_DANCE_DUAL_ROLE(kc, layer) { \
69 .fn = { NULL, qk_tap_dance_dual_role_finished, qk_tap_dance_dual_role_reset }, \
70 .user_data = (void *)&((qk_tap_dance_dual_role_t) { kc, layer }), \
71 }
72
62#define ACTION_TAP_DANCE_FN(user_fn) { \ 73#define ACTION_TAP_DANCE_FN(user_fn) { \
63 .fn = { NULL, user_fn, NULL }, \ 74 .fn = { NULL, user_fn, NULL }, \
64 .user_data = NULL, \ 75 .user_data = NULL, \
@@ -86,6 +97,9 @@ void reset_tap_dance (qk_tap_dance_state_t *state);
86void qk_tap_dance_pair_finished (qk_tap_dance_state_t *state, void *user_data); 97void qk_tap_dance_pair_finished (qk_tap_dance_state_t *state, void *user_data);
87void qk_tap_dance_pair_reset (qk_tap_dance_state_t *state, void *user_data); 98void qk_tap_dance_pair_reset (qk_tap_dance_state_t *state, void *user_data);
88 99
100void qk_tap_dance_dual_role_finished (qk_tap_dance_state_t *state, void *user_data);
101void qk_tap_dance_dual_role_reset (qk_tap_dance_state_t *state, void *user_data);
102
89#else 103#else
90 104
91#define TD(n) KC_NO 105#define TD(n) KC_NO
diff --git a/quantum/process_keycode/process_terminal.c b/quantum/process_keycode/process_terminal.c
new file mode 100644
index 000000000..deb1543e3
--- /dev/null
+++ b/quantum/process_keycode/process_terminal.c
@@ -0,0 +1,252 @@
1/* Copyright 2017 Jack Humbert
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#include "process_terminal.h"
18#include <string.h>
19#include "version.h"
20#include <stdio.h>
21#include <math.h>
22
23bool terminal_enabled = false;
24char buffer[80] = "";
25char newline[2] = "\n";
26char arguments[6][20];
27
28__attribute__ ((weak))
29const char terminal_prompt[8] = "> ";
30
31#ifdef AUDIO_ENABLE
32 #ifndef TERMINAL_SONG
33 #define TERMINAL_SONG SONG(TERMINAL_SOUND)
34 #endif
35 float terminal_song[][2] = TERMINAL_SONG;
36 #define TERMINAL_BELL() PLAY_SONG(terminal_song)
37#else
38 #define TERMINAL_BELL()
39#endif
40
41__attribute__ ((weak))
42const char keycode_to_ascii_lut[58] = {
43 0, 0, 0, 0,
44 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
45 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
46 '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', 0, 0, 0, '\t',
47 ' ', '-', '=', '[', ']', '\\', 0, ';', '\'', '`', ',', '.', '/'
48};
49
50__attribute__ ((weak))
51const char shifted_keycode_to_ascii_lut[58] = {
52 0, 0, 0, 0,
53 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
54 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
55 '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', 0, 0, 0, '\t',
56 ' ', '_', '+', '{', '}', '|', 0, ':', '\'', '~', '<', '>', '?'
57};
58
59struct stringcase {
60 char* string;
61 void (*func)(void);
62} typedef stringcase;
63
64void enable_terminal(void) {
65 terminal_enabled = true;
66 strcpy(buffer, "");
67 for (int i = 0; i < 6; i++)
68 strcpy(arguments[i], "");
69 // select all text to start over
70 // SEND_STRING(SS_LCTRL("a"));
71 send_string(terminal_prompt);
72}
73
74void disable_terminal(void) {
75 terminal_enabled = false;
76}
77
78void terminal_about(void) {
79 SEND_STRING("QMK Firmware\n");
80 SEND_STRING(" v");
81 SEND_STRING(QMK_VERSION);
82 SEND_STRING("\n"SS_TAP(X_HOME)" Built: ");
83 SEND_STRING(QMK_BUILDDATE);
84 send_string(newline);
85 #ifdef TERMINAL_HELP
86 if (strlen(arguments[1]) != 0) {
87 SEND_STRING("You entered: ");
88 send_string(arguments[1]);
89 send_string(newline);
90 }
91 #endif
92}
93
94void terminal_help(void);
95
96extern const uint16_t keymaps[][MATRIX_ROWS][MATRIX_COLS];
97
98void terminal_keycode(void) {
99 if (strlen(arguments[1]) != 0 && strlen(arguments[2]) != 0 && strlen(arguments[3]) != 0) {
100 char keycode_dec[5];
101 char keycode_hex[5];
102 uint16_t layer = strtol(arguments[1], (char **)NULL, 10);
103 uint16_t row = strtol(arguments[2], (char **)NULL, 10);
104 uint16_t col = strtol(arguments[3], (char **)NULL, 10);
105 uint16_t keycode = pgm_read_word(&keymaps[layer][row][col]);
106 itoa(keycode, keycode_dec, 10);
107 itoa(keycode, keycode_hex, 16);
108 SEND_STRING("0x");
109 send_string(keycode_hex);
110 SEND_STRING(" (");
111 send_string(keycode_dec);
112 SEND_STRING(")\n");
113 } else {
114 #ifdef TERMINAL_HELP
115 SEND_STRING("usage: keycode <layer> <row> <col>\n");
116 #endif
117 }
118}
119
120void terminal_keymap(void) {
121 if (strlen(arguments[1]) != 0) {
122 uint16_t layer = strtol(arguments[1], (char **)NULL, 10);
123 for (int r = 0; r < MATRIX_ROWS; r++) {
124 for (int c = 0; c < MATRIX_COLS; c++) {
125 uint16_t keycode = pgm_read_word(&keymaps[layer][r][c]);
126 char keycode_s[8];
127 sprintf(keycode_s, "0x%04x, ", keycode);
128 send_string(keycode_s);
129 }
130 send_string(newline);
131 }
132 } else {
133 #ifdef TERMINAL_HELP
134 SEND_STRING("usage: keymap <layer>\n");
135 #endif
136 }
137}
138
139stringcase terminal_cases[] = {
140 { "about", terminal_about },
141 { "help", terminal_help },
142 { "keycode", terminal_keycode },
143 { "keymap", terminal_keymap },
144 { "exit", disable_terminal }
145};
146
147void terminal_help(void) {
148 SEND_STRING("commands available:\n ");
149 for( stringcase* case_p = terminal_cases; case_p != terminal_cases + sizeof( terminal_cases ) / sizeof( terminal_cases[0] ); case_p++ ) {
150 send_string(case_p->string);
151 SEND_STRING(" ");
152 }
153 send_string(newline);
154}
155
156void command_not_found(void) {
157 SEND_STRING("command \"");
158 send_string(buffer);
159 SEND_STRING("\" not found\n");
160}
161
162void process_terminal_command(void) {
163 // we capture return bc of the order of events, so we need to manually send a newline
164 send_string(newline);
165
166 char * pch;
167 uint8_t i = 0;
168 pch = strtok(buffer, " ");
169 while (pch != NULL) {
170 strcpy(arguments[i], pch);
171 pch = strtok(NULL, " ");
172 i++;
173 }
174
175 bool command_found = false;
176 for( stringcase* case_p = terminal_cases; case_p != terminal_cases + sizeof( terminal_cases ) / sizeof( terminal_cases[0] ); case_p++ ) {
177 if( 0 == strcmp( case_p->string, buffer ) ) {
178 command_found = true;
179 (*case_p->func)();
180 break;
181 }
182 }
183
184 if (!command_found)
185 command_not_found();
186
187 if (terminal_enabled) {
188 strcpy(buffer, "");
189 for (int i = 0; i < 6; i++)
190 strcpy(arguments[i], "");
191 SEND_STRING(SS_TAP(X_HOME));
192 send_string(terminal_prompt);
193 }
194}
195
196bool process_terminal(uint16_t keycode, keyrecord_t *record) {
197
198 if (keycode == TERM_ON && record->event.pressed) {
199 enable_terminal();
200 return false;
201 }
202
203 if (terminal_enabled && record->event.pressed) {
204 if (keycode == TERM_OFF && record->event.pressed) {
205 disable_terminal();
206 return false;
207 }
208 if (keycode < 256) {
209 uint8_t str_len;
210 char char_to_add;
211 switch (keycode) {
212 case KC_ENTER:
213 process_terminal_command();
214 return false; break;
215 case KC_ESC:
216 SEND_STRING("\n");
217 enable_terminal();
218 return false; break;
219 case KC_BSPC:
220 str_len = strlen(buffer);
221 if (str_len > 0) {
222 buffer[str_len-1] = 0;
223 return true;
224 } else {
225 TERMINAL_BELL();
226 return false;
227 } break;
228 case KC_LEFT:
229 case KC_RIGHT:
230 case KC_UP:
231 case KC_DOWN:
232 return false; break;
233 default:
234 if (keycode <= 58) {
235 char_to_add = 0;
236 if (get_mods() & (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT))) {
237 char_to_add = shifted_keycode_to_ascii_lut[keycode];
238 } else if (get_mods() == 0) {
239 char_to_add = keycode_to_ascii_lut[keycode];
240 }
241 if (char_to_add != 0) {
242 strncat(buffer, &char_to_add, 1);
243 }
244 } break;
245 }
246
247
248
249 }
250 }
251 return true;
252} \ No newline at end of file
diff --git a/quantum/process_keycode/process_terminal.h b/quantum/process_keycode/process_terminal.h
new file mode 100644
index 000000000..d945949a4
--- /dev/null
+++ b/quantum/process_keycode/process_terminal.h
@@ -0,0 +1,27 @@
1/* Copyright 2017 Jack Humbert
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 PROCESS_TERMINAL_H
18#define PROCESS_TERMINAL_H
19
20#include "quantum.h"
21
22extern const char keycode_to_ascii_lut[58];
23extern const char shifted_keycode_to_ascii_lut[58];
24extern const char terminal_prompt[8];
25bool process_terminal(uint16_t keycode, keyrecord_t *record);
26
27#endif \ No newline at end of file
diff --git a/quantum/process_keycode/process_terminal_nop.h b/quantum/process_keycode/process_terminal_nop.h
new file mode 100644
index 000000000..56895b33c
--- /dev/null
+++ b/quantum/process_keycode/process_terminal_nop.h
@@ -0,0 +1,25 @@
1/* Copyright 2017 Jack Humbert
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 PROCESS_TERMINAL_H
18#define PROCESS_TERMINAL_H
19
20#include "quantum.h"
21
22#define TERM_ON KC_NO
23#define TERM_OFF KC_NO
24
25#endif \ No newline at end of file
diff --git a/quantum/process_keycode/process_unicode_common.c b/quantum/process_keycode/process_unicode_common.c
index 84b5d673d..7f34ad57c 100644
--- a/quantum/process_keycode/process_unicode_common.c
+++ b/quantum/process_keycode/process_unicode_common.c
@@ -49,6 +49,9 @@ void unicode_input_start (void) {
49 case UC_OSX: 49 case UC_OSX:
50 register_code(KC_LALT); 50 register_code(KC_LALT);
51 break; 51 break;
52 case UC_OSX_RALT:
53 register_code(KC_RALT);
54 break;
52 case UC_LNX: 55 case UC_LNX:
53 register_code(KC_LCTL); 56 register_code(KC_LCTL);
54 register_code(KC_LSFT); 57 register_code(KC_LSFT);
@@ -78,6 +81,9 @@ void unicode_input_finish (void) {
78 case UC_WIN: 81 case UC_WIN:
79 unregister_code(KC_LALT); 82 unregister_code(KC_LALT);
80 break; 83 break;
84 case UC_OSX_RALT:
85 unregister_code(KC_RALT);
86 break;
81 case UC_LNX: 87 case UC_LNX:
82 register_code(KC_SPC); 88 register_code(KC_SPC);
83 unregister_code(KC_SPC); 89 unregister_code(KC_SPC);
diff --git a/quantum/process_keycode/process_unicode_common.h b/quantum/process_keycode/process_unicode_common.h
index f5be1da5c..4d2b04fb3 100644
--- a/quantum/process_keycode/process_unicode_common.h
+++ b/quantum/process_keycode/process_unicode_common.h
@@ -37,6 +37,7 @@ void register_hex(uint16_t hex);
37#define UC_WIN 2 // Windows 'HexNumpad' 37#define UC_WIN 2 // Windows 'HexNumpad'
38#define UC_BSD 3 // BSD (not implemented) 38#define UC_BSD 3 // BSD (not implemented)
39#define UC_WINC 4 // WinCompose https://github.com/samhocevar/wincompose 39#define UC_WINC 4 // WinCompose https://github.com/samhocevar/wincompose
40#define UC_OSX_RALT 5 // Mac OS X using Right Alt key for Unicode Compose
40 41
41#define UC_BSPC UC(0x0008) 42#define UC_BSPC UC(0x0008)
42 43
diff --git a/quantum/process_keycode/process_unicodemap.c b/quantum/process_keycode/process_unicodemap.c
index 75f35112b..47c27b911 100644
--- a/quantum/process_keycode/process_unicodemap.c
+++ b/quantum/process_keycode/process_unicodemap.c
@@ -50,7 +50,7 @@ bool process_unicode_map(uint16_t keycode, keyrecord_t *record) {
50 const uint32_t* map = unicode_map; 50 const uint32_t* map = unicode_map;
51 uint16_t index = keycode - QK_UNICODE_MAP; 51 uint16_t index = keycode - QK_UNICODE_MAP;
52 uint32_t code = pgm_read_dword(&map[index]); 52 uint32_t code = pgm_read_dword(&map[index]);
53 if (code > 0xFFFF && code <= 0x10ffff && input_mode == UC_OSX) { 53 if (code > 0xFFFF && code <= 0x10ffff && (input_mode == UC_OSX || input_mode == UC_OSX_RALT)) {
54 // Convert to UTF-16 surrogate pair 54 // Convert to UTF-16 surrogate pair
55 code -= 0x10000; 55 code -= 0x10000;
56 uint32_t lo = code & 0x3ff; 56 uint32_t lo = code & 0x3ff;
@@ -59,7 +59,7 @@ bool process_unicode_map(uint16_t keycode, keyrecord_t *record) {
59 register_hex32(hi + 0xd800); 59 register_hex32(hi + 0xd800);
60 register_hex32(lo + 0xdc00); 60 register_hex32(lo + 0xdc00);
61 unicode_input_finish(); 61 unicode_input_finish();
62 } else if ((code > 0x10ffff && input_mode == UC_OSX) || (code > 0xFFFFF && input_mode == UC_LNX)) { 62 } else if ((code > 0x10ffff && (input_mode == UC_OSX || input_mode == UC_OSX_RALT)) || (code > 0xFFFFF && input_mode == UC_LNX)) {
63 // when character is out of range supported by the OS 63 // when character is out of range supported by the OS
64 unicode_map_input_error(); 64 unicode_map_input_error();
65 } else { 65 } else {
diff --git a/quantum/quantum.c b/quantum/quantum.c
index 5bb7b04d5..1fccaa7d5 100644
--- a/quantum/quantum.c
+++ b/quantum/quantum.c
@@ -30,6 +30,24 @@ extern backlight_config_t backlight_config;
30#include "fauxclicky.h" 30#include "fauxclicky.h"
31#endif 31#endif
32 32
33#ifdef AUDIO_ENABLE
34 #ifndef GOODBYE_SONG
35 #define GOODBYE_SONG SONG(GOODBYE_SOUND)
36 #endif
37 #ifndef AG_NORM_SONG
38 #define AG_NORM_SONG SONG(AG_NORM_SOUND)
39 #endif
40 #ifndef AG_SWAP_SONG
41 #define AG_SWAP_SONG SONG(AG_SWAP_SOUND)
42 #endif
43 float goodbye_song[][2] = GOODBYE_SONG;
44 float ag_norm_song[][2] = AG_NORM_SONG;
45 float ag_swap_song[][2] = AG_SWAP_SONG;
46 #ifdef DEFAULT_LAYER_SONGS
47 float default_layer_songs[][16][2] = DEFAULT_LAYER_SONGS;
48 #endif
49#endif
50
33static void do_code16 (uint16_t code, void (*f) (uint8_t)) { 51static void do_code16 (uint16_t code, void (*f) (uint8_t)) {
34 switch (code) { 52 switch (code) {
35 case QK_MODS ... QK_MODS_MAX: 53 case QK_MODS ... QK_MODS_MAX:
@@ -116,9 +134,15 @@ void reset_keyboard(void) {
116 clear_keyboard(); 134 clear_keyboard();
117#if defined(AUDIO_ENABLE) || (defined(MIDI_ENABLE) && defined(MIDI_ENABLE_BASIC)) 135#if defined(AUDIO_ENABLE) || (defined(MIDI_ENABLE) && defined(MIDI_ENABLE_BASIC))
118 music_all_notes_off(); 136 music_all_notes_off();
137 uint16_t timer_start = timer_read();
138 PLAY_SONG(goodbye_song);
119 shutdown_user(); 139 shutdown_user();
120#endif 140 while(timer_elapsed(timer_start) < 250)
141 wait_ms(1);
142 stop_all_notes();
143#else
121 wait_ms(250); 144 wait_ms(250);
145#endif
122#ifdef CATERINA_BOOTLOADER 146#ifdef CATERINA_BOOTLOADER
123 *(uint16_t *)0x0800 = 0x7777; // these two are a-star-specific 147 *(uint16_t *)0x0800 = 0x7777; // these two are a-star-specific
124#endif 148#endif
@@ -137,6 +161,11 @@ void reset_keyboard(void) {
137static bool shift_interrupted[2] = {0, 0}; 161static bool shift_interrupted[2] = {0, 0};
138static uint16_t scs_timer[2] = {0, 0}; 162static uint16_t scs_timer[2] = {0, 0};
139 163
164/* true if the last press of GRAVE_ESC was shifted (i.e. GUI or SHIFT were pressed), false otherwise.
165 * Used to ensure that the correct keycode is released if the key is released.
166 */
167static bool grave_esc_was_shifted = false;
168
140bool process_record_quantum(keyrecord_t *record) { 169bool process_record_quantum(keyrecord_t *record) {
141 170
142 /* This gets the keycode from the key pressed */ 171 /* This gets the keycode from the key pressed */
@@ -168,6 +197,10 @@ bool process_record_quantum(keyrecord_t *record) {
168 // } 197 // }
169 198
170 if (!( 199 if (!(
200 #if defined(KEY_LOCK_ENABLE)
201 // Must run first to be able to mask key_up events.
202 process_key_lock(&keycode, record) &&
203 #endif
171 process_record_kb(keycode, record) && 204 process_record_kb(keycode, record) &&
172 #if defined(MIDI_ENABLE) && defined(MIDI_ADVANCED) 205 #if defined(MIDI_ENABLE) && defined(MIDI_ADVANCED)
173 process_midi(keycode, record) && 206 process_midi(keycode, record) &&
@@ -175,6 +208,9 @@ bool process_record_quantum(keyrecord_t *record) {
175 #ifdef AUDIO_ENABLE 208 #ifdef AUDIO_ENABLE
176 process_audio(keycode, record) && 209 process_audio(keycode, record) &&
177 #endif 210 #endif
211 #ifdef STENO_ENABLE
212 process_steno(keycode, record) &&
213 #endif
178 #if defined(AUDIO_ENABLE) || (defined(MIDI_ENABLE) && defined(MIDI_BASIC)) 214 #if defined(AUDIO_ENABLE) || (defined(MIDI_ENABLE) && defined(MIDI_BASIC))
179 process_music(keycode, record) && 215 process_music(keycode, record) &&
180 #endif 216 #endif
@@ -202,6 +238,9 @@ bool process_record_quantum(keyrecord_t *record) {
202 #ifdef UNICODEMAP_ENABLE 238 #ifdef UNICODEMAP_ENABLE
203 process_unicode_map(keycode, record) && 239 process_unicode_map(keycode, record) &&
204 #endif 240 #endif
241 #ifdef TERMINAL_ENABLE
242 process_terminal(keycode, record) &&
243 #endif
205 true)) { 244 true)) {
206 return false; 245 return false;
207 } 246 }
@@ -213,105 +252,153 @@ bool process_record_quantum(keyrecord_t *record) {
213 if (record->event.pressed) { 252 if (record->event.pressed) {
214 reset_keyboard(); 253 reset_keyboard();
215 } 254 }
216 return false; 255 return false;
217 break;
218 case DEBUG: 256 case DEBUG:
219 if (record->event.pressed) { 257 if (record->event.pressed) {
220 print("\nDEBUG: enabled.\n");
221 debug_enable = true; 258 debug_enable = true;
259 print("DEBUG: enabled.\n");
222 } 260 }
223 return false; 261 return false;
224 break;
225 #ifdef FAUXCLICKY_ENABLE 262 #ifdef FAUXCLICKY_ENABLE
226 case FC_TOG: 263 case FC_TOG:
227 if (record->event.pressed) { 264 if (record->event.pressed) {
228 FAUXCLICKY_TOGGLE; 265 FAUXCLICKY_TOGGLE;
229 } 266 }
230 return false; 267 return false;
231 break;
232 case FC_ON: 268 case FC_ON:
233 if (record->event.pressed) { 269 if (record->event.pressed) {
234 FAUXCLICKY_ON; 270 FAUXCLICKY_ON;
235 } 271 }
236 return false; 272 return false;
237 break;
238 case FC_OFF: 273 case FC_OFF:
239 if (record->event.pressed) { 274 if (record->event.pressed) {
240 FAUXCLICKY_OFF; 275 FAUXCLICKY_OFF;
241 } 276 }
242 return false; 277 return false;
243 break;
244 #endif 278 #endif
245 #ifdef RGBLIGHT_ENABLE 279 #ifdef RGBLIGHT_ENABLE
246 case RGB_TOG: 280 case RGB_TOG:
247 if (record->event.pressed) { 281 if (record->event.pressed) {
248 rgblight_toggle(); 282 rgblight_toggle();
249 } 283 }
250 return false; 284 return false;
251 break; 285 case RGB_MOD:
252 case RGB_MOD: 286 if (record->event.pressed) {
253 if (record->event.pressed) { 287 rgblight_step();
254 rgblight_step(); 288 }
255 } 289 return false;
256 return false; 290 case RGB_HUI:
257 break; 291 if (record->event.pressed) {
258 case RGB_HUI: 292 rgblight_increase_hue();
259 if (record->event.pressed) { 293 }
260 rgblight_increase_hue(); 294 return false;
295 case RGB_HUD:
296 if (record->event.pressed) {
297 rgblight_decrease_hue();
298 }
299 return false;
300 case RGB_SAI:
301 if (record->event.pressed) {
302 rgblight_increase_sat();
303 }
304 return false;
305 case RGB_SAD:
306 if (record->event.pressed) {
307 rgblight_decrease_sat();
308 }
309 return false;
310 case RGB_VAI:
311 if (record->event.pressed) {
312 rgblight_increase_val();
313 }
314 return false;
315 case RGB_VAD:
316 if (record->event.pressed) {
317 rgblight_decrease_val();
318 }
319 return false;
320 case RGB_MODE_PLAIN:
321 if (record->event.pressed) {
322 rgblight_mode(1);
323 }
324 return false;
325 case RGB_MODE_BREATHE:
326 if (record->event.pressed) {
327 if ((2 <= rgblight_get_mode()) && (rgblight_get_mode() < 5)) {
328 rgblight_step();
329 } else {
330 rgblight_mode(2);
261 } 331 }
262 return false; 332 }
263 break; 333 return false;
264 case RGB_HUD: 334 case RGB_MODE_RAINBOW:
265 if (record->event.pressed) { 335 if (record->event.pressed) {
266 rgblight_decrease_hue(); 336 if ((6 <= rgblight_get_mode()) && (rgblight_get_mode() < 8)) {
337 rgblight_step();
338 } else {
339 rgblight_mode(6);
267 } 340 }
268 return false; 341 }
269 break; 342 return false;
270 case RGB_SAI: 343 case RGB_MODE_SWIRL:
271 if (record->event.pressed) { 344 if (record->event.pressed) {
272 rgblight_increase_sat(); 345 if ((9 <= rgblight_get_mode()) && (rgblight_get_mode() < 14)) {
346 rgblight_step();
347 } else {
348 rgblight_mode(9);
273 } 349 }
274 return false; 350 }
275 break; 351 return false;
276 case RGB_SAD: 352 case RGB_MODE_SNAKE:
277 if (record->event.pressed) { 353 if (record->event.pressed) {
278 rgblight_decrease_sat(); 354 if ((15 <= rgblight_get_mode()) && (rgblight_get_mode() < 20)) {
355 rgblight_step();
356 } else {
357 rgblight_mode(15);
279 } 358 }
280 return false; 359 }
281 break; 360 return false;
282 case RGB_VAI: 361 case RGB_MODE_KNIGHT:
283 if (record->event.pressed) { 362 if (record->event.pressed) {
284 rgblight_increase_val(); 363 if ((21 <= rgblight_get_mode()) && (rgblight_get_mode() < 23)) {
364 rgblight_step();
365 } else {
366 rgblight_mode(21);
285 } 367 }
286 return false; 368 }
287 break; 369 return false;
288 case RGB_VAD: 370 case RGB_MODE_XMAS:
289 if (record->event.pressed) { 371 if (record->event.pressed) {
290 rgblight_decrease_val(); 372 rgblight_mode(24);
373 }
374 return false;
375 case RGB_MODE_GRADIENT:
376 if (record->event.pressed) {
377 if ((25 <= rgblight_get_mode()) && (rgblight_get_mode() < 34)) {
378 rgblight_step();
379 } else {
380 rgblight_mode(25);
291 } 381 }
292 return false; 382 }
293 break; 383 return false;
294 #endif 384 #endif
295 #ifdef PROTOCOL_LUFA 385 #ifdef PROTOCOL_LUFA
296 case OUT_AUTO: 386 case OUT_AUTO:
297 if (record->event.pressed) { 387 if (record->event.pressed) {
298 set_output(OUTPUT_AUTO); 388 set_output(OUTPUT_AUTO);
299 } 389 }
300 return false; 390 return false;
301 break;
302 case OUT_USB: 391 case OUT_USB:
303 if (record->event.pressed) { 392 if (record->event.pressed) {
304 set_output(OUTPUT_USB); 393 set_output(OUTPUT_USB);
305 } 394 }
306 return false; 395 return false;
307 break;
308 #ifdef BLUETOOTH_ENABLE 396 #ifdef BLUETOOTH_ENABLE
309 case OUT_BT: 397 case OUT_BT:
310 if (record->event.pressed) { 398 if (record->event.pressed) {
311 set_output(OUTPUT_BLUETOOTH); 399 set_output(OUTPUT_BLUETOOTH);
312 } 400 }
313 return false; 401 return false;
314 break;
315 #endif 402 #endif
316 #endif 403 #endif
317 case MAGIC_SWAP_CONTROL_CAPSLOCK ... MAGIC_TOGGLE_NKRO: 404 case MAGIC_SWAP_CONTROL_CAPSLOCK ... MAGIC_TOGGLE_NKRO:
@@ -351,6 +438,9 @@ bool process_record_quantum(keyrecord_t *record) {
351 case MAGIC_SWAP_ALT_GUI: 438 case MAGIC_SWAP_ALT_GUI:
352 keymap_config.swap_lalt_lgui = true; 439 keymap_config.swap_lalt_lgui = true;
353 keymap_config.swap_ralt_rgui = true; 440 keymap_config.swap_ralt_rgui = true;
441 #ifdef AUDIO_ENABLE
442 PLAY_SONG(ag_swap_song);
443 #endif
354 break; 444 break;
355 case MAGIC_UNSWAP_CONTROL_CAPSLOCK: 445 case MAGIC_UNSWAP_CONTROL_CAPSLOCK:
356 keymap_config.swap_control_capslock = false; 446 keymap_config.swap_control_capslock = false;
@@ -379,6 +469,9 @@ bool process_record_quantum(keyrecord_t *record) {
379 case MAGIC_UNSWAP_ALT_GUI: 469 case MAGIC_UNSWAP_ALT_GUI:
380 keymap_config.swap_lalt_lgui = false; 470 keymap_config.swap_lalt_lgui = false;
381 keymap_config.swap_ralt_rgui = false; 471 keymap_config.swap_ralt_rgui = false;
472 #ifdef AUDIO_ENABLE
473 PLAY_SONG(ag_norm_song);
474 #endif
382 break; 475 break;
383 case MAGIC_TOGGLE_NKRO: 476 case MAGIC_TOGGLE_NKRO:
384 keymap_config.nkro = !keymap_config.nkro; 477 keymap_config.nkro = !keymap_config.nkro;
@@ -412,7 +505,6 @@ bool process_record_quantum(keyrecord_t *record) {
412 unregister_mods(MOD_BIT(KC_LSFT)); 505 unregister_mods(MOD_BIT(KC_LSFT));
413 } 506 }
414 return false; 507 return false;
415 // break;
416 } 508 }
417 509
418 case KC_RSPC: { 510 case KC_RSPC: {
@@ -435,15 +527,27 @@ bool process_record_quantum(keyrecord_t *record) {
435 unregister_mods(MOD_BIT(KC_RSFT)); 527 unregister_mods(MOD_BIT(KC_RSFT));
436 } 528 }
437 return false; 529 return false;
438 // break;
439 } 530 }
440 case GRAVE_ESC: { 531 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) 532 uint8_t shifted = get_mods() & ((MOD_BIT(KC_LSHIFT)|MOD_BIT(KC_RSHIFT)
443 |MOD_BIT(KC_LGUI)|MOD_BIT(KC_RGUI))); 533 |MOD_BIT(KC_LGUI)|MOD_BIT(KC_RGUI)));
444 534
445 method(shifted ? KC_GRAVE : KC_ESCAPE); 535#ifdef GRAVE_ESC_CTRL_OVERRIDE
446 send_keyboard_report(); 536 // if CTRL is pressed, ESC is always read as ESC, even if SHIFT or GUI is pressed.
537 // this is handy for the ctrl+shift+esc shortcut on windows, among other things.
538 if (get_mods() & (MOD_BIT(KC_LCTL) | MOD_BIT(KC_RCTL)))
539 shifted = 0;
540#endif
541
542 if (record->event.pressed) {
543 grave_esc_was_shifted = shifted;
544 add_key(shifted ? KC_GRAVE : KC_ESCAPE);
545 }
546 else {
547 del_key(grave_esc_was_shifted ? KC_GRAVE : KC_ESCAPE);
548 }
549
550 send_keyboard_report();
447 } 551 }
448 default: { 552 default: {
449 shift_interrupted[0] = true; 553 shift_interrupted[0] = true;
@@ -455,103 +559,8 @@ bool process_record_quantum(keyrecord_t *record) {
455 return process_action_kb(record); 559 return process_action_kb(record);
456} 560}
457 561
458#ifdef JIS_KEYCODE 562__attribute__ ((weak))
459static const uint16_t ascii_to_shift_lut[8] PROGMEM = { 563const bool ascii_to_shift_lut[0x80] 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 = {
555 0, 0, 0, 0, 0, 0, 0, 0, 564 0, 0, 0, 0, 0, 0, 0, 0,
556 0, 0, 0, 0, 0, 0, 0, 0, 565 0, 0, 0, 0, 0, 0, 0, 0,
557 0, 0, 0, 0, 0, 0, 0, 0, 566 0, 0, 0, 0, 0, 0, 0, 0,
@@ -570,7 +579,8 @@ static const bool ascii_to_qwerty_shift_lut[0x80] PROGMEM = {
570 0, 0, 0, 1, 1, 1, 1, 0 579 0, 0, 0, 1, 1, 1, 1, 0
571}; 580};
572 581
573static const uint8_t ascii_to_qwerty_keycode_lut[0x80] PROGMEM = { 582__attribute__ ((weak))
583const uint8_t ascii_to_keycode_lut[0x80] PROGMEM = {
574 0, 0, 0, 0, 0, 0, 0, 0, 584 0, 0, 0, 0, 0, 0, 0, 0,
575 KC_BSPC, KC_TAB, KC_ENT, 0, 0, 0, 0, 0, 585 KC_BSPC, KC_TAB, KC_ENT, 0, 0, 0, 0, 0,
576 0, 0, 0, 0, 0, 0, 0, 0, 586 0, 0, 0, 0, 0, 0, 0, 0,
@@ -590,70 +600,86 @@ static const uint8_t ascii_to_qwerty_keycode_lut[0x80] PROGMEM = {
590}; 600};
591 601
592void send_string(const char *str) { 602void send_string(const char *str) {
603 send_string_with_delay(str, 0);
604}
605
606void send_string_P(const char *str) {
607 send_string_with_delay_P(str, 0);
608}
609
610void send_string_with_delay(const char *str, uint8_t interval) {
593 while (1) { 611 while (1) {
594 uint8_t keycode; 612 char ascii_code = *str;
595 uint8_t ascii_code = pgm_read_byte(str);
596 if (!ascii_code) break; 613 if (!ascii_code) break;
597 keycode = pgm_read_byte(&ascii_to_qwerty_keycode_lut[ascii_code]); 614 if (ascii_code == 1) {
598 if (pgm_read_byte(&ascii_to_qwerty_shift_lut[ascii_code])) { 615 // tap
599 register_code(KC_LSFT); 616 uint8_t keycode = *(++str);
600 register_code(keycode); 617 register_code(keycode);
601 unregister_code(keycode); 618 unregister_code(keycode);
602 unregister_code(KC_LSFT); 619 } else if (ascii_code == 2) {
603 } 620 // down
604 else { 621 uint8_t keycode = *(++str);
605 register_code(keycode); 622 register_code(keycode);
606 unregister_code(keycode); 623 } else if (ascii_code == 3) {
624 // up
625 uint8_t keycode = *(++str);
626 unregister_code(keycode);
627 } else {
628 send_char(ascii_code);
607 } 629 }
608 ++str; 630 ++str;
631 // interval
632 { uint8_t ms = interval; while (ms--) wait_ms(1); }
609 } 633 }
610} 634}
611 635
612#endif 636void send_string_with_delay_P(const char *str, uint8_t interval) {
613 637 while (1) {
614/* for users whose OSes are set to Colemak */ 638 char ascii_code = pgm_read_byte(str);
615#if 0 639 if (!ascii_code) break;
616#include "keymap_colemak.h" 640 if (ascii_code == 1) {
617 641 // tap
618const bool ascii_to_colemak_shift_lut[0x80] PROGMEM = { 642 uint8_t keycode = pgm_read_byte(++str);
619 0, 0, 0, 0, 0, 0, 0, 0, 643 register_code(keycode);
620 0, 0, 0, 0, 0, 0, 0, 0, 644 unregister_code(keycode);
621 0, 0, 0, 0, 0, 0, 0, 0, 645 } else if (ascii_code == 2) {
622 0, 0, 0, 0, 0, 0, 0, 0, 646 // down
623 0, 1, 1, 1, 1, 1, 1, 0, 647 uint8_t keycode = pgm_read_byte(++str);
624 1, 1, 1, 1, 0, 0, 0, 0, 648 register_code(keycode);
625 0, 0, 0, 0, 0, 0, 0, 0, 649 } else if (ascii_code == 3) {
626 0, 0, 1, 0, 1, 0, 1, 1, 650 // up
627 1, 1, 1, 1, 1, 1, 1, 1, 651 uint8_t keycode = pgm_read_byte(++str);
628 1, 1, 1, 1, 1, 1, 1, 1, 652 unregister_code(keycode);
629 1, 1, 1, 1, 1, 1, 1, 1, 653 } else {
630 1, 1, 1, 0, 0, 0, 1, 1, 654 send_char(ascii_code);
631 0, 0, 0, 0, 0, 0, 0, 0, 655 }
632 0, 0, 0, 0, 0, 0, 0, 0, 656 ++str;
633 0, 0, 0, 0, 0, 0, 0, 0, 657 // interval
634 0, 0, 0, 1, 1, 1, 1, 0 658 { uint8_t ms = interval; while (ms--) wait_ms(1); }
635}; 659 }
660}
636 661
637const uint8_t ascii_to_colemak_keycode_lut[0x80] PROGMEM = { 662void send_char(char ascii_code) {
638 0, 0, 0, 0, 0, 0, 0, 0, 663 uint8_t keycode;
639 KC_BSPC, KC_TAB, KC_ENT, 0, 0, 0, 0, 0, 664 keycode = pgm_read_byte(&ascii_to_keycode_lut[(uint8_t)ascii_code]);
640 0, 0, 0, 0, 0, 0, 0, 0, 665 if (pgm_read_byte(&ascii_to_shift_lut[(uint8_t)ascii_code])) {
641 0, 0, 0, KC_ESC, 0, 0, 0, 0, 666 register_code(KC_LSFT);
642 KC_SPC, KC_1, KC_QUOT, KC_3, KC_4, KC_5, KC_7, KC_QUOT, 667 register_code(keycode);
643 KC_9, KC_0, KC_8, KC_EQL, KC_COMM, KC_MINS, KC_DOT, KC_SLSH, 668 unregister_code(keycode);
644 KC_0, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, 669 unregister_code(KC_LSFT);
645 KC_8, KC_9, CM_SCLN, CM_SCLN, KC_COMM, KC_EQL, KC_DOT, KC_SLSH, 670 } else {
646 KC_2, CM_A, CM_B, CM_C, CM_D, CM_E, CM_F, CM_G, 671 register_code(keycode);
647 CM_H, CM_I, CM_J, CM_K, CM_L, CM_M, CM_N, CM_O, 672 unregister_code(keycode);
648 CM_P, CM_Q, CM_R, CM_S, CM_T, CM_U, CM_V, CM_W, 673 }
649 CM_X, CM_Y, CM_Z, KC_LBRC, KC_BSLS, KC_RBRC, KC_6, KC_MINS, 674}
650 KC_GRV, CM_A, CM_B, CM_C, CM_D, CM_E, CM_F, CM_G,
651 CM_H, CM_I, CM_J, CM_K, CM_L, CM_M, CM_N, CM_O,
652 CM_P, CM_Q, CM_R, CM_S, CM_T, CM_U, CM_V, CM_W,
653 CM_X, CM_Y, CM_Z, KC_LBRC, KC_BSLS, KC_RBRC, KC_GRV, KC_DEL
654};
655 675
656#endif 676void set_single_persistent_default_layer(uint8_t default_layer) {
677 #if defined(AUDIO_ENABLE) && defined(DEFAULT_LAYER_SONGS)
678 PLAY_SONG(default_layer_songs[default_layer]);
679 #endif
680 eeconfig_update_default_layer(1U<<default_layer);
681 default_layer_set(1U<<default_layer);
682}
657 683
658void update_tri_layer(uint8_t layer1, uint8_t layer2, uint8_t layer3) { 684void update_tri_layer(uint8_t layer1, uint8_t layer2, uint8_t layer3) {
659 if (IS_LAYER_ON(layer1) && IS_LAYER_ON(layer2)) { 685 if (IS_LAYER_ON(layer1) && IS_LAYER_ON(layer2)) {
@@ -705,6 +731,9 @@ void matrix_init_quantum() {
705 #ifdef BACKLIGHT_ENABLE 731 #ifdef BACKLIGHT_ENABLE
706 backlight_init_ports(); 732 backlight_init_ports();
707 #endif 733 #endif
734 #ifdef AUDIO_ENABLE
735 audio_init();
736 #endif
708 matrix_init_kb(); 737 matrix_init_kb();
709} 738}
710 739
@@ -814,14 +843,14 @@ void backlight_set(uint8_t level)
814 // _SFR_IO8((backlight_pin >> 4) + 2) &= ~_BV(backlight_pin & 0xF); 843 // _SFR_IO8((backlight_pin >> 4) + 2) &= ~_BV(backlight_pin & 0xF);
815 // #endif 844 // #endif
816 #endif 845 #endif
817 } 846 }
818 #ifndef NO_BACKLIGHT_CLOCK 847 #ifndef NO_BACKLIGHT_CLOCK
819 else if ( level == BACKLIGHT_LEVELS ) { 848 else if ( level == BACKLIGHT_LEVELS ) {
820 // Turn on PWM control of backlight pin 849 // Turn on PWM control of backlight pin
821 TCCR1A |= _BV(COM1x1); 850 TCCR1A |= _BV(COM1x1);
822 // Set the brightness 851 // Set the brightness
823 OCR1x = 0xFFFF; 852 OCR1x = 0xFFFF;
824 } 853 }
825 else { 854 else {
826 // Turn on PWM control of backlight pin 855 // Turn on PWM control of backlight pin
827 TCCR1A |= _BV(COM1x1); 856 TCCR1A |= _BV(COM1x1);
@@ -839,7 +868,7 @@ uint8_t backlight_tick = 0;
839 868
840void backlight_task(void) { 869void backlight_task(void) {
841 #ifdef NO_BACKLIGHT_CLOCK 870 #ifdef NO_BACKLIGHT_CLOCK
842 if ((0xFFFF >> ((BACKLIGHT_LEVELS - backlight_config.level) * ((BACKLIGHT_LEVELS + 1) / 2))) & (1 << backlight_tick)) { 871 if ((0xFFFF >> ((BACKLIGHT_LEVELS - backlight_config.level) * ((BACKLIGHT_LEVELS + 1) / 2))) & (1 << backlight_tick)) {
843 #if BACKLIGHT_ON_STATE == 0 872 #if BACKLIGHT_ON_STATE == 0
844 // PORTx &= ~n 873 // PORTx &= ~n
845 _SFR_IO8((backlight_pin >> 4) + 2) &= ~_BV(backlight_pin & 0xF); 874 _SFR_IO8((backlight_pin >> 4) + 2) &= ~_BV(backlight_pin & 0xF);
diff --git a/quantum/quantum.h b/quantum/quantum.h
index 2bf18d095..f3333a002 100644
--- a/quantum/quantum.h
+++ b/quantum/quantum.h
@@ -40,7 +40,7 @@
40#include "action_util.h" 40#include "action_util.h"
41#include <stdlib.h> 41#include <stdlib.h>
42#include "print.h" 42#include "print.h"
43 43#include "send_string_keycodes.h"
44 44
45extern uint32_t default_layer_state; 45extern uint32_t default_layer_state;
46 46
@@ -56,9 +56,14 @@ extern uint32_t default_layer_state;
56#endif // MIDI_ENABLE 56#endif // MIDI_ENABLE
57 57
58#ifdef AUDIO_ENABLE 58#ifdef AUDIO_ENABLE
59 #include "audio.h"
59 #include "process_audio.h" 60 #include "process_audio.h"
60#endif 61#endif
61 62
63#ifdef STENO_ENABLE
64 #include "process_steno.h"
65#endif
66
62#if defined(AUDIO_ENABLE) || (defined(MIDI_ENABLE) && defined(MIDI_BASIC)) 67#if defined(AUDIO_ENABLE) || (defined(MIDI_ENABLE) && defined(MIDI_BASIC))
63 #include "process_music.h" 68 #include "process_music.h"
64#endif 69#endif
@@ -94,12 +99,42 @@ extern uint32_t default_layer_state;
94 #include "process_combo.h" 99 #include "process_combo.h"
95#endif 100#endif
96 101
97#define SEND_STRING(str) send_string(PSTR(str)) 102#ifdef KEY_LOCK_ENABLE
103 #include "process_key_lock.h"
104#endif
105
106#ifdef TERMINAL_ENABLE
107 #include "process_terminal.h"
108#else
109 #include "process_terminal_nop.h"
110#endif
111
112#define STRINGIZE(z) #z
113#define ADD_SLASH_X(y) STRINGIZE(\x ## y)
114#define SYMBOL_STR(x) ADD_SLASH_X(x)
115
116#define SS_TAP(keycode) "\1" SYMBOL_STR(keycode)
117#define SS_DOWN(keycode) "\2" SYMBOL_STR(keycode)
118#define SS_UP(keycode) "\3" SYMBOL_STR(keycode)
119
120#define SS_LCTRL(string) SS_DOWN(X_LCTRL) string SS_UP(X_LCTRL)
121#define SS_LGUI(string) SS_DOWN(X_LGUI) string SS_UP(X_LGUI)
122#define SS_LALT(string) SS_DOWN(X_LALT) string SS_UP(X_LALT)
123
124#define SEND_STRING(str) send_string_P(PSTR(str))
125extern const bool ascii_to_shift_lut[0x80];
126extern const uint8_t ascii_to_keycode_lut[0x80];
98void send_string(const char *str); 127void send_string(const char *str);
128void send_string_with_delay(const char *str, uint8_t interval);
129void send_string_P(const char *str);
130void send_string_with_delay_P(const char *str, uint8_t interval);
131void send_char(char ascii_code);
99 132
100// For tri-layer 133// For tri-layer
101void update_tri_layer(uint8_t layer1, uint8_t layer2, uint8_t layer3); 134void update_tri_layer(uint8_t layer1, uint8_t layer2, uint8_t layer3);
102 135
136void set_single_persistent_default_layer(uint8_t default_layer);
137
103void tap_random_base64(void); 138void tap_random_base64(void);
104 139
105#define IS_LAYER_ON(layer) (layer_state & (1UL << (layer))) 140#define IS_LAYER_ON(layer) (layer_state & (1UL << (layer)))
diff --git a/quantum/quantum_keycodes.h b/quantum/quantum_keycodes.h
index 6038e31c4..26c3c41a7 100644
--- a/quantum/quantum_keycodes.h
+++ b/quantum/quantum_keycodes.h
@@ -26,6 +26,10 @@
26#endif 26#endif
27#endif 27#endif
28 28
29// Fillers to make layering more clear
30#define _______ KC_TRNS
31#define XXXXXXX KC_NO
32
29enum quantum_keycodes { 33enum quantum_keycodes {
30 // Ranges used in shortucuts - not to be used directly 34 // Ranges used in shortucuts - not to be used directly
31 QK_TMK = 0x0000, 35 QK_TMK = 0x0000,
@@ -67,6 +71,12 @@ enum quantum_keycodes {
67 QK_TAP_DANCE_MAX = 0x57FF, 71 QK_TAP_DANCE_MAX = 0x57FF,
68 QK_LAYER_TAP_TOGGLE = 0x5800, 72 QK_LAYER_TAP_TOGGLE = 0x5800,
69 QK_LAYER_TAP_TOGGLE_MAX = 0x58FF, 73 QK_LAYER_TAP_TOGGLE_MAX = 0x58FF,
74#ifdef STENO_ENABLE
75 QK_STENO = 0x5A00,
76 QK_STENO_BOLT = 0x5A30,
77 QK_STENO_GEMINI = 0x5A31,
78 QK_STENO_MAX = 0x5A3F,
79#endif
70 QK_MOD_TAP = 0x6000, 80 QK_MOD_TAP = 0x6000,
71 QK_MOD_TAP_MAX = 0x7FFF, 81 QK_MOD_TAP_MAX = 0x7FFF,
72#if defined(UNICODEMAP_ENABLE) && defined(UNICODE_ENABLE) 82#if defined(UNICODEMAP_ENABLE) && defined(UNICODE_ENABLE)
@@ -128,6 +138,9 @@ enum quantum_keycodes {
128 MU_OFF, 138 MU_OFF,
129 MU_TOG, 139 MU_TOG,
130 140
141 // Music mode cycle
142 MU_MOD,
143
131 // Music voice iterate 144 // Music voice iterate
132 MUV_IN, 145 MUV_IN,
133 MUV_DE, 146 MUV_DE,
@@ -388,6 +401,14 @@ enum quantum_keycodes {
388 RGB_SAD, 401 RGB_SAD,
389 RGB_VAI, 402 RGB_VAI,
390 RGB_VAD, 403 RGB_VAD,
404 RGB_MODE_PLAIN,
405 RGB_MODE_BREATHE,
406 RGB_MODE_RAINBOW,
407 RGB_MODE_SWIRL,
408 RGB_MODE_SNAKE,
409 RGB_MODE_KNIGHT,
410 RGB_MODE_XMAS,
411 RGB_MODE_GRADIENT,
391 412
392 // Left shift, open paren 413 // Left shift, open paren
393 KC_LSPO, 414 KC_LSPO,
@@ -406,6 +427,15 @@ enum quantum_keycodes {
406 OUT_BT, 427 OUT_BT,
407#endif 428#endif
408 429
430#ifdef KEY_LOCK_ENABLE
431 KC_LOCK,
432#endif
433
434#ifdef TERMINAL_ENABLE
435 TERM_ON,
436 TERM_OFF,
437#endif
438
409 // always leave at the end 439 // always leave at the end
410 SAFE_RANGE 440 SAFE_RANGE
411}; 441};
@@ -517,6 +547,14 @@ enum quantum_keycodes {
517 547
518#define KC_GESC GRAVE_ESC 548#define KC_GESC GRAVE_ESC
519 549
550#define RGB_M_P RGB_MODE_PLAIN
551#define RGB_M_B RGB_MODE_BREATHE
552#define RGB_M_R RGB_MODE_RAINBOW
553#define RGB_M_SW RGB_MODE_SWIRL
554#define RGB_M_SN RGB_MODE_SNAKE
555#define RGB_M_K RGB_MODE_KNIGHT
556#define RGB_M_X RGB_MODE_XMAS
557#define RGB_M_G RGB_MODE_GRADIENT
520 558
521// L-ayer, T-ap - 256 keycode max, 16 layer max 559// L-ayer, T-ap - 256 keycode max, 16 layer max
522#define LT(layer, kc) (kc | QK_LAYER_TAP | ((layer & 0xF) << 8)) 560#define LT(layer, kc) (kc | QK_LAYER_TAP | ((layer & 0xF) << 8))
diff --git a/quantum/rgblight.c b/quantum/rgblight.c
index 49420de37..9ac1893d2 100644
--- a/quantum/rgblight.c
+++ b/quantum/rgblight.c
@@ -22,7 +22,6 @@
22#include "debug.h" 22#include "debug.h"
23#include "led_tables.h" 23#include "led_tables.h"
24 24
25
26__attribute__ ((weak)) 25__attribute__ ((weak))
27const uint8_t RGBLED_BREATHING_INTERVALS[] PROGMEM = {30, 20, 10, 5}; 26const uint8_t RGBLED_BREATHING_INTERVALS[] PROGMEM = {30, 20, 10, 5};
28__attribute__ ((weak)) 27__attribute__ ((weak))
@@ -32,7 +31,7 @@ const uint8_t RGBLED_RAINBOW_SWIRL_INTERVALS[] PROGMEM = {100, 50, 20};
32__attribute__ ((weak)) 31__attribute__ ((weak))
33const uint8_t RGBLED_SNAKE_INTERVALS[] PROGMEM = {100, 50, 20}; 32const uint8_t RGBLED_SNAKE_INTERVALS[] PROGMEM = {100, 50, 20};
34__attribute__ ((weak)) 33__attribute__ ((weak))
35const uint8_t RGBLED_KNIGHT_INTERVALS[] PROGMEM = {100, 50, 20}; 34const uint8_t RGBLED_KNIGHT_INTERVALS[] PROGMEM = {127, 63, 31};
36__attribute__ ((weak)) 35__attribute__ ((weak))
37const uint16_t RGBLED_GRADIENT_RANGES[] PROGMEM = {360, 240, 180, 120, 90}; 36const uint16_t RGBLED_GRADIENT_RANGES[] PROGMEM = {360, 240, 180, 120, 90};
38 37
@@ -197,6 +196,14 @@ void rgblight_step_reverse(void) {
197 rgblight_mode(mode); 196 rgblight_mode(mode);
198} 197}
199 198
199uint32_t rgblight_get_mode(void) {
200 if (!rgblight_config.enable) {
201 return false;
202 }
203
204 return rgblight_config.mode;
205}
206
200void rgblight_mode(uint8_t mode) { 207void rgblight_mode(uint8_t mode) {
201 if (!rgblight_config.enable) { 208 if (!rgblight_config.enable) {
202 return; 209 return;
@@ -220,6 +227,8 @@ void rgblight_mode(uint8_t mode) {
220 // MODE 9-14, rainbow swirl 227 // MODE 9-14, rainbow swirl
221 // MODE 15-20, snake 228 // MODE 15-20, snake
222 // MODE 21-23, knight 229 // MODE 21-23, knight
230 // MODE 24, xmas
231 // MODE 25-34, static rainbow
223 232
224 #ifdef RGBLIGHT_ANIMATIONS 233 #ifdef RGBLIGHT_ANIMATIONS
225 rgblight_timer_enable(); 234 rgblight_timer_enable();
@@ -540,56 +549,44 @@ void rgblight_effect_snake(uint8_t interval) {
540 } 549 }
541} 550}
542void rgblight_effect_knight(uint8_t interval) { 551void rgblight_effect_knight(uint8_t interval) {
543 static int8_t pos = 0;
544 static uint16_t last_timer = 0; 552 static uint16_t last_timer = 0;
545 uint8_t i, j, cur;
546 int8_t k;
547 LED_TYPE preled[RGBLED_NUM];
548 static int8_t increment = -1;
549 if (timer_elapsed(last_timer) < pgm_read_byte(&RGBLED_KNIGHT_INTERVALS[interval])) { 553 if (timer_elapsed(last_timer) < pgm_read_byte(&RGBLED_KNIGHT_INTERVALS[interval])) {
550 return; 554 return;
551 } 555 }
552 last_timer = timer_read(); 556 last_timer = timer_read();
557
558 static int8_t low_bound = 0;
559 static int8_t high_bound = RGBLIGHT_EFFECT_KNIGHT_LENGTH - 1;
560 static int8_t increment = 1;
561 uint8_t i, cur;
562
563 // Set all the LEDs to 0
553 for (i = 0; i < RGBLED_NUM; i++) { 564 for (i = 0; i < RGBLED_NUM; i++) {
554 preled[i].r = 0; 565 led[i].r = 0;
555 preled[i].g = 0; 566 led[i].g = 0;
556 preled[i].b = 0; 567 led[i].b = 0;
557 for (j = 0; j < RGBLIGHT_EFFECT_KNIGHT_LENGTH; j++) {
558 k = pos + j * increment;
559 if (k < 0) {
560 k = 0;
561 }
562 if (k >= RGBLED_NUM) {
563 k = RGBLED_NUM - 1;
564 }
565 if (i == k) {
566 sethsv(rgblight_config.hue, rgblight_config.sat, rgblight_config.val, (LED_TYPE *)&preled[i]);
567 }
568 }
569 } 568 }
570 if (RGBLIGHT_EFFECT_KNIGHT_OFFSET) { 569 // Determine which LEDs should be lit up
571 for (i = 0; i < RGBLED_NUM; i++) { 570 for (i = 0; i < RGBLIGHT_EFFECT_KNIGHT_LED_NUM; i++) {
572 cur = (i + RGBLIGHT_EFFECT_KNIGHT_OFFSET) % RGBLED_NUM; 571 cur = (i + RGBLIGHT_EFFECT_KNIGHT_OFFSET) % RGBLED_NUM;
573 led[i].r = preled[cur].r; 572
574 led[i].g = preled[cur].g; 573 if (i >= low_bound && i <= high_bound) {
575 led[i].b = preled[cur].b; 574 sethsv(rgblight_config.hue, rgblight_config.sat, rgblight_config.val, (LED_TYPE *)&led[cur]);
575 } else {
576 led[cur].r = 0;
577 led[cur].g = 0;
578 led[cur].b = 0;
576 } 579 }
577 } 580 }
578 rgblight_set(); 581 rgblight_set();
579 if (increment == 1) { 582
580 if (pos - 1 < 0 - RGBLIGHT_EFFECT_KNIGHT_LENGTH) { 583 // Move from low_bound to high_bound changing the direction we increment each
581 pos = 0 - RGBLIGHT_EFFECT_KNIGHT_LENGTH; 584 // time a boundary is hit.
582 increment = -1; 585 low_bound += increment;
583 } else { 586 high_bound += increment;
584 pos -= 1; 587
585 } 588 if (high_bound <= 0 || low_bound >= RGBLIGHT_EFFECT_KNIGHT_LED_NUM - 1) {
586 } else { 589 increment = -increment;
587 if (pos + 1 > RGBLED_NUM + RGBLIGHT_EFFECT_KNIGHT_LENGTH) {
588 pos = RGBLED_NUM + RGBLIGHT_EFFECT_KNIGHT_LENGTH - 1;
589 increment = 1;
590 } else {
591 pos += 1;
592 }
593 } 590 }
594} 591}
595 592
diff --git a/quantum/rgblight.h b/quantum/rgblight.h
index 6b609da7f..c1b3378b3 100644
--- a/quantum/rgblight.h
+++ b/quantum/rgblight.h
@@ -23,18 +23,19 @@
23#endif 23#endif
24 24
25#ifndef RGBLIGHT_EFFECT_SNAKE_LENGTH 25#ifndef RGBLIGHT_EFFECT_SNAKE_LENGTH
26#define RGBLIGHT_EFFECT_SNAKE_LENGTH 7 26#define RGBLIGHT_EFFECT_SNAKE_LENGTH 4
27#endif 27#endif
28 28
29#ifndef RGBLIGHT_EFFECT_KNIGHT_LENGTH 29#ifndef RGBLIGHT_EFFECT_KNIGHT_LENGTH
30#define RGBLIGHT_EFFECT_KNIGHT_LENGTH 7 30#define RGBLIGHT_EFFECT_KNIGHT_LENGTH 3
31#endif 31#endif
32
32#ifndef RGBLIGHT_EFFECT_KNIGHT_OFFSET 33#ifndef RGBLIGHT_EFFECT_KNIGHT_OFFSET
33#define RGBLIGHT_EFFECT_KNIGHT_OFFSET 9 34#define RGBLIGHT_EFFECT_KNIGHT_OFFSET 0
34#endif 35#endif
35 36
36#ifndef RGBLIGHT_EFFECT_DUALKNIGHT_LENGTH 37#ifndef RGBLIGHT_EFFECT_KNIGHT_LED_NUM
37#define RGBLIGHT_EFFECT_DUALKNIGHT_LENGTH 4 38#define RGBLIGHT_EFFECT_KNIGHT_LED_NUM RGBLED_NUM
38#endif 39#endif
39 40
40#ifndef RGBLIGHT_EFFECT_CHRISTMAS_INTERVAL 41#ifndef RGBLIGHT_EFFECT_CHRISTMAS_INTERVAL
@@ -62,7 +63,7 @@
62#include <stdbool.h> 63#include <stdbool.h>
63#include "eeconfig.h" 64#include "eeconfig.h"
64#ifndef RGBLIGHT_CUSTOM_DRIVER 65#ifndef RGBLIGHT_CUSTOM_DRIVER
65#include "light_ws2812.h" 66#include "ws2812.h"
66#endif 67#endif
67#include "rgblight_types.h" 68#include "rgblight_types.h"
68 69
@@ -92,6 +93,7 @@ void rgblight_toggle(void);
92void rgblight_enable(void); 93void rgblight_enable(void);
93void rgblight_step(void); 94void rgblight_step(void);
94void rgblight_step_reverse(void); 95void rgblight_step_reverse(void);
96uint32_t rgblight_get_mode(void);
95void rgblight_mode(uint8_t mode); 97void rgblight_mode(uint8_t mode);
96void rgblight_set(void); 98void rgblight_set(void);
97void rgblight_update_dword(uint32_t dword); 99void rgblight_update_dword(uint32_t dword);
diff --git a/quantum/send_string_keycodes.h b/quantum/send_string_keycodes.h
new file mode 100644
index 000000000..0e308be50
--- /dev/null
+++ b/quantum/send_string_keycodes.h
@@ -0,0 +1,168 @@
1#ifndef SEND_STRING_KEYCODES
2#define SEND_STRING_KEYCODES
3
4#define X_NO 00
5#define X_ROLL_OVER 01
6#define X_POST_FAIL 02
7#define X_UNDEFINED 03
8#define X_A 04
9#define X_B 05
10#define X_C 06
11#define X_D 07
12#define X_E 08
13#define X_F 09
14#define X_G 0A
15#define X_H 0B
16#define X_I 0C
17#define X_J 0D
18#define X_K 0E
19#define X_L 0F
20#define X_M 10
21#define X_N 11
22#define X_O 12
23#define X_P 13
24#define X_Q 14
25#define X_R 15
26#define X_S 16
27#define X_T 17
28#define X_U 18
29#define X_V 19
30#define X_W 1A
31#define X_X 1B
32#define X_Y 1C
33#define X_Z 1D
34#define X_1 1E
35#define X_2 1F
36#define X_3 20
37#define X_4 21
38#define X_5 22
39#define X_6 23
40#define X_7 24
41#define X_8 25
42#define X_9 26
43#define X_0 27
44#define X_ENTER 28
45#define X_ESCAPE 29
46#define X_BSPACE 2A
47#define X_TAB 2B
48#define X_SPACE 2C
49#define X_MINUS 2D
50#define X_EQUAL 2E
51#define X_LBRACKET 2F
52#define X_RBRACKET 30
53#define X_BSLASH 31
54#define X_NONUS_HASH 32
55#define X_SCOLON 33
56#define X_QUOTE 34
57#define X_GRAVE 35
58#define X_COMMA 36
59#define X_DOT 37
60#define X_SLASH 38
61#define X_CAPSLOCK 39
62#define X_F1 3A
63#define X_F2 3B
64#define X_F3 3C
65#define X_F4 3D
66#define X_F5 3E
67#define X_F6 3F
68#define X_F7 40
69#define X_F8 41
70#define X_F9 42
71#define X_F10 43
72#define X_F11 44
73#define X_F12 45
74#define X_PSCREEN 46
75#define X_SCROLLLOCK 47
76#define X_PAUSE 48
77#define X_INSERT 49
78#define X_HOME 4A
79#define X_PGUP 4B
80#define X_DELETE 4C
81#define X_END 4D
82#define X_PGDOWN 4E
83#define X_RIGHT 4F
84#define X_LEFT 50
85#define X_DOWN 51
86#define X_UP 52
87#define X_NUMLOCK 53
88#define X_KP_SLASH 54
89#define X_KP_ASTERISK 55
90#define X_KP_MINUS 56
91#define X_KP_PLUS 57
92#define X_KP_ENTER 58
93#define X_KP_1 59
94#define X_KP_2 5A
95#define X_KP_3 5B
96#define X_KP_4 5C
97#define X_KP_5 5D
98#define X_KP_6 5E
99#define X_KP_7 5F
100#define X_KP_8 60
101#define X_KP_9 61
102#define X_KP_0 62
103#define X_KP_DOT 63
104#define X_NONUS_BSLASH 64
105#define X_APPLICATION 65
106#define X_POWER 66
107#define X_KP_EQUAL 67
108#define X_F13 68
109#define X_F14 69
110#define X_F15 6A
111#define X_F16 6B
112#define X_F17 6C
113#define X_F18 6D
114#define X_F19 6E
115#define X_F20 6F
116#define X_F21 70
117#define X_F22 71
118#define X_F23 72
119#define X_F24 73
120#define X_EXECUTE 74
121#define X_HELP 75
122#define X_MENU 76
123#define X_SELECT 77
124#define X_STOP 78
125#define X_AGAIN 79
126#define X_UNDO 7A
127#define X_CUT 7B
128#define X_COPY 7C
129#define X_PASTE 7D
130#define X_FIND 7E
131#define X__MUTE 7F
132#define X__VOLUP 80
133#define X__VOLDOWN 81
134#define X_LOCKING_CAPS 82
135#define X_LOCKING_NUM 83
136#define X_LOCKING_SCROLL 84
137#define X_KP_COMMA 85
138#define X_KP_EQUAL_AS400 86
139#define X_INT1 87
140#define X_INT2 88
141#define X_INT3 89
142#define X_INT4 8A
143#define X_INT5 8B
144#define X_INT6 8C
145#define X_INT7 8D
146#define X_INT8 8E
147#define X_INT9 8F
148#define X_LANG1 90
149#define X_LANG2 91
150#define X_LANG3 92
151#define X_LANG4 93
152#define X_LANG5 94
153#define X_LANG6 95
154#define X_LANG7 96
155#define X_LANG8 97
156#define X_LANG9 98
157
158/* Modifiers */
159#define X_LCTRL e0
160#define X_LSHIFT e1
161#define X_LALT e2
162#define X_LGUI e3
163#define X_RCTRL e4
164#define X_RSHIFT e5
165#define X_RALT e6
166#define X_RGUI e7
167
168#endif \ No newline at end of file
diff --git a/quantum/template/config.h b/quantum/template/config.h
index dbca45765..700a56f52 100644
--- a/quantum/template/config.h
+++ b/quantum/template/config.h
@@ -67,6 +67,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
67/* Locking resynchronize hack */ 67/* Locking resynchronize hack */
68#define LOCKING_RESYNC_ENABLE 68#define LOCKING_RESYNC_ENABLE
69 69
70/* If defined, GRAVE_ESC will always act as ESC when CTRL is held.
71 * This is userful for the Windows task manager shortcut (ctrl+shift+esc).
72 */
73// #define GRAVE_ESC_CTRL_OVERRIDE
74
70/* 75/*
71 * Force NKRO 76 * Force NKRO
72 * 77 *
diff --git a/quantum/template/readme.md b/quantum/template/readme.md
index b16f4cd76..33562764d 100644
--- a/quantum/template/readme.md
+++ b/quantum/template/readme.md
@@ -7,22 +7,30 @@ For the full Quantum feature list, see [the parent readme](/).
7 7
8## Building 8## Building
9 9
10Download or clone the whole firmware and navigate to the keyboards/%KEYBOARD% folder. Once your dev env is setup, you'll be able to type `make` to generate your .hex - you can then use the Teensy Loader to program your .hex file. 10Download or clone the whole firmware and navigate to the root folder. Once your dev env is setup, you'll be able to type `make %KEYBOARD%-default` to generate your .hex - you can then use the Teensy Loader to program your .hex file.
11
12(Note: replace %KEYBOARD% with the name of your keyboard.)
11 13
12Depending on which keymap you would like to use, you will have to compile slightly differently. 14Depending on which keymap you would like to use, you will have to compile slightly differently.
13 15
14### Default 16### Default
15 17
16To build with the default keymap, simply run `make default`. 18To build with the default keymap, simply run `make %KEYBOARD%-default`.
17 19
18### Other Keymaps 20### Other Keymaps
19 21
20Several version of keymap are available in advance but you are recommended to define your favorite layout yourself. To define your own keymap create a folder with the name of your keymap in the keymaps folder, and see keymap documentation (you can find in top readme.md) and existant keymap files. 22Several version of keymap are available in advance but you are recommended to define your favorite layout yourself. To define your own keymap create a folder with the name of your keymap in the keymaps folder. Create a `readme.md` and a `keymap.c` file to complete your new keymap. When you are done your file tree should look like this:
23
24* `qmk_firmware/`
25 * `keyboard/`
26 * `keymaps/`
27 * `config.h` (optional)
28 * `keymap.c`
29 * `readme.md`
30 * `rules.mk` (optional)
21 31
22To build the firmware binary hex file with a keymap just do `make` with a keymap like this: 32To build the firmware binary hex file with a keymap just do `make` with a keymap like this:
23 33
24``` 34```
25$ make [default|jack|<name>] 35$ make %KEYBOARD%-[default|jack|<name>]
26``` 36```
27
28Keymaps follow the format **__\<name\>.c__** and are stored in the `keymaps` folder.
diff --git a/quantum/visualizer/common_gfxconf.h b/quantum/visualizer/common_gfxconf.h
new file mode 100644
index 000000000..eb705b188
--- /dev/null
+++ b/quantum/visualizer/common_gfxconf.h
@@ -0,0 +1,325 @@
1/**
2 * This file has a different license to the rest of the uGFX system.
3 * You can copy, modify and distribute this file as you see fit.
4 * You do not need to publish your source modifications to this file.
5 * The only thing you are not permitted to do is to relicense it
6 * under a different license.
7 */
8
9/**
10 * Copy this file into your project directory and rename it as gfxconf.h
11 * Edit your copy to turn on the uGFX features you want to use.
12 * The values below are the defaults.
13 *
14 * Only remove the comments from lines where you want to change the
15 * default value. This allows definitions to be included from
16 * driver makefiles when required and provides the best future
17 * compatibility for your project.
18 *
19 * Please use spaces instead of tabs in this file.
20 */
21
22#ifndef COMMON_GFXCONF_H
23#define COMMON_GFXCONF_H
24
25
26///////////////////////////////////////////////////////////////////////////
27// GOS - One of these must be defined, preferably in your Makefile //
28///////////////////////////////////////////////////////////////////////////
29//#define GFX_USE_OS_CHIBIOS TRUE
30//#define GFX_USE_OS_FREERTOS FALSE
31// #define GFX_FREERTOS_USE_TRACE FALSE
32//#define GFX_USE_OS_WIN32 FALSE
33//#define GFX_USE_OS_LINUX FALSE
34//#define GFX_USE_OS_OSX FALSE
35//#define GFX_USE_OS_ECOS FALSE
36//#define GFX_USE_OS_RAWRTOS FALSE
37//#define GFX_USE_OS_ARDUINO FALSE
38//#define GFX_USE_OS_KEIL FALSE
39//#define GFX_USE_OS_CMSIS FALSE
40//#define GFX_USE_OS_RAW32 FALSE
41// #define INTERRUPTS_OFF() optional_code
42// #define INTERRUPTS_ON() optional_code
43// These are not defined by default for some reason
44#define GOS_NEED_X_THREADS FALSE
45#define GOS_NEED_X_HEAP FALSE
46
47// Options that (should where relevant) apply to all operating systems
48 #define GFX_NO_INLINE FALSE
49// #define GFX_COMPILER GFX_COMPILER_UNKNOWN
50// #define GFX_CPU GFX_CPU_UNKNOWN
51// #define GFX_OS_HEAP_SIZE 0
52// #define GFX_OS_NO_INIT FALSE
53// #define GFX_OS_INIT_NO_WARNING FALSE
54// #define GFX_OS_PRE_INIT_FUNCTION myHardwareInitRoutine
55// #define GFX_OS_EXTRA_INIT_FUNCTION myOSInitRoutine
56// #define GFX_OS_EXTRA_DEINIT_FUNCTION myOSDeInitRoutine
57
58
59///////////////////////////////////////////////////////////////////////////
60// GDISP //
61///////////////////////////////////////////////////////////////////////////
62#define GFX_USE_GDISP TRUE
63
64//#define GDISP_NEED_AUTOFLUSH FALSE
65//#define GDISP_NEED_TIMERFLUSH FALSE
66//#define GDISP_NEED_VALIDATION TRUE
67//#define GDISP_NEED_CLIP TRUE
68#define GDISP_NEED_CIRCLE TRUE
69#define GDISP_NEED_ELLIPSE TRUE
70#define GDISP_NEED_ARC TRUE
71#define GDISP_NEED_ARCSECTORS TRUE
72#define GDISP_NEED_CONVEX_POLYGON TRUE
73//#define GDISP_NEED_SCROLL FALSE
74#define GDISP_NEED_PIXELREAD TRUE
75#define GDISP_NEED_CONTROL TRUE
76//#define GDISP_NEED_QUERY FALSE
77//#define GDISP_NEED_MULTITHREAD FALSE
78//#define GDISP_NEED_STREAMING FALSE
79#define GDISP_NEED_TEXT TRUE
80// #define GDISP_NEED_TEXT_WORDWRAP FALSE
81// #define GDISP_NEED_ANTIALIAS FALSE
82// #define GDISP_NEED_UTF8 FALSE
83 #define GDISP_NEED_TEXT_KERNING TRUE
84// #define GDISP_INCLUDE_FONT_UI1 FALSE
85// #define GDISP_INCLUDE_FONT_UI2 FALSE // The smallest preferred font.
86// #define GDISP_INCLUDE_FONT_LARGENUMBERS FALSE
87// #define GDISP_INCLUDE_FONT_DEJAVUSANS10 FALSE
88// #define GDISP_INCLUDE_FONT_DEJAVUSANS12 FALSE
89// #define GDISP_INCLUDE_FONT_DEJAVUSANS16 FALSE
90// #define GDISP_INCLUDE_FONT_DEJAVUSANS20 FALSE
91// #define GDISP_INCLUDE_FONT_DEJAVUSANS24 FALSE
92// #define GDISP_INCLUDE_FONT_DEJAVUSANS32 FALSE
93 #define GDISP_INCLUDE_FONT_DEJAVUSANSBOLD12 TRUE
94// #define GDISP_INCLUDE_FONT_FIXED_10X20 FALSE
95// #define GDISP_INCLUDE_FONT_FIXED_7X14 FALSE
96 #define GDISP_INCLUDE_FONT_FIXED_5X8 TRUE
97// #define GDISP_INCLUDE_FONT_DEJAVUSANS12_AA FALSE
98// #define GDISP_INCLUDE_FONT_DEJAVUSANS16_AA FALSE
99// #define GDISP_INCLUDE_FONT_DEJAVUSANS20_AA FALSE
100// #define GDISP_INCLUDE_FONT_DEJAVUSANS24_AA FALSE
101// #define GDISP_INCLUDE_FONT_DEJAVUSANS32_AA FALSE
102// #define GDISP_INCLUDE_FONT_DEJAVUSANSBOLD12_AA FALSE
103// #define GDISP_INCLUDE_USER_FONTS FALSE
104
105//#define GDISP_NEED_IMAGE FALSE
106// #define GDISP_NEED_IMAGE_NATIVE FALSE
107// #define GDISP_NEED_IMAGE_GIF FALSE
108// #define GDISP_NEED_IMAGE_BMP FALSE
109// #define GDISP_NEED_IMAGE_BMP_1 FALSE
110// #define GDISP_NEED_IMAGE_BMP_4 FALSE
111// #define GDISP_NEED_IMAGE_BMP_4_RLE FALSE
112// #define GDISP_NEED_IMAGE_BMP_8 FALSE
113// #define GDISP_NEED_IMAGE_BMP_8_RLE FALSE
114// #define GDISP_NEED_IMAGE_BMP_16 FALSE
115// #define GDISP_NEED_IMAGE_BMP_24 FALSE
116// #define GDISP_NEED_IMAGE_BMP_32 FALSE
117// #define GDISP_NEED_IMAGE_JPG FALSE
118// #define GDISP_NEED_IMAGE_PNG FALSE
119// #define GDISP_NEED_IMAGE_ACCOUNTING FALSE
120#ifdef EMULATOR
121#define GDISP_NEED_PIXMAP TRUE
122#endif
123// #define GDISP_NEED_PIXMAP_IMAGE FALSE
124
125//#define GDISP_DEFAULT_ORIENTATION GDISP_ROTATE_LANDSCAPE // If not defined the native hardware orientation is used.
126//#define GDISP_LINEBUF_SIZE 128
127//#define GDISP_STARTUP_COLOR Black
128#define GDISP_NEED_STARTUP_LOGO FALSE
129
130//#define GDISP_TOTAL_DISPLAYS 2
131
132 #ifdef GDISP_DRIVER_LIST
133 // For code and speed optimization define as TRUE or FALSE if all controllers have the same capability
134 #define GDISP_HARDWARE_STREAM_WRITE FALSE
135 #define GDISP_HARDWARE_STREAM_READ FALSE
136 #define GDISP_HARDWARE_STREAM_POS FALSE
137 #define GDISP_HARDWARE_DRAWPIXEL TRUE
138 #define GDISP_HARDWARE_CLEARS FALSE
139 #define GDISP_HARDWARE_FILLS FALSE
140 //#define GDISP_HARDWARE_BITFILLS FALSE
141 #define GDISP_HARDWARE_SCROLL FALSE
142 #define GDISP_HARDWARE_PIXELREAD TRUE
143 #define GDISP_HARDWARE_CONTROL TRUE
144 #define GDISP_HARDWARE_QUERY FALSE
145 #define GDISP_HARDWARE_CLIP FALSE
146
147 #define GDISP_PIXELFORMAT GDISP_PIXELFORMAT_RGB888
148 #endif
149
150// The custom format is not defined for some reason, so define it as error
151// so we don't get compiler warnings
152#define GDISP_PIXELFORMAT_CUSTOM GDISP_PIXELFORMAT_ERROR
153
154#define GDISP_USE_GFXNET FALSE
155// #define GDISP_GFXNET_PORT 13001
156// #define GDISP_GFXNET_CUSTOM_LWIP_STARTUP FALSE
157// #define GDISP_DONT_WAIT_FOR_NET_DISPLAY FALSE
158// #define GDISP_GFXNET_UNSAFE_SOCKETS FALSE
159
160
161///////////////////////////////////////////////////////////////////////////
162// GWIN //
163///////////////////////////////////////////////////////////////////////////
164#define GFX_USE_GWIN FALSE
165
166//#define GWIN_NEED_WINDOWMANAGER FALSE
167// #define GWIN_REDRAW_IMMEDIATE FALSE
168// #define GWIN_REDRAW_SINGLEOP FALSE
169// #define GWIN_NEED_FLASHING FALSE
170// #define GWIN_FLASHING_PERIOD 250
171
172//#define GWIN_NEED_CONSOLE FALSE
173// #define GWIN_CONSOLE_USE_HISTORY FALSE
174// #define GWIN_CONSOLE_HISTORY_AVERAGING FALSE
175// #define GWIN_CONSOLE_HISTORY_ATCREATE FALSE
176// #define GWIN_CONSOLE_ESCSEQ FALSE
177// #define GWIN_CONSOLE_USE_BASESTREAM FALSE
178// #define GWIN_CONSOLE_USE_FLOAT FALSE
179//#define GWIN_NEED_GRAPH FALSE
180//#define GWIN_NEED_GL3D FALSE
181
182//#define GWIN_NEED_WIDGET FALSE
183//#define GWIN_FOCUS_HIGHLIGHT_WIDTH 1
184// #define GWIN_NEED_LABEL FALSE
185// #define GWIN_LABEL_ATTRIBUTE FALSE
186// #define GWIN_NEED_BUTTON FALSE
187// #define GWIN_BUTTON_LAZY_RELEASE FALSE
188// #define GWIN_NEED_SLIDER FALSE
189// #define GWIN_SLIDER_NOSNAP FALSE
190// #define GWIN_SLIDER_DEAD_BAND 5
191// #define GWIN_SLIDER_TOGGLE_INC 20
192// #define GWIN_NEED_CHECKBOX FALSE
193// #define GWIN_NEED_IMAGE FALSE
194// #define GWIN_NEED_IMAGE_ANIMATION FALSE
195// #define GWIN_NEED_RADIO FALSE
196// #define GWIN_NEED_LIST FALSE
197// #define GWIN_NEED_LIST_IMAGES FALSE
198// #define GWIN_NEED_PROGRESSBAR FALSE
199// #define GWIN_PROGRESSBAR_AUTO FALSE
200// #define GWIN_NEED_KEYBOARD FALSE
201// #define GWIN_KEYBOARD_DEFAULT_LAYOUT VirtualKeyboard_English1
202// #define GWIN_NEED_KEYBOARD_ENGLISH1 TRUE
203// #define GWIN_NEED_TEXTEDIT FALSE
204// #define GWIN_FLAT_STYLING FALSE
205// #define GWIN_WIDGET_TAGS FALSE
206
207//#define GWIN_NEED_CONTAINERS FALSE
208// #define GWIN_NEED_CONTAINER FALSE
209// #define GWIN_NEED_FRAME FALSE
210// #define GWIN_NEED_TABSET FALSE
211// #define GWIN_TABSET_TABHEIGHT 18
212
213
214///////////////////////////////////////////////////////////////////////////
215// GEVENT //
216///////////////////////////////////////////////////////////////////////////
217#define GFX_USE_GEVENT TRUE
218
219//#define GEVENT_ASSERT_NO_RESOURCE FALSE
220//#define GEVENT_MAXIMUM_SIZE 32
221//#define GEVENT_MAX_SOURCE_LISTENERS 32
222
223
224///////////////////////////////////////////////////////////////////////////
225// GTIMER //
226///////////////////////////////////////////////////////////////////////////
227#define GFX_USE_GTIMER FALSE
228
229//#define GTIMER_THREAD_PRIORITY HIGH_PRIORITY
230//#define GTIMER_THREAD_WORKAREA_SIZE 2048
231
232
233///////////////////////////////////////////////////////////////////////////
234// GQUEUE //
235///////////////////////////////////////////////////////////////////////////
236#define GFX_USE_GQUEUE FALSE
237
238//#define GQUEUE_NEED_ASYNC FALSE
239//#define GQUEUE_NEED_GSYNC FALSE
240//#define GQUEUE_NEED_FSYNC FALSE
241//#define GQUEUE_NEED_BUFFERS FALSE
242
243///////////////////////////////////////////////////////////////////////////
244// GINPUT //
245///////////////////////////////////////////////////////////////////////////
246#define GFX_USE_GINPUT FALSE
247
248//#define GINPUT_NEED_MOUSE FALSE
249// #define GINPUT_TOUCH_STARTRAW FALSE
250// #define GINPUT_TOUCH_NOTOUCH FALSE
251// #define GINPUT_TOUCH_NOCALIBRATE FALSE
252// #define GINPUT_TOUCH_NOCALIBRATE_GUI FALSE
253// #define GINPUT_MOUSE_POLL_PERIOD 25
254// #define GINPUT_MOUSE_CLICK_TIME 300
255// #define GINPUT_TOUCH_CXTCLICK_TIME 700
256// #define GINPUT_TOUCH_USER_CALIBRATION_LOAD FALSE
257// #define GINPUT_TOUCH_USER_CALIBRATION_SAVE FALSE
258// #define GMOUSE_DRIVER_LIST GMOUSEVMT_Win32, GMOUSEVMT_Win32
259//#define GINPUT_NEED_KEYBOARD FALSE
260// #define GINPUT_KEYBOARD_POLL_PERIOD 200
261// #define GKEYBOARD_DRIVER_LIST GKEYBOARDVMT_Win32, GKEYBOARDVMT_Win32
262// #define GKEYBOARD_LAYOUT_OFF FALSE
263// #define GKEYBOARD_LAYOUT_SCANCODE2_US FALSE
264//#define GINPUT_NEED_TOGGLE FALSE
265//#define GINPUT_NEED_DIAL FALSE
266
267
268///////////////////////////////////////////////////////////////////////////
269// GFILE //
270///////////////////////////////////////////////////////////////////////////
271#define GFX_USE_GFILE FALSE
272
273//#define GFILE_NEED_PRINTG FALSE
274//#define GFILE_NEED_SCANG FALSE
275//#define GFILE_NEED_STRINGS FALSE
276//#define GFILE_NEED_FILELISTS FALSE
277//#define GFILE_NEED_STDIO FALSE
278//#define GFILE_NEED_NOAUTOMOUNT FALSE
279//#define GFILE_NEED_NOAUTOSYNC FALSE
280
281//#define GFILE_NEED_MEMFS FALSE
282//#define GFILE_NEED_ROMFS FALSE
283//#define GFILE_NEED_RAMFS FALSE
284//#define GFILE_NEED_FATFS FALSE
285//#define GFILE_NEED_NATIVEFS FALSE
286//#define GFILE_NEED_CHBIOSFS FALSE
287
288//#define GFILE_ALLOW_FLOATS FALSE
289//#define GFILE_ALLOW_DEVICESPECIFIC FALSE
290//#define GFILE_MAX_GFILES 3
291
292///////////////////////////////////////////////////////////////////////////
293// GADC //
294///////////////////////////////////////////////////////////////////////////
295#define GFX_USE_GADC FALSE
296
297//#define GADC_MAX_LOWSPEED_DEVICES 4
298
299
300///////////////////////////////////////////////////////////////////////////
301// GAUDIO //
302///////////////////////////////////////////////////////////////////////////
303#define GFX_USE_GAUDIO FALSE
304// There seems to be a bug in the ugfx code, the wrong define is used
305// So define it in order to avoid warnings
306#define GFX_USE_GAUDIN GFX_USE_GAUDIO
307// #define GAUDIO_NEED_PLAY FALSE
308// #define GAUDIO_NEED_RECORD FALSE
309
310
311///////////////////////////////////////////////////////////////////////////
312// GMISC //
313///////////////////////////////////////////////////////////////////////////
314#define GFX_USE_GMISC TRUE
315
316//#define GMISC_NEED_ARRAYOPS FALSE
317//#define GMISC_NEED_FASTTRIG FALSE
318//#define GMISC_NEED_FIXEDTRIG FALSE
319//#define GMISC_NEED_INVSQRT FALSE
320// #define GMISC_INVSQRT_MIXED_ENDIAN FALSE
321// #define GMISC_INVSQRT_REAL_SLOW FALSE
322#define GMISC_NEED_MATRIXFLOAT2D TRUE
323#define GMISC_NEED_MATRIXFIXED2D FALSE
324
325#endif /* COMMON_GFXCONF_H */
diff --git a/quantum/visualizer/default_animations.c b/quantum/visualizer/default_animations.c
new file mode 100644
index 000000000..2d0327372
--- /dev/null
+++ b/quantum/visualizer/default_animations.c
@@ -0,0 +1,176 @@
1/* Copyright 2017 Fred Sundvik
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#if defined(VISUALIZER_ENABLE)
18
19#include "default_animations.h"
20#include "visualizer.h"
21#ifdef LCD_ENABLE
22#include "lcd_keyframes.h"
23#endif
24#ifdef LCD_BACKLIGHT_ENABLE
25#include "lcd_backlight_keyframes.h"
26#endif
27
28#ifdef BACKLIGHT_ENABLE
29#include "led_backlight_keyframes.h"
30#endif
31
32#include "visualizer_keyframes.h"
33
34
35#if defined(LCD_ENABLE) || defined(LCD_BACKLIGHT_ENABLE) || defined(BACKLIGHT_ENABLE)
36
37static bool keyframe_enable(keyframe_animation_t* animation, visualizer_state_t* state) {
38#ifdef LCD_ENABLE
39 lcd_keyframe_enable(animation, state);
40#endif
41#ifdef LCD_BACKLIGHT_ENABLE
42 lcd_backlight_keyframe_enable(animation, state);
43#endif
44#ifdef BACKLIGHT_ENABLE
45 led_backlight_keyframe_enable(animation, state);
46#endif
47 return false;
48}
49
50static bool keyframe_disable(keyframe_animation_t* animation, visualizer_state_t* state) {
51#ifdef LCD_ENABLE
52 lcd_keyframe_disable(animation, state);
53#endif
54#ifdef LCD_BACKLIGHT_ENABLE
55 lcd_backlight_keyframe_disable(animation, state);
56#endif
57#ifdef BACKLIGHT_ENABLE
58 led_backlight_keyframe_disable(animation, state);
59#endif
60 return false;
61}
62
63static bool keyframe_fade_in(keyframe_animation_t* animation, visualizer_state_t* state) {
64 bool ret = false;
65#ifdef LCD_BACKLIGHT_ENABLE
66 ret |= lcd_backlight_keyframe_animate_color(animation, state);
67#endif
68#ifdef BACKLIGHT_ENABLE
69 ret |= led_backlight_keyframe_fade_in_all(animation, state);
70#endif
71 return ret;
72}
73
74static bool keyframe_fade_out(keyframe_animation_t* animation, visualizer_state_t* state) {
75 bool ret = false;
76#ifdef LCD_BACKLIGHT_ENABLE
77 ret |= lcd_backlight_keyframe_animate_color(animation, state);
78#endif
79#ifdef BACKLIGHT_ENABLE
80 ret |= led_backlight_keyframe_fade_out_all(animation, state);
81#endif
82 return ret;
83}
84
85
86// Don't worry, if the startup animation is long, you can use the keyboard like normal
87// during that time
88keyframe_animation_t default_startup_animation = {
89#if LCD_ENABLE
90 .num_frames = 3,
91#else
92 .num_frames = 2,
93#endif
94 .loop = false,
95 .frame_lengths = {
96 0,
97#if LCD_ENABLE
98 0,
99#endif
100 gfxMillisecondsToTicks(5000)},
101 .frame_functions = {
102 keyframe_enable,
103#if LCD_ENABLE
104 lcd_keyframe_draw_logo,
105#endif
106 keyframe_fade_in,
107 },
108};
109
110keyframe_animation_t default_suspend_animation = {
111#if LCD_ENABLE
112 .num_frames = 3,
113#else
114 .num_frames = 2,
115#endif
116 .loop = false,
117 .frame_lengths = {
118#if LCD_ENABLE
119 0,
120#endif
121 gfxMillisecondsToTicks(1000),
122 0},
123 .frame_functions = {
124#if LCD_ENABLE
125 lcd_keyframe_display_layer_text,
126#endif
127 keyframe_fade_out,
128 keyframe_disable,
129 },
130};
131#endif
132
133#if defined(BACKLIGHT_ENABLE)
134#define CROSSFADE_TIME 1000
135#define GRADIENT_TIME 3000
136
137keyframe_animation_t led_test_animation = {
138 .num_frames = 14,
139 .loop = true,
140 .frame_lengths = {
141 gfxMillisecondsToTicks(1000), // fade in
142 gfxMillisecondsToTicks(1000), // no op (leds on)
143 gfxMillisecondsToTicks(1000), // fade out
144 gfxMillisecondsToTicks(CROSSFADE_TIME), // crossfade
145 gfxMillisecondsToTicks(GRADIENT_TIME), // left to rigt (outside in)
146 gfxMillisecondsToTicks(CROSSFADE_TIME), // crossfade
147 gfxMillisecondsToTicks(GRADIENT_TIME), // top_to_bottom
148 0, // mirror leds
149 gfxMillisecondsToTicks(CROSSFADE_TIME), // crossfade
150 gfxMillisecondsToTicks(GRADIENT_TIME), // left_to_right (mirrored, so inside out)
151 gfxMillisecondsToTicks(CROSSFADE_TIME), // crossfade
152 gfxMillisecondsToTicks(GRADIENT_TIME), // top_to_bottom
153 0, // normal leds
154 gfxMillisecondsToTicks(CROSSFADE_TIME), // crossfade
155
156 },
157 .frame_functions = {
158 led_backlight_keyframe_fade_in_all,
159 keyframe_no_operation,
160 led_backlight_keyframe_fade_out_all,
161 led_backlight_keyframe_crossfade,
162 led_backlight_keyframe_left_to_right_gradient,
163 led_backlight_keyframe_crossfade,
164 led_backlight_keyframe_top_to_bottom_gradient,
165 led_backlight_keyframe_mirror_orientation,
166 led_backlight_keyframe_crossfade,
167 led_backlight_keyframe_left_to_right_gradient,
168 led_backlight_keyframe_crossfade,
169 led_backlight_keyframe_top_to_bottom_gradient,
170 led_backlight_keyframe_normal_orientation,
171 led_backlight_keyframe_crossfade,
172 },
173};
174#endif
175
176#endif
diff --git a/quantum/visualizer/lcd_backlight_keyframes.h b/quantum/visualizer/default_animations.h
index e1c125cf9..51320b8b8 100644
--- a/quantum/visualizer/lcd_backlight_keyframes.h
+++ b/quantum/visualizer/default_animations.h
@@ -14,17 +14,17 @@
14 * along with this program. If not, see <http://www.gnu.org/licenses/>. 14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */ 15 */
16 16
17#ifndef QUANTUM_VISUALIZER_LCD_BACKLIGHT_KEYFRAMES_H_ 17#ifndef DEFAULT_ANIMATIONS_H_
18#define QUANTUM_VISUALIZER_LCD_BACKLIGHT_KEYFRAMES_H_ 18#define DEFAULT_ANIMATIONS_H_
19 19
20#include "visualizer.h" 20#include "visualizer.h"
21 21
22// Animates the LCD backlight color between the current color and the target color (of the state) 22// You can use these default animations, but of course you can also write your own custom ones instead
23bool backlight_keyframe_animate_color(keyframe_animation_t* animation, visualizer_state_t* state); 23extern keyframe_animation_t default_startup_animation;
24// Sets the backlight color to the target color 24extern keyframe_animation_t default_suspend_animation;
25bool backlight_keyframe_set_color(keyframe_animation_t* animation, visualizer_state_t* state);
26 25
27bool backlight_keyframe_disable(keyframe_animation_t* animation, visualizer_state_t* state); 26// An animation for testing and demonstrating the led support, should probably not be used for real world
28bool backlight_keyframe_enable(keyframe_animation_t* animation, visualizer_state_t* state); 27// cases
28extern keyframe_animation_t led_test_animation;
29 29
30#endif /* QUANTUM_VISUALIZER_LCD_BACKLIGHT_KEYFRAMES_H_ */ 30#endif /* DEFAULT_ANIMATIONS_H_ */
diff --git a/quantum/visualizer/lcd_backlight_keyframes.c b/quantum/visualizer/lcd_backlight_keyframes.c
index 8436d4e3d..8c402baf6 100644
--- a/quantum/visualizer/lcd_backlight_keyframes.c
+++ b/quantum/visualizer/lcd_backlight_keyframes.c
@@ -16,7 +16,7 @@
16 16
17#include "lcd_backlight_keyframes.h" 17#include "lcd_backlight_keyframes.h"
18 18
19bool backlight_keyframe_animate_color(keyframe_animation_t* animation, visualizer_state_t* state) { 19bool lcd_backlight_keyframe_animate_color(keyframe_animation_t* animation, visualizer_state_t* state) {
20 int frame_length = animation->frame_lengths[animation->current_frame]; 20 int frame_length = animation->frame_lengths[animation->current_frame];
21 int current_pos = frame_length - animation->time_left_in_frame; 21 int current_pos = frame_length - animation->time_left_in_frame;
22 uint8_t t_h = LCD_HUE(state->target_lcd_color); 22 uint8_t t_h = LCD_HUE(state->target_lcd_color);
@@ -49,7 +49,7 @@ bool backlight_keyframe_animate_color(keyframe_animation_t* animation, visualize
49 return true; 49 return true;
50} 50}
51 51
52bool backlight_keyframe_set_color(keyframe_animation_t* animation, visualizer_state_t* state) { 52bool lcd_backlight_keyframe_set_color(keyframe_animation_t* animation, visualizer_state_t* state) {
53 (void)animation; 53 (void)animation;
54 state->prev_lcd_color = state->target_lcd_color; 54 state->prev_lcd_color = state->target_lcd_color;
55 state->current_lcd_color = state->target_lcd_color; 55 state->current_lcd_color = state->target_lcd_color;
@@ -60,14 +60,14 @@ bool backlight_keyframe_set_color(keyframe_animation_t* animation, visualizer_st
60 return false; 60 return false;
61} 61}
62 62
63bool backlight_keyframe_disable(keyframe_animation_t* animation, visualizer_state_t* state) { 63bool lcd_backlight_keyframe_disable(keyframe_animation_t* animation, visualizer_state_t* state) {
64 (void)animation; 64 (void)animation;
65 (void)state; 65 (void)state;
66 lcd_backlight_hal_color(0, 0, 0); 66 lcd_backlight_hal_color(0, 0, 0);
67 return false; 67 return false;
68} 68}
69 69
70bool backlight_keyframe_enable(keyframe_animation_t* animation, visualizer_state_t* state) { 70bool lcd_backlight_keyframe_enable(keyframe_animation_t* animation, visualizer_state_t* state) {
71 (void)animation; 71 (void)animation;
72 (void)state; 72 (void)state;
73 lcd_backlight_color(LCD_HUE(state->current_lcd_color), 73 lcd_backlight_color(LCD_HUE(state->current_lcd_color),
diff --git a/quantum/visualizer/lcd_keyframes.c b/quantum/visualizer/lcd_keyframes.c
index 82e4184d2..75eb45700 100644
--- a/quantum/visualizer/lcd_keyframes.c
+++ b/quantum/visualizer/lcd_keyframes.c
@@ -166,8 +166,8 @@ bool lcd_keyframe_draw_logo(keyframe_animation_t* animation, visualizer_state_t*
166 // or state structs, here we use the image 166 // or state structs, here we use the image
167 167
168 //gdispGBlitArea is a tricky function to use since it supports blitting part of the image 168 //gdispGBlitArea is a tricky function to use since it supports blitting part of the image
169 // if you have full screen image, then just use 128 and 32 for both source and target dimensions 169 // if you have full screen image, then just use LCD_WIDTH and LCD_HEIGHT for both source and target dimensions
170 gdispGBlitArea(GDISP, 0, 0, 128, 32, 0, 0, 128, (pixel_t*)resource_lcd_logo); 170 gdispGBlitArea(GDISP, 0, 0, LCD_WIDTH, LCD_HEIGHT, 0, 0, LCD_WIDTH, (pixel_t*)resource_lcd_logo);
171 171
172 return false; 172 return false;
173} 173}
diff --git a/quantum/visualizer/led_keyframes.c b/quantum/visualizer/led_backlight_keyframes.c
index 7e6e5d1ab..eb3f5561d 100644
--- a/quantum/visualizer/led_keyframes.c
+++ b/quantum/visualizer/led_backlight_keyframes.c
@@ -23,7 +23,7 @@ SOFTWARE.
23*/ 23*/
24#include "gfx.h" 24#include "gfx.h"
25#include "math.h" 25#include "math.h"
26#include "led_keyframes.h" 26#include "led_backlight_keyframes.h"
27 27
28static uint8_t fade_led_color(keyframe_animation_t* animation, int from, int to) { 28static uint8_t fade_led_color(keyframe_animation_t* animation, int from, int to) {
29 int frame_length = animation->frame_lengths[animation->current_frame]; 29 int frame_length = animation->frame_lengths[animation->current_frame];
@@ -41,8 +41,8 @@ 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 LED_NUM_ROWS 44#define NUM_ROWS LED_HEIGHT
45#define NUM_COLS LED_NUM_COLS 45#define NUM_COLS LED_WIDTH
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];
@@ -55,19 +55,19 @@ static uint8_t compute_gradient_color(float t, float index, float num) {
55 return (uint8_t)(255.0f * v); 55 return (uint8_t)(255.0f * v);
56} 56}
57 57
58bool led_keyframe_fade_in_all(keyframe_animation_t* animation, visualizer_state_t* state) { 58bool led_backlight_keyframe_fade_in_all(keyframe_animation_t* animation, visualizer_state_t* state) {
59 (void)state; 59 (void)state;
60 keyframe_fade_all_leds_from_to(animation, 0, 255); 60 keyframe_fade_all_leds_from_to(animation, 0, 255);
61 return true; 61 return true;
62} 62}
63 63
64bool led_keyframe_fade_out_all(keyframe_animation_t* animation, visualizer_state_t* state) { 64bool led_backlight_keyframe_fade_out_all(keyframe_animation_t* animation, visualizer_state_t* state) {
65 (void)state; 65 (void)state;
66 keyframe_fade_all_leds_from_to(animation, 255, 0); 66 keyframe_fade_all_leds_from_to(animation, 255, 0);
67 return true; 67 return true;
68} 68}
69 69
70bool led_keyframe_left_to_right_gradient(keyframe_animation_t* animation, visualizer_state_t* state) { 70bool led_backlight_keyframe_left_to_right_gradient(keyframe_animation_t* animation, visualizer_state_t* state) {
71 (void)state; 71 (void)state;
72 float frame_length = animation->frame_lengths[animation->current_frame]; 72 float frame_length = animation->frame_lengths[animation->current_frame];
73 float current_pos = frame_length - animation->time_left_in_frame; 73 float current_pos = frame_length - animation->time_left_in_frame;
@@ -79,7 +79,7 @@ bool led_keyframe_left_to_right_gradient(keyframe_animation_t* animation, visual
79 return true; 79 return true;
80} 80}
81 81
82bool led_keyframe_top_to_bottom_gradient(keyframe_animation_t* animation, visualizer_state_t* state) { 82bool led_backlight_keyframe_top_to_bottom_gradient(keyframe_animation_t* animation, visualizer_state_t* state) {
83 (void)state; 83 (void)state;
84 float frame_length = animation->frame_lengths[animation->current_frame]; 84 float frame_length = animation->frame_lengths[animation->current_frame];
85 float current_pos = frame_length - animation->time_left_in_frame; 85 float current_pos = frame_length - animation->time_left_in_frame;
@@ -98,7 +98,7 @@ static void copy_current_led_state(uint8_t* dest) {
98 } 98 }
99 } 99 }
100} 100}
101bool led_keyframe_crossfade(keyframe_animation_t* animation, visualizer_state_t* state) { 101bool led_backlight_keyframe_crossfade(keyframe_animation_t* animation, visualizer_state_t* state) {
102 (void)state; 102 (void)state;
103 if (animation->first_update_of_frame) { 103 if (animation->first_update_of_frame) {
104 copy_current_led_state(&crossfade_start_frame[0][0]); 104 copy_current_led_state(&crossfade_start_frame[0][0]);
@@ -114,28 +114,28 @@ bool led_keyframe_crossfade(keyframe_animation_t* animation, visualizer_state_t*
114 return true; 114 return true;
115} 115}
116 116
117bool led_keyframe_mirror_orientation(keyframe_animation_t* animation, visualizer_state_t* state) { 117bool led_backlight_keyframe_mirror_orientation(keyframe_animation_t* animation, visualizer_state_t* state) {
118 (void)state; 118 (void)state;
119 (void)animation; 119 (void)animation;
120 gdispGSetOrientation(LED_DISPLAY, GDISP_ROTATE_180); 120 gdispGSetOrientation(LED_DISPLAY, GDISP_ROTATE_180);
121 return false; 121 return false;
122} 122}
123 123
124bool led_keyframe_normal_orientation(keyframe_animation_t* animation, visualizer_state_t* state) { 124bool led_backlight_keyframe_normal_orientation(keyframe_animation_t* animation, visualizer_state_t* state) {
125 (void)state; 125 (void)state;
126 (void)animation; 126 (void)animation;
127 gdispGSetOrientation(LED_DISPLAY, GDISP_ROTATE_0); 127 gdispGSetOrientation(LED_DISPLAY, GDISP_ROTATE_0);
128 return false; 128 return false;
129} 129}
130 130
131bool led_keyframe_disable(keyframe_animation_t* animation, visualizer_state_t* state) { 131bool led_backlight_keyframe_disable(keyframe_animation_t* animation, visualizer_state_t* state) {
132 (void)state; 132 (void)state;
133 (void)animation; 133 (void)animation;
134 gdispGSetPowerMode(LED_DISPLAY, powerOff); 134 gdispGSetPowerMode(LED_DISPLAY, powerOff);
135 return false; 135 return false;
136} 136}
137 137
138bool led_keyframe_enable(keyframe_animation_t* animation, visualizer_state_t* state) { 138bool led_backlight_keyframe_enable(keyframe_animation_t* animation, visualizer_state_t* state) {
139 (void)state; 139 (void)state;
140 (void)animation; 140 (void)animation;
141 gdispGSetPowerMode(LED_DISPLAY, powerOn); 141 gdispGSetPowerMode(LED_DISPLAY, powerOn);
diff --git a/quantum/visualizer/led_keyframes.h b/quantum/visualizer/led_backlight_keyframes.h
index a59a4f37d..487151013 100644
--- a/quantum/visualizer/led_keyframes.h
+++ b/quantum/visualizer/led_backlight_keyframes.h
@@ -22,21 +22,21 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22SOFTWARE. 22SOFTWARE.
23*/ 23*/
24 24
25#ifndef LED_KEYFRAMES_H 25#ifndef LED_BACKLIGHT_KEYFRAMES_H
26#define LED_KEYFRAMES_H 26#define LED_BACKLIGHT_KEYFRAMES_H
27 27
28#include "visualizer.h" 28#include "visualizer.h"
29 29
30bool led_keyframe_fade_in_all(keyframe_animation_t* animation, visualizer_state_t* state); 30bool led_backlight_keyframe_fade_in_all(keyframe_animation_t* animation, visualizer_state_t* state);
31bool led_keyframe_fade_out_all(keyframe_animation_t* animation, visualizer_state_t* state); 31bool led_backlight_keyframe_fade_out_all(keyframe_animation_t* animation, visualizer_state_t* state);
32bool led_keyframe_left_to_right_gradient(keyframe_animation_t* animation, visualizer_state_t* state); 32bool led_backlight_keyframe_left_to_right_gradient(keyframe_animation_t* animation, visualizer_state_t* state);
33bool led_keyframe_top_to_bottom_gradient(keyframe_animation_t* animation, visualizer_state_t* state); 33bool led_backlight_keyframe_top_to_bottom_gradient(keyframe_animation_t* animation, visualizer_state_t* state);
34bool led_keyframe_crossfade(keyframe_animation_t* animation, visualizer_state_t* state); 34bool led_backlight_keyframe_crossfade(keyframe_animation_t* animation, visualizer_state_t* state);
35bool led_keyframe_mirror_orientation(keyframe_animation_t* animation, visualizer_state_t* state); 35bool led_backlight_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_backlight_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); 38bool led_backlight_keyframe_disable(keyframe_animation_t* animation, visualizer_state_t* state);
39bool led_keyframe_enable(keyframe_animation_t* animation, visualizer_state_t* state); 39bool led_backlight_keyframe_enable(keyframe_animation_t* animation, visualizer_state_t* state);
40 40
41extern keyframe_animation_t led_test_animation; 41extern keyframe_animation_t led_test_animation;
42 42
diff --git a/quantum/visualizer/visualizer.c b/quantum/visualizer/visualizer.c
index cc99d1e3b..5b4d8d603 100644
--- a/quantum/visualizer/visualizer.c
+++ b/quantum/visualizer/visualizer.c
@@ -52,7 +52,8 @@ SOFTWARE.
52 52
53// Define this in config.h 53// Define this in config.h
54#ifndef VISUALIZER_THREAD_PRIORITY 54#ifndef VISUALIZER_THREAD_PRIORITY
55#define "Visualizer thread priority not defined" 55// The visualizer needs gfx thread priorities
56#define VISUALIZER_THREAD_PRIORITY (NORMAL_PRIORITY - 2)
56#endif 57#endif
57 58
58static visualizer_keyboard_status_t current_status = { 59static visualizer_keyboard_status_t current_status = {
@@ -255,6 +256,9 @@ static DECLARE_THREAD_FUNCTION(visualizerThread, arg) {
255 .mods = 0xFF, 256 .mods = 0xFF,
256 .leds = 0xFFFFFFFF, 257 .leds = 0xFFFFFFFF,
257 .suspended = false, 258 .suspended = false,
259 #ifdef BACKLIGHT_ENABLE
260 .backlight_level = 0,
261 #endif
258 #ifdef VISUALIZER_USER_DATA_SIZE 262 #ifdef VISUALIZER_USER_DATA_SIZE
259 .user_data = {0}, 263 .user_data = {0},
260 #endif 264 #endif
@@ -299,6 +303,7 @@ static DECLARE_THREAD_FUNCTION(visualizerThread, arg) {
299 else { 303 else {
300 gdispGSetPowerMode(LED_DISPLAY, powerOff); 304 gdispGSetPowerMode(LED_DISPLAY, powerOff);
301 } 305 }
306 state.status.backlight_level = current_status.backlight_level;
302 } 307 }
303 #endif 308 #endif
304 if (visualizer_enabled) { 309 if (visualizer_enabled) {
diff --git a/quantum/visualizer/visualizer.mk b/quantum/visualizer/visualizer.mk
index 0f7d8636c..671b63ea2 100644
--- a/quantum/visualizer/visualizer.mk
+++ b/quantum/visualizer/visualizer.mk
@@ -20,6 +20,30 @@
20# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21# SOFTWARE. 21# SOFTWARE.
22 22
23define ADD_DRIVER
24 $(1)_DRIVER:=$(strip $($(1)_DRIVER))
25 $(1)_WIDTH:=$(strip $($(1)_WIDTH))
26 $(1)_HEIGHT:=$(strip $($(1)_HEIGHT))
27 ifeq ($($(1)_DRIVER),)
28 $$(error $(1)_DRIVER is not defined)
29 endif
30 ifeq ($($(1)_WIDTH),)
31 $$(error $(1)_WIDTH is not defined)
32 endif
33 ifeq ($($(1)_HEIGHT),)
34 $$(error $(1)_HEIGHT is not defined)
35 endif
36 OPT_DEFS+=-D$(1)_WIDTH=$($(1)_WIDTH)
37 OPT_DEFS+=-D$(1)_HEIGHT=$($(1)_HEIGHT)
38 GFXDEFS+=-D$(1)_WIDTH=$($(1)_WIDTH)
39 GFXDEFS+=-D$(1)_HEIGHT=$($(1)_HEIGHT)
40 $(1)_DISPLAY_NUMBER:=$$(words $$(GDISP_DRIVER_LIST))
41 OPT_DEFS+=-D$(1)_DISPLAY_NUMBER=$$($(1)_DISPLAY_NUMBER)
42 include $(TOP_DIR)/drivers/ugfx/gdisp/$($(1)_DRIVER)/driver.mk
43endef
44
45GDISP_DRIVER_LIST:=
46
23SRC += $(VISUALIZER_DIR)/visualizer.c \ 47SRC += $(VISUALIZER_DIR)/visualizer.c \
24 $(VISUALIZER_DIR)/visualizer_keyframes.c 48 $(VISUALIZER_DIR)/visualizer_keyframes.c
25EXTRAINCDIRS += $(GFXINC) $(VISUALIZER_DIR) 49EXTRAINCDIRS += $(GFXINC) $(VISUALIZER_DIR)
@@ -40,18 +64,34 @@ SRC += $(VISUALIZER_DIR)/lcd_backlight_keyframes.c
40# Note, that the linker will strip out any resources that are not actually in use 64# Note, that the linker will strip out any resources that are not actually in use
41SRC += $(VISUALIZER_DIR)/resources/lcd_logo.c 65SRC += $(VISUALIZER_DIR)/resources/lcd_logo.c
42OPT_DEFS += -DLCD_BACKLIGHT_ENABLE 66OPT_DEFS += -DLCD_BACKLIGHT_ENABLE
67$(eval $(call ADD_DRIVER,LCD))
43endif 68endif
44 69
45ifeq ($(strip $(BACKLIGHT_ENABLE)), yes) 70ifeq ($(strip $(BACKLIGHT_ENABLE)), yes)
46SRC += $(VISUALIZER_DIR)/led_keyframes.c 71SRC += $(VISUALIZER_DIR)/led_backlight_keyframes.c
72$(eval $(call ADD_DRIVER,LED))
47endif 73endif
48 74
75SRC += $(VISUALIZER_DIR)/default_animations.c
76
49include $(GFXLIB)/gfx.mk 77include $(GFXLIB)/gfx.mk
78# For the common_gfxconf.h
79GFXINC += quantum/visualizer
80
50GFXSRC := $(patsubst $(TOP_DIR)/%,%,$(GFXSRC)) 81GFXSRC := $(patsubst $(TOP_DIR)/%,%,$(GFXSRC))
51GFXDEFS := $(patsubst %,-D%,$(patsubst -D%,%,$(GFXDEFS))) 82GFXDEFS := $(patsubst %,-D%,$(patsubst -D%,%,$(GFXDEFS)))
52 83
84GDISP_LIST_COMMA=,
85GDISP_LIST_EMPTY=
86GDISP_LIST_SPACE=$(GDISP_LIST_EMPTY) $(GDISP_LIST_EMPTY)
87
88GDISP_DRIVER_LIST := $(strip $(GDISP_DRIVER_LIST))
89GDISP_DRIVER_LIST := $(subst $(GDISP_LIST_SPACE),$(GDISP_LIST_COMMA),$(GDISP_DRIVER_LIST))
90
91GFXDEFS +=-DGDISP_DRIVER_LIST="$(GDISP_DRIVER_LIST)"
92
53ifneq ("$(wildcard $(KEYMAP_PATH)/visualizer.c)","") 93ifneq ("$(wildcard $(KEYMAP_PATH)/visualizer.c)","")
54 SRC += keyboards/$(KEYBOARD)/keymaps/$(KEYMAP)/visualizer.c 94 SRC += $(KEYMAP_PATH)/visualizer.c
55else 95else
56 ifeq ("$(wildcard $(SUBPROJECT_PATH)/keymaps/$(KEYMAP)/visualizer.c)","") 96 ifeq ("$(wildcard $(SUBPROJECT_PATH)/keymaps/$(KEYMAP)/visualizer.c)","")
57 ifeq ("$(wildcard $(SUBPROJECT_PATH)/visualizer.c)","") 97 ifeq ("$(wildcard $(SUBPROJECT_PATH)/visualizer.c)","")