aboutsummaryrefslogtreecommitdiff
path: root/quantum
diff options
context:
space:
mode:
authorZay950 <Zay950@users.noreply.github.com>2017-03-29 12:00:38 -0700
committerGitHub <noreply@github.com>2017-03-29 12:00:38 -0700
commit2366ebfbbdeb6ec29cc9a0facda44d666305dd6e (patch)
tree883efed0b7260f3143f5a2a879bc3844a8255e0b /quantum
parent80c5ada3394c5ad8087df00ef878eb2cbcd87d70 (diff)
parent942f2ccee44bdb2e251553e9730cd8d59307d8b2 (diff)
downloadqmk_firmware-2366ebfbbdeb6ec29cc9a0facda44d666305dd6e.tar.gz
qmk_firmware-2366ebfbbdeb6ec29cc9a0facda44d666305dd6e.zip
Merge branch 'master' into to_push
Diffstat (limited to 'quantum')
-rw-r--r--quantum/analog.c16
-rw-r--r--quantum/analog.h16
-rw-r--r--quantum/api.c195
-rw-r--r--quantum/api.h75
-rw-r--r--quantum/api/api_sysex.c72
-rw-r--r--quantum/api/api_sysex.h26
-rw-r--r--quantum/audio/audio.c334
-rw-r--r--quantum/audio/audio.h17
-rw-r--r--quantum/audio/audio_pwm.c15
-rw-r--r--quantum/audio/luts.c16
-rw-r--r--quantum/audio/luts.h18
-rw-r--r--quantum/audio/musical_notes.h18
-rw-r--r--quantum/audio/song_list.h42
-rw-r--r--quantum/audio/voices.c137
-rw-r--r--quantum/audio/voices.h21
-rw-r--r--quantum/audio/wave.h18
-rw-r--r--quantum/config_common.h169
-rw-r--r--quantum/dynamic_macro.h16
-rw-r--r--quantum/fauxclicky.c68
-rw-r--r--quantum/fauxclicky.h99
-rw-r--r--quantum/keycode_config.c18
-rw-r--r--quantum/keycode_config.h16
-rw-r--r--quantum/keymap.h311
-rw-r--r--quantum/keymap_common.c28
-rw-r--r--quantum/keymap_extras/keymap_bepo.h15
-rw-r--r--quantum/keymap_extras/keymap_br_abnt2.h74
-rw-r--r--quantum/keymap_extras/keymap_canadian_multilingual.h15
-rw-r--r--quantum/keymap_extras/keymap_colemak.h15
-rw-r--r--quantum/keymap_extras/keymap_dvorak.h15
-rw-r--r--quantum/keymap_extras/keymap_dvp.h16
-rw-r--r--quantum/keymap_extras/keymap_fr_ch.h15
-rw-r--r--quantum/keymap_extras/keymap_french.h19
-rw-r--r--quantum/keymap_extras/keymap_french_osx.h17
-rw-r--r--quantum/keymap_extras/keymap_german.h16
-rw-r--r--quantum/keymap_extras/keymap_german_ch.h15
-rw-r--r--quantum/keymap_extras/keymap_german_osx.h15
-rw-r--r--quantum/keymap_extras/keymap_jp.h77
-rw-r--r--quantum/keymap_extras/keymap_neo2.h15
-rw-r--r--quantum/keymap_extras/keymap_nordic.h17
-rw-r--r--quantum/keymap_extras/keymap_norwegian.h15
-rw-r--r--quantum/keymap_extras/keymap_plover.h15
-rw-r--r--quantum/keymap_extras/keymap_russian.h77
-rw-r--r--quantum/keymap_extras/keymap_spanish.h15
-rw-r--r--quantum/keymap_extras/keymap_uk.h15
-rw-r--r--quantum/keymap_extras/keymap_unicode_cyrillic.h163
-rwxr-xr-xquantum/light_ws2812.c164
-rwxr-xr-xquantum/light_ws2812.h28
-rw-r--r--quantum/matrix.c331
-rw-r--r--quantum/pincontrol.h52
-rw-r--r--quantum/process_keycode/process_audio.c62
-rw-r--r--quantum/process_keycode/process_audio.h11
-rw-r--r--quantum/process_keycode/process_chording.c18
-rw-r--r--quantum/process_keycode/process_chording.h18
-rw-r--r--quantum/process_keycode/process_combo.c150
-rw-r--r--quantum/process_keycode/process_combo.h59
-rw-r--r--quantum/process_keycode/process_leader.c18
-rw-r--r--quantum/process_keycode/process_leader.h18
-rw-r--r--quantum/process_keycode/process_midi.c307
-rw-r--r--quantum/process_keycode/process_midi.h243
-rw-r--r--quantum/process_keycode/process_music.c141
-rw-r--r--quantum/process_keycode/process_music.h24
-rw-r--r--quantum/process_keycode/process_printer.c270
-rw-r--r--quantum/process_keycode/process_printer.h24
-rw-r--r--quantum/process_keycode/process_printer_bb.c276
-rw-r--r--quantum/process_keycode/process_tap_dance.c22
-rw-r--r--quantum/process_keycode/process_tap_dance.h16
-rw-r--r--quantum/process_keycode/process_ucis.c149
-rw-r--r--quantum/process_keycode/process_ucis.h51
-rw-r--r--quantum/process_keycode/process_unicode.c196
-rw-r--r--quantum/process_keycode/process_unicode.h174
-rw-r--r--quantum/process_keycode/process_unicode_common.c101
-rw-r--r--quantum/process_keycode/process_unicode_common.h148
-rw-r--r--quantum/process_keycode/process_unicodemap.c72
-rw-r--r--quantum/process_keycode/process_unicodemap.h25
-rw-r--r--quantum/quantum.c313
-rw-r--r--quantum/quantum.h47
-rw-r--r--quantum/quantum_keycodes.h600
-rw-r--r--quantum/rgblight.c211
-rw-r--r--quantum/rgblight.h44
-rw-r--r--quantum/serial_link/LICENSE2
-rw-r--r--quantum/template/Makefile17
-rw-r--r--quantum/template/config.h27
-rw-r--r--quantum/template/keymaps/default/Makefile22
-rw-r--r--quantum/template/keymaps/default/config.h18
-rw-r--r--quantum/template/keymaps/default/keymap.c17
-rw-r--r--quantum/template/rules.mk3
-rw-r--r--quantum/template/template.c15
-rw-r--r--quantum/template/template.h15
-rw-r--r--quantum/variable_trace.c16
-rw-r--r--quantum/variable_trace.h16
-rw-r--r--quantum/visualizer/visualizer.c58
-rw-r--r--quantum/visualizer/visualizer.h9
92 files changed, 5330 insertions, 1705 deletions
diff --git a/quantum/analog.c b/quantum/analog.c
index 49b84ee0e..1ec38df75 100644
--- a/quantum/analog.c
+++ b/quantum/analog.c
@@ -1,3 +1,19 @@
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
1// Simple analog to digitial conversion 17// Simple analog to digitial conversion
2 18
3#include <avr/io.h> 19#include <avr/io.h>
diff --git a/quantum/analog.h b/quantum/analog.h
index 9b95a93be..8d93de7dc 100644
--- a/quantum/analog.h
+++ b/quantum/analog.h
@@ -1,3 +1,19 @@
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
1#ifndef _analog_h_included__ 17#ifndef _analog_h_included__
2#define _analog_h_included__ 18#define _analog_h_included__
3 19
diff --git a/quantum/api.c b/quantum/api.c
new file mode 100644
index 000000000..52dfe23e1
--- /dev/null
+++ b/quantum/api.c
@@ -0,0 +1,195 @@
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
17#include "api.h"
18#include "quantum.h"
19
20void dword_to_bytes(uint32_t dword, uint8_t * bytes) {
21 bytes[0] = (dword >> 24) & 0xFF;
22 bytes[1] = (dword >> 16) & 0xFF;
23 bytes[2] = (dword >> 8) & 0xFF;
24 bytes[3] = (dword >> 0) & 0xFF;
25}
26
27uint32_t bytes_to_dword(uint8_t * bytes, uint8_t index) {
28 return ((uint32_t)bytes[index + 0] << 24) | ((uint32_t)bytes[index + 1] << 16) | ((uint32_t)bytes[index + 2] << 8) | (uint32_t)bytes[index + 3];
29}
30
31__attribute__ ((weak))
32bool process_api_quantum(uint8_t length, uint8_t * data) {
33 return process_api_keyboard(length, data);
34}
35
36__attribute__ ((weak))
37bool process_api_keyboard(uint8_t length, uint8_t * data) {
38 return process_api_user(length, data);
39}
40
41__attribute__ ((weak))
42bool process_api_user(uint8_t length, uint8_t * data) {
43 return true;
44}
45
46void process_api(uint16_t length, uint8_t * data) {
47 // SEND_STRING("\nRX: ");
48 // for (uint8_t i = 0; i < length; i++) {
49 // send_byte(data[i]);
50 // SEND_STRING(" ");
51 // }
52 if (!process_api_quantum(length, data))
53 return;
54
55 switch (data[0]) {
56 case MT_SET_DATA:
57 switch (data[1]) {
58 case DT_DEFAULT_LAYER: {
59 eeconfig_update_default_layer(data[2]);
60 default_layer_set((uint32_t)(data[2]));
61 break;
62 }
63 case DT_KEYMAP_OPTIONS: {
64 eeconfig_update_keymap(data[2]);
65 break;
66 }
67 case DT_RGBLIGHT: {
68 #ifdef RGBLIGHT_ENABLE
69 uint32_t rgblight = bytes_to_dword(data, 2);
70 rgblight_update_dword(rgblight);
71 #endif
72 break;
73 }
74 }
75 case MT_GET_DATA:
76 switch (data[1]) {
77 case DT_HANDSHAKE: {
78 MT_GET_DATA_ACK(DT_HANDSHAKE, NULL, 0);
79 break;
80 }
81 case DT_DEBUG: {
82 uint8_t debug_bytes[1] = { eeprom_read_byte(EECONFIG_DEBUG) };
83 MT_GET_DATA_ACK(DT_DEBUG, debug_bytes, 1);
84 break;
85 }
86 case DT_DEFAULT_LAYER: {
87 uint8_t default_bytes[1] = { eeprom_read_byte(EECONFIG_DEFAULT_LAYER) };
88 MT_GET_DATA_ACK(DT_DEFAULT_LAYER, default_bytes, 1);
89 break;
90 }
91 case DT_CURRENT_LAYER: {
92 uint8_t layer_state_bytes[4];
93 dword_to_bytes(layer_state, layer_state_bytes);
94 MT_GET_DATA_ACK(DT_CURRENT_LAYER, layer_state_bytes, 4);
95 break;
96 }
97 case DT_AUDIO: {
98 #ifdef AUDIO_ENABLE
99 uint8_t audio_bytes[1] = { eeprom_read_byte(EECONFIG_AUDIO) };
100 MT_GET_DATA_ACK(DT_AUDIO, audio_bytes, 1);
101 #else
102 MT_GET_DATA_ACK(DT_AUDIO, NULL, 0);
103 #endif
104 break;
105 }
106 case DT_BACKLIGHT: {
107 #ifdef BACKLIGHT_ENABLE
108 uint8_t backlight_bytes[1] = { eeprom_read_byte(EECONFIG_BACKLIGHT) };
109 MT_GET_DATA_ACK(DT_BACKLIGHT, backlight_bytes, 1);
110 #else
111 MT_GET_DATA_ACK(DT_BACKLIGHT, NULL, 0);
112 #endif
113 break;
114 }
115 case DT_RGBLIGHT: {
116 #ifdef RGBLIGHT_ENABLE
117 uint8_t rgblight_bytes[4];
118 dword_to_bytes(eeconfig_read_rgblight(), rgblight_bytes);
119 MT_GET_DATA_ACK(DT_RGBLIGHT, rgblight_bytes, 4);
120 #else
121 MT_GET_DATA_ACK(DT_RGBLIGHT, NULL, 0);
122 #endif
123 break;
124 }
125 case DT_KEYMAP_OPTIONS: {
126 uint8_t keymap_bytes[1] = { eeconfig_read_keymap() };
127 MT_GET_DATA_ACK(DT_KEYMAP_OPTIONS, keymap_bytes, 1);
128 break;
129 }
130 case DT_KEYMAP_SIZE: {
131 uint8_t keymap_size[2] = {MATRIX_ROWS, MATRIX_COLS};
132 MT_GET_DATA_ACK(DT_KEYMAP_SIZE, keymap_size, 2);
133 break;
134 }
135 // This may be too much
136 // case DT_KEYMAP: {
137 // uint8_t keymap_data[MATRIX_ROWS * MATRIX_COLS * 4 + 3];
138 // keymap_data[0] = data[2];
139 // keymap_data[1] = MATRIX_ROWS;
140 // keymap_data[2] = MATRIX_COLS;
141 // for (int i = 0; i < MATRIX_ROWS; i++) {
142 // for (int j = 0; j < MATRIX_COLS; j++) {
143 // keymap_data[3 + (i*MATRIX_COLS*2) + (j*2)] = pgm_read_word(&keymaps[data[2]][i][j]) >> 8;
144 // keymap_data[3 + (i*MATRIX_COLS*2) + (j*2) + 1] = pgm_read_word(&keymaps[data[2]][i][j]) & 0xFF;
145 // }
146 // }
147 // MT_GET_DATA_ACK(DT_KEYMAP, keymap_data, MATRIX_ROWS * MATRIX_COLS * 4 + 3);
148 // // uint8_t keymap_data[5];
149 // // keymap_data[0] = data[2];
150 // // keymap_data[1] = data[3];
151 // // keymap_data[2] = data[4];
152 // // keymap_data[3] = pgm_read_word(&keymaps[data[2]][data[3]][data[4]]) >> 8;
153 // // keymap_data[4] = pgm_read_word(&keymaps[data[2]][data[3]][data[4]]) & 0xFF;
154
155 // // MT_GET_DATA_ACK(DT_KEYMAP, keymap_data, 5);
156 // break;
157 // }
158 default:
159 break;
160 }
161 break;
162 case MT_SET_DATA_ACK:
163 case MT_GET_DATA_ACK:
164 break;
165 case MT_SEND_DATA:
166 break;
167 case MT_SEND_DATA_ACK:
168 break;
169 case MT_EXE_ACTION:
170 break;
171 case MT_EXE_ACTION_ACK:
172 break;
173 case MT_TYPE_ERROR:
174 break;
175 default: ; // command not recognised
176 SEND_BYTES(MT_TYPE_ERROR, DT_NONE, data, length);
177 break;
178
179 // #ifdef RGBLIGHT_ENABLE
180 // case 0x27: ; // RGB LED functions
181 // switch (*data++) {
182 // case 0x00: ; // Update HSV
183 // rgblight_sethsv((data[0] << 8 | data[1]) % 360, data[2], data[3]);
184 // break;
185 // case 0x01: ; // Update RGB
186 // break;
187 // case 0x02: ; // Update mode
188 // rgblight_mode(data[0]);
189 // break;
190 // }
191 // break;
192 // #endif
193 }
194
195}
diff --git a/quantum/api.h b/quantum/api.h
new file mode 100644
index 000000000..efc0ddca1
--- /dev/null
+++ b/quantum/api.h
@@ -0,0 +1,75 @@
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
17#ifndef _API_H_
18#define _API_H_
19
20#include "lufa.h"
21
22enum MESSAGE_TYPE {
23 MT_GET_DATA = 0x10, // Get data from keyboard
24 MT_GET_DATA_ACK = 0x11, // returned data to process (ACK)
25 MT_SET_DATA = 0x20, // Set data on keyboard
26 MT_SET_DATA_ACK = 0x21, // returned data to confirm (ACK)
27 MT_SEND_DATA = 0x30, // Sending data/action from keyboard
28 MT_SEND_DATA_ACK = 0x31, // returned data/action confirmation (ACK)
29 MT_EXE_ACTION = 0x40, // executing actions on keyboard
30 MT_EXE_ACTION_ACK =0x41, // return confirmation/value (ACK)
31 MT_TYPE_ERROR = 0x80 // type not recofgnised (ACK)
32};
33
34enum DATA_TYPE {
35 DT_NONE = 0x00,
36 DT_HANDSHAKE,
37 DT_DEFAULT_LAYER,
38 DT_CURRENT_LAYER,
39 DT_KEYMAP_OPTIONS,
40 DT_BACKLIGHT,
41 DT_RGBLIGHT,
42 DT_UNICODE,
43 DT_DEBUG,
44 DT_AUDIO,
45 DT_QUANTUM_ACTION,
46 DT_KEYBOARD_ACTION,
47 DT_USER_ACTION,
48 DT_KEYMAP_SIZE,
49 DT_KEYMAP
50};
51
52void dword_to_bytes(uint32_t dword, uint8_t * bytes);
53uint32_t bytes_to_dword(uint8_t * bytes, uint8_t index);
54
55#define MT_GET_DATA(data_type, data, length) SEND_BYTES(MT_GET_DATA, data_type, data, length)
56#define MT_GET_DATA_ACK(data_type, data, length) SEND_BYTES(MT_GET_DATA_ACK, data_type, data, length)
57#define MT_SET_DATA(data_type, data, length) SEND_BYTES(MT_SET_DATA, data_type, data, length)
58#define MT_SET_DATA_ACK(data_type, data, length) SEND_BYTES(MT_SET_DATA_ACK, data_type, data, length)
59#define MT_SEND_DATA(data_type, data, length) SEND_BYTES(MT_SEND_DATA, data_type, data, length)
60#define MT_SEND_DATA_ACK(data_type, data, length) SEND_BYTES(MT_SEND_DATA_ACK, data_type, data, length)
61#define MT_EXE_ACTION(data_type, data, length) SEND_BYTES(MT_EXE_ACTION, data_type, data, length)
62#define MT_EXE_ACTION_ACK(data_type, data, length) SEND_BYTES(MT_EXE_ACTION_ACK, data_type, data, length)
63
64void process_api(uint16_t length, uint8_t * data);
65
66__attribute__ ((weak))
67bool process_api_quantum(uint8_t length, uint8_t * data);
68
69__attribute__ ((weak))
70bool process_api_keyboard(uint8_t length, uint8_t * data);
71
72__attribute__ ((weak))
73bool process_api_user(uint8_t length, uint8_t * data);
74
75#endif
diff --git a/quantum/api/api_sysex.c b/quantum/api/api_sysex.c
new file mode 100644
index 000000000..6a2ee9012
--- /dev/null
+++ b/quantum/api/api_sysex.c
@@ -0,0 +1,72 @@
1/* Copyright 2016 Jack Humbert, 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#include "api_sysex.h"
17#include "sysex_tools.h"
18#include "print.h"
19
20void send_bytes_sysex(uint8_t message_type, uint8_t data_type, uint8_t * bytes, uint16_t length) {
21 // SEND_STRING("\nTX: ");
22 // for (uint8_t i = 0; i < length; i++) {
23 // send_byte(bytes[i]);
24 // SEND_STRING(" ");
25 // }
26 if (length > API_SYSEX_MAX_SIZE) {
27 xprintf("Sysex msg too big %d %d %d", message_type, data_type, length);
28 return;
29 }
30
31
32 // The buffer size required is calculated as the following
33 // API_SYSEX_MAX_SIZE is the maximum length
34 // In addition to that we have a two byte message header consisting of the message_type and data_type
35 // This has to be encoded with an additional overhead of one byte for every starting 7 bytes
36 // We just add one extra byte in case it's not divisible by 7
37 // Then we have an unencoded header consisting of 4 bytes
38 // Plus a one byte terminator
39 const unsigned message_header = 2;
40 const unsigned unencoded_message = API_SYSEX_MAX_SIZE + message_header;
41 const unsigned encoding_overhead = unencoded_message / 7 + 1;
42 const unsigned encoded_size = unencoded_message + encoding_overhead;
43 const unsigned unencoded_header = 4;
44 const unsigned terminator = 1;
45 const unsigned buffer_size = encoded_size + unencoded_header + terminator;
46 uint8_t buffer[encoded_size + unencoded_header + terminator];
47 // The unencoded header
48 buffer[0] = 0xF0;
49 buffer[1] = 0x00;
50 buffer[2] = 0x00;
51 buffer[3] = 0x00;
52
53 // We copy the message to the end of the array, this way we can do an inplace encoding, using the same
54 // buffer for both input and output
55 const unsigned message_size = length + message_header;
56 uint8_t* unencoded_start = buffer + buffer_size - message_size;
57 uint8_t* ptr = unencoded_start;
58 *(ptr++) = message_type;
59 *(ptr++) = data_type;
60 memcpy(ptr, bytes, length);
61
62 unsigned encoded_length = sysex_encode(buffer + unencoded_header, unencoded_start, message_size);
63 unsigned final_size = unencoded_header + encoded_length + terminator;
64 buffer[final_size - 1] = 0xF7;
65 midi_send_array(&midi_device, final_size, buffer);
66
67 // SEND_STRING("\nTD: ");
68 // for (uint8_t i = 0; i < encoded_length + 5; i++) {
69 // send_byte(buffer[i]);
70 // SEND_STRING(" ");
71 // }
72}
diff --git a/quantum/api/api_sysex.h b/quantum/api/api_sysex.h
new file mode 100644
index 000000000..a23f00f57
--- /dev/null
+++ b/quantum/api/api_sysex.h
@@ -0,0 +1,26 @@
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
17#ifndef _API_SYSEX_H_
18#define _API_SYSEX_H_
19
20#include "api.h"
21
22void send_bytes_sysex(uint8_t message_type, uint8_t data_type, uint8_t * bytes, uint16_t length);
23
24#define SEND_BYTES(mt, dt, b, l) send_bytes_sysex(mt, dt, b, l)
25
26#endif
diff --git a/quantum/audio/audio.c b/quantum/audio/audio.c
index ead5fbf3e..597073611 100644
--- a/quantum/audio/audio.c
+++ b/quantum/audio/audio.c
@@ -1,3 +1,18 @@
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 */
1#include <stdio.h> 16#include <stdio.h>
2#include <string.h> 17#include <string.h>
3//#include <math.h> 18//#include <math.h>
@@ -77,6 +92,7 @@ static bool audio_initialized = false;
77audio_config_t audio_config; 92audio_config_t audio_config;
78 93
79uint16_t envelope_index = 0; 94uint16_t envelope_index = 0;
95bool glissando = true;
80 96
81void audio_init() 97void audio_init()
82{ 98{
@@ -88,15 +104,15 @@ void audio_init()
88 } 104 }
89 audio_config.raw = eeconfig_read_audio(); 105 audio_config.raw = eeconfig_read_audio();
90 106
91 // Set port PC6 (OC3A and /OC4A) as output 107 // Set port PC6 (OC3A and /OC4A) as output
92 DDRC |= _BV(PORTC6); 108 DDRC |= _BV(PORTC6);
93 109
94 DISABLE_AUDIO_COUNTER_3_ISR; 110 DISABLE_AUDIO_COUNTER_3_ISR;
95 111
96 // TCCR3A / TCCR3B: Timer/Counter #3 Control Registers 112 // TCCR3A / TCCR3B: Timer/Counter #3 Control Registers
97 // Compare Output Mode (COM3An) = 0b00 = Normal port operation, OC3A disconnected from PC6 113 // Compare Output Mode (COM3An) = 0b00 = Normal port operation, OC3A disconnected from PC6
98 // Waveform Generation Mode (WGM3n) = 0b1110 = Fast PWM Mode 14 (Period = ICR3, Duty Cycle = OCR3A) 114 // Waveform Generation Mode (WGM3n) = 0b1110 = Fast PWM Mode 14 (Period = ICR3, Duty Cycle = OCR3A)
99 // Clock Select (CS3n) = 0b010 = Clock / 8 115 // Clock Select (CS3n) = 0b010 = Clock / 8
100 TCCR3A = (0 << COM3A1) | (0 << COM3A0) | (1 << WGM31) | (0 << WGM30); 116 TCCR3A = (0 << COM3A1) | (0 << COM3A0) | (1 << WGM31) | (0 << WGM30);
101 TCCR3B = (1 << WGM33) | (1 << WGM32) | (0 << CS32) | (1 << CS31) | (0 << CS30); 117 TCCR3B = (1 << WGM33) | (1 << WGM32) | (0 << CS32) | (1 << CS31) | (0 << CS30);
102 118
@@ -105,6 +121,8 @@ void audio_init()
105 121
106void stop_all_notes() 122void stop_all_notes()
107{ 123{
124 dprintf("audio stop all notes");
125
108 if (!audio_initialized) { 126 if (!audio_initialized) {
109 audio_init(); 127 audio_init();
110 } 128 }
@@ -127,6 +145,8 @@ void stop_all_notes()
127 145
128void stop_note(float freq) 146void stop_note(float freq)
129{ 147{
148 dprintf("audio stop note freq=%d", (int)freq);
149
130 if (playing_note) { 150 if (playing_note) {
131 if (!audio_initialized) { 151 if (!audio_initialized) {
132 audio_init(); 152 audio_init();
@@ -182,155 +202,161 @@ float vibrato(float average_freq) {
182 202
183ISR(TIMER3_COMPA_vect) 203ISR(TIMER3_COMPA_vect)
184{ 204{
185 float freq; 205 float freq;
186 206
187 if (playing_note) { 207 if (playing_note) {
188 if (voices > 0) { 208 if (voices > 0) {
189 if (polyphony_rate > 0) { 209 if (polyphony_rate > 0) {
190 if (voices > 1) { 210 if (voices > 1) {
191 voice_place %= voices; 211 voice_place %= voices;
192 if (place++ > (frequencies[voice_place] / polyphony_rate / CPU_PRESCALER)) { 212 if (place++ > (frequencies[voice_place] / polyphony_rate / CPU_PRESCALER)) {
193 voice_place = (voice_place + 1) % voices; 213 voice_place = (voice_place + 1) % voices;
194 place = 0.0; 214 place = 0.0;
195 } 215 }
196 } 216 }
197 217
198 #ifdef VIBRATO_ENABLE 218 #ifdef VIBRATO_ENABLE
199 if (vibrato_strength > 0) { 219 if (vibrato_strength > 0) {
200 freq = vibrato(frequencies[voice_place]); 220 freq = vibrato(frequencies[voice_place]);
201 } else { 221 } else {
202 freq = frequencies[voice_place]; 222 freq = frequencies[voice_place];
203 } 223 }
204 #else 224 #else
205 freq = frequencies[voice_place]; 225 freq = frequencies[voice_place];
206 #endif 226 #endif
207 } else { 227 } else {
208 if (frequency != 0 && frequency < frequencies[voices - 1] && frequency < frequencies[voices - 1] * pow(2, -440/frequencies[voices - 1]/12/2)) { 228 if (glissando) {
209 frequency = frequency * pow(2, 440/frequency/12/2); 229 if (frequency != 0 && frequency < frequencies[voices - 1] && frequency < frequencies[voices - 1] * pow(2, -440/frequencies[voices - 1]/12/2)) {
210 } else if (frequency != 0 && frequency > frequencies[voices - 1] && frequency > frequencies[voices - 1] * pow(2, 440/frequencies[voices - 1]/12/2)) { 230 frequency = frequency * pow(2, 440/frequency/12/2);
211 frequency = frequency * pow(2, -440/frequency/12/2); 231 } else if (frequency != 0 && frequency > frequencies[voices - 1] && frequency > frequencies[voices - 1] * pow(2, 440/frequencies[voices - 1]/12/2)) {
212 } else { 232 frequency = frequency * pow(2, -440/frequency/12/2);
213 frequency = frequencies[voices - 1]; 233 } else {
214 } 234 frequency = frequencies[voices - 1];
215 235 }
216 #ifdef VIBRATO_ENABLE 236 } else {
217 if (vibrato_strength > 0) { 237 frequency = frequencies[voices - 1];
218 freq = vibrato(frequency); 238 }
219 } else { 239
220 freq = frequency; 240 #ifdef VIBRATO_ENABLE
221 } 241 if (vibrato_strength > 0) {
222 #else 242 freq = vibrato(frequency);
223 freq = frequency; 243 } else {
224 #endif 244 freq = frequency;
225 } 245 }
226 246 #else
227 if (envelope_index < 65535) { 247 freq = frequency;
228 envelope_index++; 248 #endif
229 } 249 }
230 250
231 freq = voice_envelope(freq); 251 if (envelope_index < 65535) {
232 252 envelope_index++;
233 if (freq < 30.517578125) { 253 }
234 freq = 30.52; 254
235 } 255 freq = voice_envelope(freq);
236 256
237 TIMER_3_PERIOD = (uint16_t)(((float)F_CPU) / (freq * CPU_PRESCALER)); 257 if (freq < 30.517578125) {
238 TIMER_3_DUTY_CYCLE = (uint16_t)((((float)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre); 258 freq = 30.52;
239 } 259 }
240 } 260
241 261 TIMER_3_PERIOD = (uint16_t)(((float)F_CPU) / (freq * CPU_PRESCALER));
242 if (playing_notes) { 262 TIMER_3_DUTY_CYCLE = (uint16_t)((((float)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre);
243 if (note_frequency > 0) { 263 }
244 #ifdef VIBRATO_ENABLE 264 }
245 if (vibrato_strength > 0) { 265
246 freq = vibrato(note_frequency); 266 if (playing_notes) {
247 } else { 267 if (note_frequency > 0) {
248 freq = note_frequency; 268 #ifdef VIBRATO_ENABLE
249 } 269 if (vibrato_strength > 0) {
250 #else 270 freq = vibrato(note_frequency);
251 freq = note_frequency; 271 } else {
252 #endif 272 freq = note_frequency;
253 273 }
254 if (envelope_index < 65535) { 274 #else
255 envelope_index++; 275 freq = note_frequency;
256 } 276 #endif
257 freq = voice_envelope(freq); 277
258 278 if (envelope_index < 65535) {
259 TIMER_3_PERIOD = (uint16_t)(((float)F_CPU) / (freq * CPU_PRESCALER)); 279 envelope_index++;
260 TIMER_3_DUTY_CYCLE = (uint16_t)((((float)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre); 280 }
261 } else { 281 freq = voice_envelope(freq);
262 TIMER_3_PERIOD = 0; 282
263 TIMER_3_DUTY_CYCLE = 0; 283 TIMER_3_PERIOD = (uint16_t)(((float)F_CPU) / (freq * CPU_PRESCALER));
264 } 284 TIMER_3_DUTY_CYCLE = (uint16_t)((((float)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre);
265 285 } else {
266 note_position++; 286 TIMER_3_PERIOD = 0;
267 bool end_of_note = false; 287 TIMER_3_DUTY_CYCLE = 0;
268 if (TIMER_3_PERIOD > 0) { 288 }
269 end_of_note = (note_position >= (note_length / TIMER_3_PERIOD * 0xFFFF)); 289
270 } else { 290 note_position++;
271 end_of_note = (note_position >= (note_length * 0x7FF)); 291 bool end_of_note = false;
272 } 292 if (TIMER_3_PERIOD > 0) {
273 293 end_of_note = (note_position >= (note_length / TIMER_3_PERIOD * 0xFFFF));
274 if (end_of_note) { 294 } else {
275 current_note++; 295 end_of_note = (note_position >= (note_length * 0x7FF));
276 if (current_note >= notes_count) { 296 }
277 if (notes_repeat) { 297
278 current_note = 0; 298 if (end_of_note) {
279 } else { 299 current_note++;
280 DISABLE_AUDIO_COUNTER_3_ISR; 300 if (current_note >= notes_count) {
281 DISABLE_AUDIO_COUNTER_3_OUTPUT; 301 if (notes_repeat) {
282 playing_notes = false; 302 current_note = 0;
283 return; 303 } else {
284 } 304 DISABLE_AUDIO_COUNTER_3_ISR;
285 } 305 DISABLE_AUDIO_COUNTER_3_OUTPUT;
286 if (!note_resting && (notes_rest > 0)) { 306 playing_notes = false;
287 note_resting = true; 307 return;
288 note_frequency = 0; 308 }
289 note_length = notes_rest; 309 }
290 current_note--; 310 if (!note_resting && (notes_rest > 0)) {
291 } else { 311 note_resting = true;
292 note_resting = false; 312 note_frequency = 0;
293 envelope_index = 0; 313 note_length = notes_rest;
294 note_frequency = (*notes_pointer)[current_note][0]; 314 current_note--;
295 note_length = ((*notes_pointer)[current_note][1] / 4) * (((float)note_tempo) / 100); 315 } else {
296 } 316 note_resting = false;
297 317 envelope_index = 0;
298 note_position = 0; 318 note_frequency = (*notes_pointer)[current_note][0];
299 } 319 note_length = ((*notes_pointer)[current_note][1] / 4) * (((float)note_tempo) / 100);
300 } 320 }
301 321
302 if (!audio_config.enable) { 322 note_position = 0;
303 playing_notes = false; 323 }
304 playing_note = false; 324 }
305 } 325
326 if (!audio_config.enable) {
327 playing_notes = false;
328 playing_note = false;
329 }
306} 330}
307 331
308void play_note(float freq, int vol) { 332void play_note(float freq, int vol) {
309 333
334 dprintf("audio play note freq=%d vol=%d", (int)freq, vol);
335
310 if (!audio_initialized) { 336 if (!audio_initialized) {
311 audio_init(); 337 audio_init();
312 } 338 }
313 339
314 if (audio_config.enable && voices < 8) { 340 if (audio_config.enable && voices < 8) {
315 DISABLE_AUDIO_COUNTER_3_ISR; 341 DISABLE_AUDIO_COUNTER_3_ISR;
316 342
317 // Cancel notes if notes are playing 343 // Cancel notes if notes are playing
318 if (playing_notes) 344 if (playing_notes)
319 stop_all_notes(); 345 stop_all_notes();
320 346
321 playing_note = true; 347 playing_note = true;
322 348
323 envelope_index = 0; 349 envelope_index = 0;
324 350
325 if (freq > 0) { 351 if (freq > 0) {
326 frequencies[voices] = freq; 352 frequencies[voices] = freq;
327 volumes[voices] = vol; 353 volumes[voices] = vol;
328 voices++; 354 voices++;
329 } 355 }
330 356
331 ENABLE_AUDIO_COUNTER_3_ISR; 357 ENABLE_AUDIO_COUNTER_3_ISR;
332 ENABLE_AUDIO_COUNTER_3_OUTPUT; 358 ENABLE_AUDIO_COUNTER_3_OUTPUT;
333 } 359 }
334 360
335} 361}
336 362
@@ -341,37 +367,37 @@ void play_notes(float (*np)[][2], uint16_t n_count, bool n_repeat, float n_rest)
341 audio_init(); 367 audio_init();
342 } 368 }
343 369
344 if (audio_config.enable) { 370 if (audio_config.enable) {
345 371
346 DISABLE_AUDIO_COUNTER_3_ISR; 372 DISABLE_AUDIO_COUNTER_3_ISR;
347 373
348 // Cancel note if a note is playing 374 // Cancel note if a note is playing
349 if (playing_note) 375 if (playing_note)
350 stop_all_notes(); 376 stop_all_notes();
351 377
352 playing_notes = true; 378 playing_notes = true;
353 379
354 notes_pointer = np; 380 notes_pointer = np;
355 notes_count = n_count; 381 notes_count = n_count;
356 notes_repeat = n_repeat; 382 notes_repeat = n_repeat;
357 notes_rest = n_rest; 383 notes_rest = n_rest;
358 384
359 place = 0; 385 place = 0;
360 current_note = 0; 386 current_note = 0;
361 387
362 note_frequency = (*notes_pointer)[current_note][0]; 388 note_frequency = (*notes_pointer)[current_note][0];
363 note_length = ((*notes_pointer)[current_note][1] / 4) * (((float)note_tempo) / 100); 389 note_length = ((*notes_pointer)[current_note][1] / 4) * (((float)note_tempo) / 100);
364 note_position = 0; 390 note_position = 0;
365 391
366 392
367 ENABLE_AUDIO_COUNTER_3_ISR; 393 ENABLE_AUDIO_COUNTER_3_ISR;
368 ENABLE_AUDIO_COUNTER_3_OUTPUT; 394 ENABLE_AUDIO_COUNTER_3_OUTPUT;
369 } 395 }
370 396
371} 397}
372 398
373bool is_playing_notes(void) { 399bool is_playing_notes(void) {
374 return playing_notes; 400 return playing_notes;
375} 401}
376 402
377bool is_audio_on(void) { 403bool is_audio_on(void) {
diff --git a/quantum/audio/audio.h b/quantum/audio/audio.h
index 47f326ea0..27fdc2ab6 100644
--- a/quantum/audio/audio.h
+++ b/quantum/audio/audio.h
@@ -1,3 +1,18 @@
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 */
1#ifndef AUDIO_H 16#ifndef AUDIO_H
2#define AUDIO_H 17#define AUDIO_H
3 18
@@ -88,4 +103,4 @@ void play_notes(float (*np)[][2], uint16_t n_count, bool n_repeat, float n_rest)
88 103
89bool is_playing_notes(void); 104bool is_playing_notes(void);
90 105
91#endif \ No newline at end of file 106#endif
diff --git a/quantum/audio/audio_pwm.c b/quantum/audio/audio_pwm.c
index f820eec1b..ded86edee 100644
--- a/quantum/audio/audio_pwm.c
+++ b/quantum/audio/audio_pwm.c
@@ -1,3 +1,18 @@
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 */
1#include <stdio.h> 16#include <stdio.h>
2#include <string.h> 17#include <string.h>
3//#include <math.h> 18//#include <math.h>
diff --git a/quantum/audio/luts.c b/quantum/audio/luts.c
index 9f3de9a05..57f2d5924 100644
--- a/quantum/audio/luts.c
+++ b/quantum/audio/luts.c
@@ -1,3 +1,19 @@
1/* Copyright 2016 IBNobody
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
1#include <avr/io.h> 17#include <avr/io.h>
2#include <avr/interrupt.h> 18#include <avr/interrupt.h>
3#include <avr/pgmspace.h> 19#include <avr/pgmspace.h>
diff --git a/quantum/audio/luts.h b/quantum/audio/luts.h
index 7df3078a7..155e34e88 100644
--- a/quantum/audio/luts.h
+++ b/quantum/audio/luts.h
@@ -1,3 +1,19 @@
1/* Copyright 2016 IBNobody
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
1#include <avr/io.h> 17#include <avr/io.h>
2#include <avr/interrupt.h> 18#include <avr/interrupt.h>
3#include <avr/pgmspace.h> 19#include <avr/pgmspace.h>
@@ -12,4 +28,4 @@
12extern const float vibrato_lut[VIBRATO_LUT_LENGTH]; 28extern const float vibrato_lut[VIBRATO_LUT_LENGTH];
13extern const uint16_t frequency_lut[FREQUENCY_LUT_LENGTH]; 29extern const uint16_t frequency_lut[FREQUENCY_LUT_LENGTH];
14 30
15#endif /* LUTS_H */ \ No newline at end of file 31#endif /* LUTS_H */
diff --git a/quantum/audio/musical_notes.h b/quantum/audio/musical_notes.h
index b08d16a6f..a3aaa2f19 100644
--- a/quantum/audio/musical_notes.h
+++ b/quantum/audio/musical_notes.h
@@ -1,3 +1,19 @@
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
1#ifndef MUSICAL_NOTES_H 17#ifndef MUSICAL_NOTES_H
2#define MUSICAL_NOTES_H 18#define MUSICAL_NOTES_H
3 19
@@ -214,4 +230,4 @@
214#define NOTE_BF8 NOTE_AS8 230#define NOTE_BF8 NOTE_AS8
215 231
216 232
217#endif \ No newline at end of file 233#endif
diff --git a/quantum/audio/song_list.h b/quantum/audio/song_list.h
index 623f24f32..db2d1a94c 100644
--- a/quantum/audio/song_list.h
+++ b/quantum/audio/song_list.h
@@ -1,3 +1,18 @@
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 */
1#include "musical_notes.h" 16#include "musical_notes.h"
2 17
3#ifndef SONG_LIST_H 18#ifndef SONG_LIST_H
@@ -134,4 +149,31 @@
134 E__NOTE(_E6), \ 149 E__NOTE(_E6), \
135 S__NOTE(_B5), 150 S__NOTE(_B5),
136 151
152#define COIN_SOUND \
153 E__NOTE(_A5 ), \
154 HD_NOTE(_E6 ),
155
156#define ONE_UP_SOUND \
157 Q__NOTE(_E6 ), \
158 Q__NOTE(_G6 ), \
159 Q__NOTE(_E7 ), \
160 Q__NOTE(_C7 ), \
161 Q__NOTE(_D7 ), \
162 Q__NOTE(_G7 ),
163
164#define SONIC_RING \
165 E__NOTE(_E6), \
166 E__NOTE(_G6), \
167 HD_NOTE(_C7),
168
169#define ZELDA_PUZZLE \
170 Q__NOTE(_G5), \
171 Q__NOTE(_FS5), \
172 Q__NOTE(_DS5), \
173 Q__NOTE(_A4), \
174 Q__NOTE(_GS4), \
175 Q__NOTE(_E5), \
176 Q__NOTE(_GS5), \
177 HD_NOTE(_C6),
178
137#endif 179#endif
diff --git a/quantum/audio/voices.c b/quantum/audio/voices.c
index 6d4172a06..54ebd423b 100644
--- a/quantum/audio/voices.c
+++ b/quantum/audio/voices.c
@@ -1,3 +1,18 @@
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 */
1#include "voices.h" 16#include "voices.h"
2#include "audio.h" 17#include "audio.h"
3#include "stdlib.h" 18#include "stdlib.h"
@@ -6,6 +21,7 @@
6extern uint16_t envelope_index; 21extern uint16_t envelope_index;
7extern float note_timbre; 22extern float note_timbre;
8extern float polyphony_rate; 23extern float polyphony_rate;
24extern bool glissando;
9 25
10voice_type voice = default_voice; 26voice_type voice = default_voice;
11 27
@@ -18,20 +34,132 @@ void voice_iterate() {
18} 34}
19 35
20void voice_deiterate() { 36void voice_deiterate() {
21 voice = (voice - 1) % number_of_voices; 37 voice = (voice - 1 + number_of_voices) % number_of_voices;
22} 38}
23 39
24float voice_envelope(float frequency) { 40float voice_envelope(float frequency) {
25 // envelope_index ranges from 0 to 0xFFFF, which is preserved at 880.0 Hz 41 // envelope_index ranges from 0 to 0xFFFF, which is preserved at 880.0 Hz
42 __attribute__ ((unused))
26 uint16_t compensated_index = (uint16_t)((float)envelope_index * (880.0 / frequency)); 43 uint16_t compensated_index = (uint16_t)((float)envelope_index * (880.0 / frequency));
27 44
28 switch (voice) { 45 switch (voice) {
29 case default_voice: 46 case default_voice:
47 glissando = true;
30 note_timbre = TIMBRE_50; 48 note_timbre = TIMBRE_50;
31 polyphony_rate = 0; 49 polyphony_rate = 0;
32 break; 50 break;
33 51
52 #ifdef AUDIO_VOICES
53
54 case something:
55 glissando = false;
56 polyphony_rate = 0;
57 switch (compensated_index) {
58 case 0 ... 9:
59 note_timbre = TIMBRE_12;
60 break;
61
62 case 10 ... 19:
63 note_timbre = TIMBRE_25;
64 break;
65
66 case 20 ... 200:
67 note_timbre = .125 + .125;
68 break;
69
70 default:
71 note_timbre = .125;
72 break;
73 }
74 break;
75
76 case drums:
77 glissando = false;
78 polyphony_rate = 0;
79 // switch (compensated_index) {
80 // case 0 ... 10:
81 // note_timbre = 0.5;
82 // break;
83 // case 11 ... 20:
84 // note_timbre = 0.5 * (21 - compensated_index) / 10;
85 // break;
86 // default:
87 // note_timbre = 0;
88 // break;
89 // }
90 // frequency = (rand() % (int)(frequency * 1.2 - frequency)) + (frequency * 0.8);
91
92 if (frequency < 80.0) {
93
94 } else if (frequency < 160.0) {
95
96 // Bass drum: 60 - 100 Hz
97 frequency = (rand() % (int)(40)) + 60;
98 switch (envelope_index) {
99 case 0 ... 10:
100 note_timbre = 0.5;
101 break;
102 case 11 ... 20:
103 note_timbre = 0.5 * (21 - envelope_index) / 10;
104 break;
105 default:
106 note_timbre = 0;
107 break;
108 }
109
110 } else if (frequency < 320.0) {
111
112
113 // Snare drum: 1 - 2 KHz
114 frequency = (rand() % (int)(1000)) + 1000;
115 switch (envelope_index) {
116 case 0 ... 5:
117 note_timbre = 0.5;
118 break;
119 case 6 ... 20:
120 note_timbre = 0.5 * (21 - envelope_index) / 15;
121 break;
122 default:
123 note_timbre = 0;
124 break;
125 }
126
127 } else if (frequency < 640.0) {
128
129 // Closed Hi-hat: 3 - 5 KHz
130 frequency = (rand() % (int)(2000)) + 3000;
131 switch (envelope_index) {
132 case 0 ... 15:
133 note_timbre = 0.5;
134 break;
135 case 16 ... 20:
136 note_timbre = 0.5 * (21 - envelope_index) / 5;
137 break;
138 default:
139 note_timbre = 0;
140 break;
141 }
142
143 } else if (frequency < 1280.0) {
144
145 // Open Hi-hat: 3 - 5 KHz
146 frequency = (rand() % (int)(2000)) + 3000;
147 switch (envelope_index) {
148 case 0 ... 35:
149 note_timbre = 0.5;
150 break;
151 case 36 ... 50:
152 note_timbre = 0.5 * (51 - envelope_index) / 15;
153 break;
154 default:
155 note_timbre = 0;
156 break;
157 }
158
159 }
160 break;
34 case butts_fader: 161 case butts_fader:
162 glissando = true;
35 polyphony_rate = 0; 163 polyphony_rate = 0;
36 switch (compensated_index) { 164 switch (compensated_index) {
37 case 0 ... 9: 165 case 0 ... 9:
@@ -79,6 +207,7 @@ float voice_envelope(float frequency) {
79 207
80 case duty_osc: 208 case duty_osc:
81 // This slows the loop down a substantial amount, so higher notes may freeze 209 // This slows the loop down a substantial amount, so higher notes may freeze
210 glissando = true;
82 polyphony_rate = 0; 211 polyphony_rate = 0;
83 switch (compensated_index) { 212 switch (compensated_index) {
84 default: 213 default:
@@ -93,6 +222,7 @@ float voice_envelope(float frequency) {
93 break; 222 break;
94 223
95 case duty_octave_down: 224 case duty_octave_down:
225 glissando = true;
96 polyphony_rate = 0; 226 polyphony_rate = 0;
97 note_timbre = (envelope_index % 2) * .125 + .375 * 2; 227 note_timbre = (envelope_index % 2) * .125 + .375 * 2;
98 if ((envelope_index % 4) == 0) 228 if ((envelope_index % 4) == 0)
@@ -101,6 +231,7 @@ float voice_envelope(float frequency) {
101 note_timbre = 0; 231 note_timbre = 0;
102 break; 232 break;
103 case delayed_vibrato: 233 case delayed_vibrato:
234 glissando = true;
104 polyphony_rate = 0; 235 polyphony_rate = 0;
105 note_timbre = TIMBRE_50; 236 note_timbre = TIMBRE_50;
106 #define VOICE_VIBRATO_DELAY 150 237 #define VOICE_VIBRATO_DELAY 150
@@ -155,11 +286,11 @@ float voice_envelope(float frequency) {
155 // note_timbre = 0.25; 286 // note_timbre = 0.25;
156 // break; 287 // break;
157 288
289 #endif
290
158 default: 291 default:
159 break; 292 break;
160 } 293 }
161 294
162 return frequency; 295 return frequency;
163} 296}
164
165
diff --git a/quantum/audio/voices.h b/quantum/audio/voices.h
index b2495b23b..9403a6b5e 100644
--- a/quantum/audio/voices.h
+++ b/quantum/audio/voices.h
@@ -1,3 +1,18 @@
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 */
1#include <stdint.h> 16#include <stdint.h>
2#include <stdbool.h> 17#include <stdbool.h>
3#include <avr/io.h> 18#include <avr/io.h>
@@ -11,6 +26,9 @@ float voice_envelope(float frequency);
11 26
12typedef enum { 27typedef enum {
13 default_voice, 28 default_voice,
29 #ifdef AUDIO_VOICES
30 something,
31 drums,
14 butts_fader, 32 butts_fader,
15 octave_crunch, 33 octave_crunch,
16 duty_osc, 34 duty_osc,
@@ -21,6 +39,7 @@ typedef enum {
21 // duty_fourth_down, 39 // duty_fourth_down,
22 // duty_third_down, 40 // duty_third_down,
23 // duty_fifth_third_down, 41 // duty_fifth_third_down,
42 #endif
24 number_of_voices // important that this is last 43 number_of_voices // important that this is last
25} voice_type; 44} voice_type;
26 45
@@ -28,4 +47,4 @@ void set_voice(voice_type v);
28void voice_iterate(void); 47void voice_iterate(void);
29void voice_deiterate(void); 48void voice_deiterate(void);
30 49
31#endif \ No newline at end of file 50#endif
diff --git a/quantum/audio/wave.h b/quantum/audio/wave.h
index 6ebc34851..f15615dd1 100644
--- a/quantum/audio/wave.h
+++ b/quantum/audio/wave.h
@@ -1,3 +1,19 @@
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
1#include <avr/io.h> 17#include <avr/io.h>
2#include <avr/interrupt.h> 18#include <avr/interrupt.h>
3#include <avr/pgmspace.h> 19#include <avr/pgmspace.h>
@@ -262,4 +278,4 @@ const uint8_t sinewave[] PROGMEM= //2048 values
2620x76,0x77,0x77,0x77,0x78,0x78,0x78,0x79, 2780x76,0x77,0x77,0x77,0x78,0x78,0x78,0x79,
2630x79,0x7a,0x7a,0x7a,0x7b,0x7b,0x7c,0x7c, 2790x79,0x7a,0x7a,0x7a,0x7b,0x7b,0x7c,0x7c,
2640x7c,0x7d,0x7d,0x7e,0x7e,0x7e,0x7f,0x7f 2800x7c,0x7d,0x7d,0x7e,0x7e,0x7e,0x7f,0x7f
265}; \ No newline at end of file 281};
diff --git a/quantum/config_common.h b/quantum/config_common.h
index 8ed5f4a10..c88e02d91 100644
--- a/quantum/config_common.h
+++ b/quantum/config_common.h
@@ -1,59 +1,78 @@
1/* Copyright 2015-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
1#ifndef CONFIG_DEFINITIONS_H 17#ifndef CONFIG_DEFINITIONS_H
2#define CONFIG_DEFINITIONS_H 18#define CONFIG_DEFINITIONS_H
3 19
4/* diode directions */ 20/* diode directions */
5#define COL2ROW 0 21#define COL2ROW 0
6#define ROW2COL 1 22#define ROW2COL 1
7/* I/O pins */ 23#define CUSTOM_MATRIX 2 /* Disables built-in matrix scanning code */
8#define B0 0x30
9#define B1 0x31
10#define B2 0x32
11#define B3 0x33
12#define B4 0x34
13#define B5 0x35
14#define B6 0x36
15#define B7 0x37
16#define C0 0x60
17#define C1 0x61
18#define C2 0x62
19#define C3 0x63
20#define C4 0x64
21#define C5 0x65
22#define C6 0x66
23#define C7 0x67
24#define D0 0x90
25#define D1 0x91
26#define D2 0x92
27#define D3 0x93
28#define D4 0x94
29#define D5 0x95
30#define D6 0x96
31#define D7 0x97
32#define E0 0xC0
33#define E1 0xC1
34#define E2 0xC2
35#define E3 0xC3
36#define E4 0xC4
37#define E5 0xC5
38#define E6 0xC6
39#define E7 0xC7
40#define F0 0xF0
41#define F1 0xF1
42#define F2 0xF2
43#define F3 0xF3
44#define F4 0xF4
45#define F5 0xF5
46#define F6 0xF6
47#define F7 0xF7
48#define A0 0x00
49#define A1 0x01
50#define A2 0x02
51#define A3 0x03
52#define A4 0x04
53#define A5 0x05
54#define A6 0x06
55#define A7 0x07
56 24
25/* I/O pins */
26#ifndef F0
27 #define B0 0x30
28 #define B1 0x31
29 #define B2 0x32
30 #define B3 0x33
31 #define B4 0x34
32 #define B5 0x35
33 #define B6 0x36
34 #define B7 0x37
35 #define C0 0x60
36 #define C1 0x61
37 #define C2 0x62
38 #define C3 0x63
39 #define C4 0x64
40 #define C5 0x65
41 #define C6 0x66
42 #define C7 0x67
43 #define D0 0x90
44 #define D1 0x91
45 #define D2 0x92
46 #define D3 0x93
47 #define D4 0x94
48 #define D5 0x95
49 #define D6 0x96
50 #define D7 0x97
51 #define E0 0xC0
52 #define E1 0xC1
53 #define E2 0xC2
54 #define E3 0xC3
55 #define E4 0xC4
56 #define E5 0xC5
57 #define E6 0xC6
58 #define E7 0xC7
59 #define F0 0xF0
60 #define F1 0xF1
61 #define F2 0xF2
62 #define F3 0xF3
63 #define F4 0xF4
64 #define F5 0xF5
65 #define F6 0xF6
66 #define F7 0xF7
67 #define A0 0x00
68 #define A1 0x01
69 #define A2 0x02
70 #define A3 0x03
71 #define A4 0x04
72 #define A5 0x05
73 #define A6 0x06
74 #define A7 0x07
75#endif
57 76
58/* USART configuration */ 77/* USART configuration */
59#ifdef BLUETOOTH_ENABLE 78#ifdef BLUETOOTH_ENABLE
@@ -76,53 +95,9 @@
76 } while(0) 95 } while(0)
77# else 96# else
78# error "USART configuration is needed." 97# error "USART configuration is needed."
98# endif
79#endif 99#endif
80 100
81// I'm fairly sure these aren't needed, but oh well - Jack 101#define API_SYSEX_MAX_SIZE 32
82
83/*
84 * PS/2 Interrupt configuration
85 */
86#ifdef PS2_USE_INT
87/* uses INT1 for clock line(ATMega32U4) */
88#define PS2_CLOCK_PORT PORTD
89#define PS2_CLOCK_PIN PIND
90#define PS2_CLOCK_DDR DDRD
91#define PS2_CLOCK_BIT 1
92
93#define PS2_DATA_PORT PORTD
94#define PS2_DATA_PIN PIND
95#define PS2_DATA_DDR DDRD
96#define PS2_DATA_BIT 0
97
98#define PS2_INT_INIT() do { \
99 EICRA |= ((1<<ISC11) | \
100 (0<<ISC10)); \
101} while (0)
102#define PS2_INT_ON() do { \
103 EIMSK |= (1<<INT1); \
104} while (0)
105#define PS2_INT_OFF() do { \
106 EIMSK &= ~(1<<INT1); \
107} while (0)
108#define PS2_INT_VECT INT1_vect
109#endif
110
111/*
112 * PS/2 Busywait configuration
113 */
114#ifdef PS2_USE_BUSYWAIT
115#define PS2_CLOCK_PORT PORTD
116#define PS2_CLOCK_PIN PIND
117#define PS2_CLOCK_DDR DDRD
118#define PS2_CLOCK_BIT 1
119
120#define PS2_DATA_PORT PORTD
121#define PS2_DATA_PIN PIND
122#define PS2_DATA_DDR DDRD
123#define PS2_DATA_BIT 0
124#endif
125
126#endif
127 102
128#endif 103#endif
diff --git a/quantum/dynamic_macro.h b/quantum/dynamic_macro.h
index e6dbc5b9c..64093f293 100644
--- a/quantum/dynamic_macro.h
+++ b/quantum/dynamic_macro.h
@@ -1,3 +1,19 @@
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
1/* Author: Wojciech Siewierski < wojciech dot siewierski at onet dot pl > */ 17/* Author: Wojciech Siewierski < wojciech dot siewierski at onet dot pl > */
2#ifndef DYNAMIC_MACROS_H 18#ifndef DYNAMIC_MACROS_H
3#define DYNAMIC_MACROS_H 19#define DYNAMIC_MACROS_H
diff --git a/quantum/fauxclicky.c b/quantum/fauxclicky.c
new file mode 100644
index 000000000..13273e705
--- /dev/null
+++ b/quantum/fauxclicky.c
@@ -0,0 +1,68 @@
1/*
2Copyright 2017 Priyadi Iman Nurcahyo
3
4This program is free software: you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation, either version 2 of the License, or
7(at your option) any later version.
8This program is distributed in the hope that it will be useful,
9but WITHOUT ANY WARRANTY; without even the implied warranty of
10MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11GNU General Public License for more details.
12You should have received a copy of the GNU General Public License
13along with this program. If not, see <http://www.gnu.org/licenses/>.
14*/
15
16#include <avr/interrupt.h>
17#include <avr/io.h>
18#include <timer.h>
19#include <fauxclicky.h>
20#include <stdbool.h>
21#include <musical_notes.h>
22
23__attribute__ ((weak))
24float fauxclicky_pressed_note[2] = MUSICAL_NOTE(_F3, 2);
25__attribute__ ((weak))
26float fauxclicky_released_note[2] = MUSICAL_NOTE(_A3, 2);
27__attribute__ ((weak))
28float fauxclicky_beep_note[2] = MUSICAL_NOTE(_C3, 2);
29
30bool fauxclicky_enabled = true;
31uint16_t note_start = 0;
32bool note_playing = false;
33uint16_t note_period = 0;
34
35void fauxclicky_init()
36{
37 // Set port PC6 (OC3A and /OC4A) as output
38 DDRC |= _BV(PORTC6);
39
40 // TCCR3A / TCCR3B: Timer/Counter #3 Control Registers
41 TCCR3A = (0 << COM3A1) | (0 << COM3A0) | (1 << WGM31) | (0 << WGM30);
42 TCCR3B = (1 << WGM33) | (1 << WGM32) | (0 << CS32) | (1 << CS31) | (0 << CS30);
43}
44
45void fauxclicky_stop()
46{
47 FAUXCLICKY_DISABLE_OUTPUT;
48 note_playing = false;
49}
50
51void fauxclicky_play(float note[2]) {
52 if (!fauxclicky_enabled) return;
53 if (note_playing) fauxclicky_stop();
54 FAUXCLICKY_TIMER_PERIOD = (uint16_t)(((float)F_CPU) / (note[0] * FAUXCLICKY_CPU_PRESCALER));
55 FAUXCLICKY_DUTY_CYCLE = (uint16_t)((((float)F_CPU) / (note[0] * FAUXCLICKY_CPU_PRESCALER)) / 2);
56 note_playing = true;
57 note_period = (note[1] / 16) * (60 / (float)FAUXCLICKY_TEMPO) * 100; // check this
58 note_start = timer_read();
59 FAUXCLICKY_ENABLE_OUTPUT;
60}
61
62void fauxclicky_check() {
63 if (!note_playing) return;
64
65 if (timer_elapsed(note_start) > note_period) {
66 fauxclicky_stop();
67 }
68}
diff --git a/quantum/fauxclicky.h b/quantum/fauxclicky.h
new file mode 100644
index 000000000..109bd0d83
--- /dev/null
+++ b/quantum/fauxclicky.h
@@ -0,0 +1,99 @@
1/*
2Copyright 2017 Priyadi Iman Nurcahyo
3
4This program is free software: you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation, either version 2 of the License, or
7(at your option) any later version.
8This program is distributed in the hope that it will be useful,
9but WITHOUT ANY WARRANTY; without even the implied warranty of
10MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11GNU General Public License for more details.
12You should have received a copy of the GNU General Public License
13along with this program. If not, see <http://www.gnu.org/licenses/>.
14*/
15
16#ifdef AUDIO_ENABLE
17#error "AUDIO_ENABLE and FAUXCLICKY_ENABLE cannot be both enabled"
18#endif
19
20#include "musical_notes.h"
21#include "stdbool.h"
22
23__attribute__ ((weak))
24float fauxclicky_pressed_note[2];
25__attribute__ ((weak))
26float fauxclicky_released_note[2];
27__attribute__ ((weak))
28float fauxclicky_beep_note[2];
29
30bool fauxclicky_enabled;
31
32//
33// tempo in BPM
34//
35
36#ifndef FAUXCLICKY_TEMPO
37#define FAUXCLICKY_TEMPO TEMPO_DEFAULT
38#endif
39
40// beep on press
41#define FAUXCLICKY_ACTION_PRESS fauxclicky_play(fauxclicky_pressed_note)
42
43// beep on release
44#define FAUXCLICKY_ACTION_RELEASE fauxclicky_play(fauxclicky_released_note)
45
46// general purpose beep
47#define FAUXCLICKY_BEEP fauxclicky_play(fauxclicky_beep_note)
48
49// enable
50#define FAUXCLICKY_ON fauxclicky_enabled = true
51
52// disable
53#define FAUXCLICKY_OFF do { \
54 fauxclicky_enabled = false; \
55 fauxclicky_stop(); \
56} while (0)
57
58// toggle
59#define FAUXCLICKY_TOGGLE do { \
60 if (fauxclicky_enabled) { \
61 FAUXCLICKY_OFF; \
62 } else { \
63 FAUXCLICKY_ON; \
64 } \
65} while (0)
66
67//
68// pin configuration
69//
70
71#ifndef FAUXCLICKY_CPU_PRESCALER
72#define FAUXCLICKY_CPU_PRESCALER 8
73#endif
74
75#ifndef FAUXCLICKY_ENABLE_OUTPUT
76#define FAUXCLICKY_ENABLE_OUTPUT TCCR3A |= _BV(COM3A1);
77#endif
78
79#ifndef FAUXCLICKY_DISABLE_OUTPUT
80#define FAUXCLICKY_DISABLE_OUTPUT TCCR3A &= ~(_BV(COM3A1) | _BV(COM3A0));
81#endif
82
83#ifndef FAUXCLICKY_TIMER_PERIOD
84#define FAUXCLICKY_TIMER_PERIOD ICR3
85#endif
86
87#ifndef FAUXCLICKY_DUTY_CYCLE
88#define FAUXCLICKY_DUTY_CYCLE OCR3A
89#endif
90
91//
92// definitions
93//
94
95void fauxclicky_init(void);
96void fauxclicky_stop(void);
97void fauxclicky_play(float note[2]);
98void fauxclicky_check(void);
99
diff --git a/quantum/keycode_config.c b/quantum/keycode_config.c
index 6d90781a1..4f7bc525e 100644
--- a/quantum/keycode_config.c
+++ b/quantum/keycode_config.c
@@ -1,3 +1,19 @@
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
1#include "keycode_config.h" 17#include "keycode_config.h"
2 18
3extern keymap_config_t keymap_config; 19extern keymap_config_t keymap_config;
@@ -71,4 +87,4 @@ uint16_t keycode_config(uint16_t keycode) {
71 default: 87 default:
72 return keycode; 88 return keycode;
73 } 89 }
74} \ No newline at end of file 90}
diff --git a/quantum/keycode_config.h b/quantum/keycode_config.h
index c15b0d32f..293fefecf 100644
--- a/quantum/keycode_config.h
+++ b/quantum/keycode_config.h
@@ -1,3 +1,19 @@
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
1#include "eeconfig.h" 17#include "eeconfig.h"
2#include "keycode.h" 18#include "keycode.h"
3 19
diff --git a/quantum/keymap.h b/quantum/keymap.h
index a01bbfbd1..5d64be19c 100644
--- a/quantum/keymap.h
+++ b/quantum/keymap.h
@@ -1,5 +1,5 @@
1/* 1/*
2Copyright 2012,2013 Jun Wako <wakojun@gmail.com> 2Copyright 2012-2016 Jun Wako <wakojun@gmail.com>
3 3
4This program is free software: you can redistribute it and/or modify 4This program is free software: you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by 5it under the terms of the GNU General Public License as published by
@@ -38,313 +38,16 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
38#define RESET QK_RESET 38#define RESET QK_RESET
39#endif 39#endif
40 40
41/* translates key to keycode */ 41#include "quantum_keycodes.h"
42
43// translates key to keycode
42uint16_t keymap_key_to_keycode(uint8_t layer, keypos_t key); 44uint16_t keymap_key_to_keycode(uint8_t layer, keypos_t key);
43 45
46// translates function id to action
47uint16_t keymap_function_id_to_action( uint16_t function_id );
48
44extern const uint16_t keymaps[][MATRIX_ROWS][MATRIX_COLS]; 49extern const uint16_t keymaps[][MATRIX_ROWS][MATRIX_COLS];
45extern const uint16_t fn_actions[]; 50extern const uint16_t fn_actions[];
46 51
47enum quantum_keycodes {
48 // Ranges used in shortucuts - not to be used directly
49 QK_TMK = 0x0000,
50 QK_TMK_MAX = 0x00FF,
51 QK_MODS = 0x0100,
52 QK_LCTL = 0x0100,
53 QK_LSFT = 0x0200,
54 QK_LALT = 0x0400,
55 QK_LGUI = 0x0800,
56 QK_RCTL = 0x1100,
57 QK_RSFT = 0x1200,
58 QK_RALT = 0x1400,
59 QK_RGUI = 0x1800,
60 QK_MODS_MAX = 0x1FFF,
61 QK_FUNCTION = 0x2000,
62 QK_FUNCTION_MAX = 0x2FFF,
63 QK_MACRO = 0x3000,
64 QK_MACRO_MAX = 0x3FFF,
65 QK_LAYER_TAP = 0x4000,
66 QK_LAYER_TAP_MAX = 0x4FFF,
67 QK_TO = 0x5000,
68 QK_TO_MAX = 0x50FF,
69 QK_MOMENTARY = 0x5100,
70 QK_MOMENTARY_MAX = 0x51FF,
71 QK_DEF_LAYER = 0x5200,
72 QK_DEF_LAYER_MAX = 0x52FF,
73 QK_TOGGLE_LAYER = 0x5300,
74 QK_TOGGLE_LAYER_MAX = 0x53FF,
75 QK_ONE_SHOT_LAYER = 0x5400,
76 QK_ONE_SHOT_LAYER_MAX = 0x54FF,
77 QK_ONE_SHOT_MOD = 0x5500,
78 QK_ONE_SHOT_MOD_MAX = 0x55FF,
79#ifndef DISABLE_CHORDING
80 QK_CHORDING = 0x5600,
81 QK_CHORDING_MAX = 0x56FF,
82#endif
83 QK_MOD_TAP = 0x6000,
84 QK_MOD_TAP_MAX = 0x6FFF,
85 QK_TAP_DANCE = 0x7100,
86 QK_TAP_DANCE_MAX = 0x71FF,
87#ifdef UNICODEMAP_ENABLE
88 QK_UNICODE_MAP = 0x7800,
89 QK_UNICODE_MAP_MAX = 0x7FFF,
90#endif
91#ifdef UNICODE_ENABLE
92 QK_UNICODE = 0x8000,
93 QK_UNICODE_MAX = 0xFFFF,
94#endif
95
96 // Loose keycodes - to be used directly
97
98 RESET = 0x7000,
99 DEBUG,
100 MAGIC_SWAP_CONTROL_CAPSLOCK,
101 MAGIC_CAPSLOCK_TO_CONTROL,
102 MAGIC_SWAP_LALT_LGUI,
103 MAGIC_SWAP_RALT_RGUI,
104 MAGIC_NO_GUI,
105 MAGIC_SWAP_GRAVE_ESC,
106 MAGIC_SWAP_BACKSLASH_BACKSPACE,
107 MAGIC_HOST_NKRO,
108 MAGIC_SWAP_ALT_GUI,
109 MAGIC_UNSWAP_CONTROL_CAPSLOCK,
110 MAGIC_UNCAPSLOCK_TO_CONTROL,
111 MAGIC_UNSWAP_LALT_LGUI,
112 MAGIC_UNSWAP_RALT_RGUI,
113 MAGIC_UNNO_GUI,
114 MAGIC_UNSWAP_GRAVE_ESC,
115 MAGIC_UNSWAP_BACKSLASH_BACKSPACE,
116 MAGIC_UNHOST_NKRO,
117 MAGIC_UNSWAP_ALT_GUI,
118 MAGIC_TOGGLE_NKRO,
119
120 // Leader key
121#ifndef DISABLE_LEADER
122 KC_LEAD,
123#endif
124
125 // Audio on/off/toggle
126 AU_ON,
127 AU_OFF,
128 AU_TOG,
129
130 // Music mode on/off/toggle
131 MU_ON,
132 MU_OFF,
133 MU_TOG,
134
135 // Music voice iterate
136 MUV_IN,
137 MUV_DE,
138
139 // Midi mode on/off
140 MIDI_ON,
141 MIDI_OFF,
142
143 // Backlight functionality
144 BL_0,
145 BL_1,
146 BL_2,
147 BL_3,
148 BL_4,
149 BL_5,
150 BL_6,
151 BL_7,
152 BL_8,
153 BL_9,
154 BL_10,
155 BL_11,
156 BL_12,
157 BL_13,
158 BL_14,
159 BL_15,
160 BL_DEC,
161 BL_INC,
162 BL_TOGG,
163 BL_STEP,
164
165 // RGB functionality
166 RGB_TOG,
167 RGB_MOD,
168 RGB_HUI,
169 RGB_HUD,
170 RGB_SAI,
171 RGB_SAD,
172 RGB_VAI,
173 RGB_VAD,
174
175 // Left shift, open paren
176 KC_LSPO,
177
178 // Right shift, close paren
179 KC_RSPC,
180
181 // always leave at the end
182 SAFE_RANGE
183};
184
185// Ability to use mods in layouts
186#define LCTL(kc) (kc | QK_LCTL)
187#define LSFT(kc) (kc | QK_LSFT)
188#define LALT(kc) (kc | QK_LALT)
189#define LGUI(kc) (kc | QK_LGUI)
190#define RCTL(kc) (kc | QK_RCTL)
191#define RSFT(kc) (kc | QK_RSFT)
192#define RALT(kc) (kc | QK_RALT)
193#define RGUI(kc) (kc | QK_RGUI)
194
195#define HYPR(kc) (kc | QK_LCTL | QK_LSFT | QK_LALT | QK_LGUI)
196#define MEH(kc) (kc | QK_LCTL | QK_LSFT | QK_LALT)
197#define LCAG(kc) (kc | QK_LCTL | QK_LALT | QK_LGUI)
198#define ALTG(kc) (kc | QK_RCTL | QK_RALT)
199
200#define MOD_HYPR 0xf
201#define MOD_MEH 0x7
202
203
204// Aliases for shifted symbols
205// Each key has a 4-letter code, and some have longer aliases too.
206// While the long aliases are descriptive, the 4-letter codes
207// make for nicer grid layouts (everything lines up), and are
208// the preferred style for Quantum.
209#define KC_TILD LSFT(KC_GRV) // ~
210#define KC_TILDE KC_TILD
211
212#define KC_EXLM LSFT(KC_1) // !
213#define KC_EXCLAIM KC_EXLM
214
215#define KC_AT LSFT(KC_2) // @
216
217#define KC_HASH LSFT(KC_3) // #
218
219#define KC_DLR LSFT(KC_4) // $
220#define KC_DOLLAR KC_DLR
221
222#define KC_PERC LSFT(KC_5) // %
223#define KC_PERCENT KC_PERC
224
225#define KC_CIRC LSFT(KC_6) // ^
226#define KC_CIRCUMFLEX KC_CIRC
227
228#define KC_AMPR LSFT(KC_7) // &
229#define KC_AMPERSAND KC_AMPR
230
231#define KC_ASTR LSFT(KC_8) // *
232#define KC_ASTERISK KC_ASTR
233
234#define KC_LPRN LSFT(KC_9) // (
235#define KC_LEFT_PAREN KC_LPRN
236
237#define KC_RPRN LSFT(KC_0) // )
238#define KC_RIGHT_PAREN KC_RPRN
239
240#define KC_UNDS LSFT(KC_MINS) // _
241#define KC_UNDERSCORE KC_UNDS
242
243#define KC_PLUS LSFT(KC_EQL) // +
244
245#define KC_LCBR LSFT(KC_LBRC) // {
246#define KC_LEFT_CURLY_BRACE KC_LCBR
247
248#define KC_RCBR LSFT(KC_RBRC) // }
249#define KC_RIGHT_CURLY_BRACE KC_RCBR
250
251#define KC_LABK LSFT(KC_COMM) // <
252#define KC_LEFT_ANGLE_BRACKET KC_LABK
253
254#define KC_RABK LSFT(KC_DOT) // >
255#define KC_RIGHT_ANGLE_BRACKET KC_RABK
256
257#define KC_COLN LSFT(KC_SCLN) // :
258#define KC_COLON KC_COLN
259
260#define KC_PIPE LSFT(KC_BSLS) // |
261
262#define KC_LT LSFT(KC_COMM) // <
263
264#define KC_GT LSFT(KC_DOT) // >
265
266#define KC_QUES LSFT(KC_SLSH) // ?
267#define KC_QUESTION KC_QUES
268
269#define KC_DQT LSFT(KC_QUOT) // "
270#define KC_DOUBLE_QUOTE KC_DQT
271#define KC_DQUO KC_DQT
272
273#define KC_DELT KC_DELETE // Del key (four letter code)
274
275// Alias for function layers than expand past FN31
276#define FUNC(kc) (kc | QK_FUNCTION)
277
278// Aliases
279#define S(kc) LSFT(kc)
280#define F(kc) FUNC(kc)
281
282#define M(kc) (kc | QK_MACRO)
283
284#define MACRODOWN(...) (record->event.pressed ? MACRO(__VA_ARGS__) : MACRO_NONE)
285
286// L-ayer, T-ap - 256 keycode max, 16 layer max
287#define LT(layer, kc) (kc | QK_LAYER_TAP | ((layer & 0xF) << 8))
288
289#define AG_SWAP MAGIC_SWAP_ALT_GUI
290#define AG_NORM MAGIC_UNSWAP_ALT_GUI
291
292#define BL_ON BL_9
293#define BL_OFF BL_0
294
295#define MI_ON MIDI_ON
296#define MI_OFF MIDI_OFF
297
298// GOTO layer - 16 layers max
299// when:
300// ON_PRESS = 1
301// ON_RELEASE = 2
302// Unless you have a good reason not to do so, prefer ON_PRESS (1) as your default.
303// In fact, we changed it to assume ON_PRESS for sanity/simplicity. If needed, you can add your own
304// keycode modeled after the old version, kept below for this.
305/* #define TO(layer, when) (layer | QK_TO | (when << 0x4)) */
306#define TO(layer) (layer | QK_TO | (ON_PRESS << 0x4))
307
308// Momentary switch layer - 256 layer max
309#define MO(layer) (layer | QK_MOMENTARY)
310
311// Set default layer - 256 layer max
312#define DF(layer) (layer | QK_DEF_LAYER)
313
314// Toggle to layer - 256 layer max
315#define TG(layer) (layer | QK_TOGGLE_LAYER)
316
317// One-shot layer - 256 layer max
318#define OSL(layer) (layer | QK_ONE_SHOT_LAYER)
319
320// One-shot mod
321#define OSM(mod) (mod | QK_ONE_SHOT_MOD)
322
323// M-od, T-ap - 256 keycode max
324#define MT(mod, kc) (kc | QK_MOD_TAP | ((mod & 0xF) << 8))
325#define CTL_T(kc) MT(MOD_LCTL, kc)
326#define SFT_T(kc) MT(MOD_LSFT, kc)
327#define ALT_T(kc) MT(MOD_LALT, kc)
328#define GUI_T(kc) MT(MOD_LGUI, kc)
329#define C_S_T(kc) MT((MOD_LCTL | MOD_LSFT), kc) // Control + Shift e.g. for gnome-terminal
330#define MEH_T(kc) MT((MOD_LCTL | MOD_LSFT | MOD_LALT), kc) // Meh is a less hyper version of the Hyper key -- doesn't include Win or Cmd, so just alt+shift+ctrl
331#define LCAG_T(kc) MT((MOD_LCTL | MOD_LALT | MOD_LGUI), kc) // Left control alt and gui
332#define ALL_T(kc) MT((MOD_LCTL | MOD_LSFT | MOD_LALT | MOD_LGUI), kc) // see http://brettterpstra.com/2012/12/08/a-useful-caps-lock-key/
333
334// Dedicated keycode versions for Hyper and Meh, if you want to use them as standalone keys rather than mod-tap
335#define KC_HYPR HYPR(KC_NO)
336#define KC_MEH MEH(KC_NO)
337
338#ifdef UNICODE_ENABLE
339 // For sending unicode codes.
340 // You may not send codes over 7FFF -- this supports most of UTF8.
341 // To have a key that sends out Œ, go UC(0x0152)
342 #define UNICODE(n) (n | QK_UNICODE)
343 #define UC(n) UNICODE(n)
344#endif
345
346#ifdef UNICODEMAP_ENABLE
347 #define X(n) (n | QK_UNICODE_MAP)
348#endif
349 52
350#endif 53#endif
diff --git a/quantum/keymap_common.c b/quantum/keymap_common.c
index 833e5a8f8..6cf4f031f 100644
--- a/quantum/keymap_common.c
+++ b/quantum/keymap_common.c
@@ -1,5 +1,5 @@
1/* 1/*
2Copyright 2012,2013 Jun Wako <wakojun@gmail.com> 2Copyright 2012-2017 Jun Wako <wakojun@gmail.com>
3 3
4This program is free software: you can redistribute it and/or modify 4This program is free software: you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by 5it under the terms of the GNU General Public License as published by
@@ -48,12 +48,10 @@ action_t action_for_key(uint8_t layer, keypos_t key)
48 48
49 action_t action; 49 action_t action;
50 uint8_t action_layer, when, mod; 50 uint8_t action_layer, when, mod;
51 // The arm-none-eabi compiler generates out of bounds warnings when using the fn_actions directly for some reason
52 const uint16_t* actions = fn_actions;
53 51
54 switch (keycode) { 52 switch (keycode) {
55 case KC_FN0 ... KC_FN31: 53 case KC_FN0 ... KC_FN31:
56 action.code = pgm_read_word(&actions[FN_INDEX(keycode)]); 54 action.code = keymap_function_id_to_action(FN_INDEX(keycode));
57 break; 55 break;
58 case KC_A ... KC_EXSEL: 56 case KC_A ... KC_EXSEL:
59 case KC_LCTRL ... KC_RGUI: 57 case KC_LCTRL ... KC_RGUI:
@@ -79,10 +77,13 @@ action_t action_for_key(uint8_t layer, keypos_t key)
79 case QK_FUNCTION ... QK_FUNCTION_MAX: ; 77 case QK_FUNCTION ... QK_FUNCTION_MAX: ;
80 // Is a shortcut for function action_layer, pull last 12bits 78 // Is a shortcut for function action_layer, pull last 12bits
81 // This means we have 4,096 FN macros at our disposal 79 // This means we have 4,096 FN macros at our disposal
82 action.code = pgm_read_word(&actions[(int)keycode & 0xFFF]); 80 action.code = keymap_function_id_to_action( (int)keycode & 0xFFF );
83 break; 81 break;
84 case QK_MACRO ... QK_MACRO_MAX: 82 case QK_MACRO ... QK_MACRO_MAX:
85 action.code = ACTION_MACRO(keycode & 0xFF); 83 if (keycode & 0x800) // tap macros have upper bit set
84 action.code = ACTION_MACRO_TAP(keycode & 0xFF);
85 else
86 action.code = ACTION_MACRO(keycode & 0xFF);
86 break; 87 break;
87 case QK_LAYER_TAP ... QK_LAYER_TAP_MAX: 88 case QK_LAYER_TAP ... QK_LAYER_TAP_MAX:
88 action.code = ACTION_LAYER_TAP_KEY((keycode >> 0x8) & 0xF, keycode & 0xFF); 89 action.code = ACTION_LAYER_TAP_KEY((keycode >> 0x8) & 0xF, keycode & 0xFF);
@@ -118,8 +119,11 @@ action_t action_for_key(uint8_t layer, keypos_t key)
118 mod = keycode & 0xFF; 119 mod = keycode & 0xFF;
119 action.code = ACTION_MODS_ONESHOT(mod); 120 action.code = ACTION_MODS_ONESHOT(mod);
120 break; 121 break;
122 case QK_LAYER_TAP_TOGGLE ... QK_LAYER_TAP_TOGGLE_MAX:
123 action.code = ACTION_LAYER_TAP_TOGGLE(keycode & 0xFF);
124 break;
121 case QK_MOD_TAP ... QK_MOD_TAP_MAX: 125 case QK_MOD_TAP ... QK_MOD_TAP_MAX:
122 action.code = ACTION_MODS_TAP_KEY((keycode >> 0x8) & 0xF, keycode & 0xFF); 126 action.code = ACTION_MODS_TAP_KEY((keycode >> 0x8) & 0x1F, keycode & 0xFF);
123 break; 127 break;
124 #ifdef BACKLIGHT_ENABLE 128 #ifdef BACKLIGHT_ENABLE
125 case BL_0 ... BL_15: 129 case BL_0 ... BL_15:
@@ -163,9 +167,17 @@ void action_function(keyrecord_t *record, uint8_t id, uint8_t opt)
163{ 167{
164} 168}
165 169
166/* translates key to keycode */ 170// translates key to keycode
171__attribute__ ((weak))
167uint16_t keymap_key_to_keycode(uint8_t layer, keypos_t key) 172uint16_t keymap_key_to_keycode(uint8_t layer, keypos_t key)
168{ 173{
169 // Read entire word (16bits) 174 // Read entire word (16bits)
170 return pgm_read_word(&keymaps[(layer)][(key.row)][(key.col)]); 175 return pgm_read_word(&keymaps[(layer)][(key.row)][(key.col)]);
171} 176}
177
178// translates function id to action
179__attribute__ ((weak))
180uint16_t keymap_function_id_to_action( uint16_t function_id )
181{
182 return pgm_read_word(&fn_actions[function_id]);
183}
diff --git a/quantum/keymap_extras/keymap_bepo.h b/quantum/keymap_extras/keymap_bepo.h
index e5ef39552..013559e96 100644
--- a/quantum/keymap_extras/keymap_bepo.h
+++ b/quantum/keymap_extras/keymap_bepo.h
@@ -1,3 +1,18 @@
1/* Copyright 2016 Didier Loiseau
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 */
1/* Keymap macros for the French BÉPO layout - http://bepo.fr */ 16/* Keymap macros for the French BÉPO layout - http://bepo.fr */
2#ifndef KEYMAP_BEPO_H 17#ifndef KEYMAP_BEPO_H
3#define KEYMAP_BEPO_H 18#define KEYMAP_BEPO_H
diff --git a/quantum/keymap_extras/keymap_br_abnt2.h b/quantum/keymap_extras/keymap_br_abnt2.h
new file mode 100644
index 000000000..b001139dd
--- /dev/null
+++ b/quantum/keymap_extras/keymap_br_abnt2.h
@@ -0,0 +1,74 @@
1/* Copyright 2017 Potiguar Faga
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#ifndef KEYMAP_BR_ABNT2_H
18#define KEYMAP_BR_ABNT2_H
19
20#include "keymap_common.h"
21
22/* Scan codes for the Brazilian ABNT2 keyboard layout */
23
24#define BR_CCDL KC_SCLN // Ç same scancode as ;: on US layout
25#define BR_SCLN KC_SLSH // ;: same scancode as /? on US layout
26#define BR_QUOT KC_GRV // '" same scancode as `~ on US layout
27#define BR_TILD KC_QUOT // ~^ dead keys, same scancode as '" on US layout
28#define BR_ACUT KC_LBRC // ´` dead keys, same scancode as [{ on US layout
29#define BR_LBRC KC_RBRC // [{ same scancode as ]} on US layout
30#define BR_RBRC KC_BSLS // ]} same scancode as \| on US layout
31#define BR_BSLS KC_NUBS // \| uses the non-US hash scancode (#~, sometimes §±)
32#define BR_SLSH KC_INT1 // /? uses the INTL1 scancode
33
34#define BR_COLN LSFT(BR_SCLN) // shifted :
35#define BR_DQT LSFT(BR_QUOT) // shifted "
36#define BR_CIRC LSFT(BR_TILD) // shifted ^ (dead key)
37#define BR_GRAV LSFT(BR_ACUT) // shifted ` (dead key)
38#define BR_LCBR LSFT(BR_LBRC) // shifted {
39#define BR_RCBR LSFT(BR_RBRC) // shifted }
40#define BR_PIPE LSFT(BR_BSLS) // shifted |
41#define BR_QUES LSFT(BR_SLSH) // shifted ?
42#define BR_TRMA LSFT(KC_6) // shifted ¨ (dead key - trema accent)
43
44// On the ABNT2 the keypad comma and the keypad dot scancodes are switched
45// (presumably because in Brazil comma is used as the decimal separator)
46#define BR_KPDT KC_KP_COMMA // keypad .
47#define BR_KPCM KC_KP_DOT // keypad ,
48
49#define BR_1UP LALT(KC_1) // 1 superscript ¹ alt+1
50#define BR_2UP LALT(KC_2) // 2 superscript ² alt+2
51#define BR_3UP LALT(KC_3) // 3 superscript ³ alt+3
52#define BR_PND LALT(KC_4) // Pound sign £ alt+4
53#define BR_CENT LALT(KC_5) // Cent sign ¢ alt+5
54#define BR_NOT LALT(KC_6) // Not sign ¬ alt+6
55#define BR_SECT LALT(KC_EQL) // Section sign § alt+=
56#define BR_FORD LALT(BR_LBRC) // Feminine Ordinal Sign ª alt+[
57#define BR_MORD LALT(BR_RBRC) // Masculine Ordinal Sign º alt+]
58#define BR_DGRE LALT(BR_SLSH) // Degree sign ° alt+/
59
60#define BR_EURO LALT(KC_E) // Euro sign € alt+e
61#define BR_NDTD LALT(BR_TILD) // Non-dead key tilde ~ alt+~
62#define BR_NDAC LALT(BR_ACUT) // Non-dead key acute accent ´ alt+´
63#define BR_NDGV LALT(BR_QUOT) // Non-dead key grave accent ` alt+'
64#define BR_NDCR LALT(BR_CIRC) // Non-dead key circumflex accent ^ alt+^ (alt+shift+~)
65#define BR_NDTR LALT(BR_TRMA) // Non-dead key trema accent ¨ alt+¨ (alt+shift+6)
66
67// For 101-key keyboard layouts, the ABNT2 layout allows
68// the slash and question mark to be typed using alt+q and alt+w.
69// The shortcuts are provided here for completeness' sake,
70// but it's recommended to use BR_SLSH and BR_QUES instead
71#define BR_ASLS LALT(KC_Q)
72#define BR_AQST LALT(KC_W)
73
74#endif
diff --git a/quantum/keymap_extras/keymap_canadian_multilingual.h b/quantum/keymap_extras/keymap_canadian_multilingual.h
index 0bc20c7b9..1d45bee32 100644
--- a/quantum/keymap_extras/keymap_canadian_multilingual.h
+++ b/quantum/keymap_extras/keymap_canadian_multilingual.h
@@ -1,3 +1,18 @@
1/* Copyright 2016 Didier Loiseau
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 */
1#ifndef KEYMAP_CANADIAN_MULTILINGUAG_H 16#ifndef KEYMAP_CANADIAN_MULTILINGUAG_H
2#define KEYMAP_CANADIAN_MULTILINGUAG_H 17#define KEYMAP_CANADIAN_MULTILINGUAG_H
3 18
diff --git a/quantum/keymap_extras/keymap_colemak.h b/quantum/keymap_extras/keymap_colemak.h
index b8d615748..2d3f9c06a 100644
--- a/quantum/keymap_extras/keymap_colemak.h
+++ b/quantum/keymap_extras/keymap_colemak.h
@@ -1,3 +1,18 @@
1/* Copyright 2015-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 */
1#ifndef KEYMAP_COLEMAK_H 16#ifndef KEYMAP_COLEMAK_H
2#define KEYMAP_COLEMAK_H 17#define KEYMAP_COLEMAK_H
3 18
diff --git a/quantum/keymap_extras/keymap_dvorak.h b/quantum/keymap_extras/keymap_dvorak.h
index a0feed850..b1d5604ba 100644
--- a/quantum/keymap_extras/keymap_dvorak.h
+++ b/quantum/keymap_extras/keymap_dvorak.h
@@ -1,3 +1,18 @@
1/* Copyright 2015-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 */
1#ifndef KEYMAP_DVORAK_H 16#ifndef KEYMAP_DVORAK_H
2#define KEYMAP_DVORAK_H 17#define KEYMAP_DVORAK_H
3 18
diff --git a/quantum/keymap_extras/keymap_dvp.h b/quantum/keymap_extras/keymap_dvp.h
index 83f49a52b..50e2d1f46 100644
--- a/quantum/keymap_extras/keymap_dvp.h
+++ b/quantum/keymap_extras/keymap_dvp.h
@@ -1,3 +1,19 @@
1/* Copyright 2016 Artyom Mironov
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
1#ifndef KEYMAP_DVP_H 17#ifndef KEYMAP_DVP_H
2#define KEYMAP_DVP_H 18#define KEYMAP_DVP_H
3 19
diff --git a/quantum/keymap_extras/keymap_fr_ch.h b/quantum/keymap_extras/keymap_fr_ch.h
index 87d4bb24c..c0ca832a6 100644
--- a/quantum/keymap_extras/keymap_fr_ch.h
+++ b/quantum/keymap_extras/keymap_fr_ch.h
@@ -1,3 +1,18 @@
1/* Copyright 2016 Vincent Pochet
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 */
1#ifndef KEYMAP_FR_CH 16#ifndef KEYMAP_FR_CH
2#define KEYMAP_FR_CH 17#define KEYMAP_FR_CH
3 18
diff --git a/quantum/keymap_extras/keymap_french.h b/quantum/keymap_extras/keymap_french.h
index 834c69650..3308dc5f7 100644
--- a/quantum/keymap_extras/keymap_french.h
+++ b/quantum/keymap_extras/keymap_french.h
@@ -1,10 +1,27 @@
1/* Copyright 2015-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 */
1#ifndef KEYMAP_FRENCH_H 16#ifndef KEYMAP_FRENCH_H
2#define KEYMAP_FRENCH_H 17#define KEYMAP_FRENCH_H
3 18
4#include "keymap.h" 19#include "keymap.h"
5 20
6// Alt gr 21// Alt gr
22#ifndef ALGR
7#define ALGR(kc) RALT(kc) 23#define ALGR(kc) RALT(kc)
24#endif
8#define NO_ALGR KC_RALT 25#define NO_ALGR KC_RALT
9 26
10// Normal characters 27// Normal characters
@@ -72,7 +89,7 @@
72#define FR_PIPE ALGR(KC_6) 89#define FR_PIPE ALGR(KC_6)
73#define FR_GRV ALGR(KC_7) 90#define FR_GRV ALGR(KC_7)
74#define FR_BSLS ALGR(KC_8) 91#define FR_BSLS ALGR(KC_8)
75#define FR_CIRC ALGR(KC_9) 92#define FR_CCIRC ALGR(KC_9)
76#define FR_AT ALGR(KC_0) 93#define FR_AT ALGR(KC_0)
77#define FR_RBRC ALGR(FR_RPRN) 94#define FR_RBRC ALGR(FR_RPRN)
78#define FR_RCBR ALGR(FR_EQL) 95#define FR_RCBR ALGR(FR_EQL)
diff --git a/quantum/keymap_extras/keymap_french_osx.h b/quantum/keymap_extras/keymap_french_osx.h
index 004d73ee2..ecade3fe9 100644
--- a/quantum/keymap_extras/keymap_french_osx.h
+++ b/quantum/keymap_extras/keymap_french_osx.h
@@ -1,3 +1,18 @@
1/* Copyright 2016 Sébastien Pérochon
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 */
1#ifndef KEYMAP_FRENCH_OSX_H 16#ifndef KEYMAP_FRENCH_OSX_H
2#define KEYMAP_FRENCH_OSX_H 17#define KEYMAP_FRENCH_OSX_H
3 18
@@ -74,4 +89,4 @@
74#define FR_PIPE LSFT(LALT(KC_L)) 89#define FR_PIPE LSFT(LALT(KC_L))
75#define FR_BSLS LSFT(LALT(FR_COLN)) 90#define FR_BSLS LSFT(LALT(FR_COLN))
76 91
77#endif \ No newline at end of file 92#endif
diff --git a/quantum/keymap_extras/keymap_german.h b/quantum/keymap_extras/keymap_german.h
index 7e2e0ed44..e007c26ef 100644
--- a/quantum/keymap_extras/keymap_german.h
+++ b/quantum/keymap_extras/keymap_german.h
@@ -1,3 +1,19 @@
1/* Copyright 2015-2016 Matthias Schmidtt
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
1#ifndef KEYMAP_GERMAN 17#ifndef KEYMAP_GERMAN
2#define KEYMAP_GERMAN 18#define KEYMAP_GERMAN
3 19
diff --git a/quantum/keymap_extras/keymap_german_ch.h b/quantum/keymap_extras/keymap_german_ch.h
index b66d582a4..8332e00af 100644
--- a/quantum/keymap_extras/keymap_german_ch.h
+++ b/quantum/keymap_extras/keymap_german_ch.h
@@ -1,3 +1,18 @@
1/* Copyright 2016 heartsekai
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 */
1#ifndef KEYMAP_SWISS_GERMAN 16#ifndef KEYMAP_SWISS_GERMAN
2#define KEYMAP_SWISS_GERMAN 17#define KEYMAP_SWISS_GERMAN
3 18
diff --git a/quantum/keymap_extras/keymap_german_osx.h b/quantum/keymap_extras/keymap_german_osx.h
index f63f06618..798bb7579 100644
--- a/quantum/keymap_extras/keymap_german_osx.h
+++ b/quantum/keymap_extras/keymap_german_osx.h
@@ -1,3 +1,18 @@
1/* Copyright 2016 Stephen Bösebeck
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 */
1#ifndef KEYMAP_GERMAN_OSX 16#ifndef KEYMAP_GERMAN_OSX
2#define KEYMAP_GERMAN_OSX 17#define KEYMAP_GERMAN_OSX
3 18
diff --git a/quantum/keymap_extras/keymap_jp.h b/quantum/keymap_extras/keymap_jp.h
new file mode 100644
index 000000000..fb74bce8d
--- /dev/null
+++ b/quantum/keymap_extras/keymap_jp.h
@@ -0,0 +1,77 @@
1/* Copyright 2016 h-youhei
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 * JP106-layout (Japanese Standard)
17 *
18 * For more information, see
19 * http://www2d.biglobe.ne.jp/~msyk/keyboard/layout/usbkeycode.html
20 * note: This website is written in Japanese.
21 */
22
23
24#ifndef KEYMAP_JP_H
25#define KEYMAP_JP_H
26
27
28#include "keymap.h"
29
30
31#define JP_ZHTG KC_GRV // hankaku/zenkaku|kanzi
32#define JP_YEN KC_INT3 // yen, |
33#define JP_CIRC KC_EQL // ^, ~
34#define JP_AT KC_LBRC // @, `
35#define JP_LBRC KC_RBRC // [, {
36#define JP_COLN KC_QUOT // :, *
37#define JP_RBRC KC_NUHS // ], }
38#define JP_BSLS KC_INT1 // \, _
39#define JP_MHEN KC_INT5 // muhenkan
40#define JP_HENK KC_INT4 // henkan
41#define JP_KANA KC_INT2 // katakana/hiragana|ro-mazi
42
43
44//Aliases for shifted symbols
45#define JP_DQT LSFT(KC_2) // "
46#define JP_AMPR LSFT(KC_6) // &
47#define JP_QUOT LSFT(KC_7) // '
48#define JP_LPRN LSFT(KC_8) // (
49#define JP_RPRN LSFT(KC_9) // )
50#define JP_EQL LSFT(KC_MINS) // =
51#define JP_TILD LSFT(JP_CIRC) // ~
52#define JP_PIPE LSFT(JP_YEN) // |
53#define JP_GRV LSFT(JP_AT) // `
54#define JP_LCBR LSFT(JP_LBRC) // {
55#define JP_PLUS LSFT(KC_SCLN) // +
56#define JP_ASTR LSFT(JP_COLN) // *
57#define JP_RCBR LSFT(JP_RBRC) // }
58#define JP_UNDS LSFT(JP_BSLS) // _
59
60
61// These symbols are correspond to US101-layout.
62#define JP_MINS KC_MINS // -
63#define JP_SCLN KC_SCLN // ;
64#define JP_COMM KC_COMM // ,
65#define JP_DOT KC_DOT // .
66#define JP_SLSH KC_SLSH // /
67// shifted
68#define JP_EXLM KC_EXLM // !
69#define JP_HASH KC_HASH // #
70#define JP_DLR KC_DLR // $
71#define JP_PERC KC_PERC // %
72#define JP_LT KC_LT // <
73#define JP_GT KC_GT // >
74#define JP_QUES KC_QUES // ?
75
76
77#endif
diff --git a/quantum/keymap_extras/keymap_neo2.h b/quantum/keymap_extras/keymap_neo2.h
index 80439af34..174f4a6ee 100644
--- a/quantum/keymap_extras/keymap_neo2.h
+++ b/quantum/keymap_extras/keymap_neo2.h
@@ -1,3 +1,18 @@
1/* Copyright 2016 Matthias Schmitt
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 */
1#ifndef KEYMAP_NEO2 16#ifndef KEYMAP_NEO2
2#define KEYMAP_NEO2 17#define KEYMAP_NEO2
3 18
diff --git a/quantum/keymap_extras/keymap_nordic.h b/quantum/keymap_extras/keymap_nordic.h
index da5c82975..6b34db558 100644
--- a/quantum/keymap_extras/keymap_nordic.h
+++ b/quantum/keymap_extras/keymap_nordic.h
@@ -1,3 +1,18 @@
1/* Copyright 2015-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 */
1#ifndef KEYMAP_NORDIC_H 16#ifndef KEYMAP_NORDIC_H
2#define KEYMAP_NORDIC_H 17#define KEYMAP_NORDIC_H
3 18
@@ -13,7 +28,7 @@
13#define NO_ACUT KC_EQL 28#define NO_ACUT KC_EQL
14 29
15#define NO_AM KC_LBRC 30#define NO_AM KC_LBRC
16#define NO_QUOT KC_RBRC 31#define NO_QUOT KC_RBRC // this is the "umlaut" char on Nordic keyboards, Apple layout
17#define NO_AE KC_SCLN 32#define NO_AE KC_SCLN
18#define NO_OSLH KC_QUOT 33#define NO_OSLH KC_QUOT
19#define NO_APOS KC_NUHS 34#define NO_APOS KC_NUHS
diff --git a/quantum/keymap_extras/keymap_norwegian.h b/quantum/keymap_extras/keymap_norwegian.h
index 5c4e8c495..b7128973a 100644
--- a/quantum/keymap_extras/keymap_norwegian.h
+++ b/quantum/keymap_extras/keymap_norwegian.h
@@ -1,3 +1,18 @@
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 */
1#ifndef KEYMAP_NORWEGIAN_H 16#ifndef KEYMAP_NORWEGIAN_H
2#define KEYMAP_NORWEGIAN_H 17#define KEYMAP_NORWEGIAN_H
3 18
diff --git a/quantum/keymap_extras/keymap_plover.h b/quantum/keymap_extras/keymap_plover.h
index 9b88f7d84..de6d8c53f 100644
--- a/quantum/keymap_extras/keymap_plover.h
+++ b/quantum/keymap_extras/keymap_plover.h
@@ -1,3 +1,18 @@
1/* Copyright 2016 James Kay
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 */
1#ifndef KEYMAP_PLOVER_H 16#ifndef KEYMAP_PLOVER_H
2#define KEYMAP_PLOVER_H 17#define KEYMAP_PLOVER_H
3 18
diff --git a/quantum/keymap_extras/keymap_russian.h b/quantum/keymap_extras/keymap_russian.h
deleted file mode 100644
index 237e9abde..000000000
--- a/quantum/keymap_extras/keymap_russian.h
+++ /dev/null
@@ -1,77 +0,0 @@
1#ifndef KEYMAP_RUSSIAN_H
2#define KEYMAP_RUSSIAN_H
3
4#include "keymap.h"
5
6// Normal Chracters // reg SHIFT
7#define RU_A KC_F // а and А
8#define RU_BE KC_COMM // б and Б
9#define RU_VE KC_D // в and В
10#define RU_GHE KC_U // г and Г
11#define RU_DE KC_L // д and Д
12#define RU_IE KC_T // е and Е
13#define RU_IO KC_GRV // ё and Ё
14#define RU_ZHE KC_SCLN // ж and Ж
15#define RU_ZE KC_P // з and З
16#define RU_I KC_B // и and И
17#define RU_SRT_I KC_Q // й and Й
18#define RU_KA KC_R // к and К
19#define RU_EL KC_K // л and Л
20#define RU_EM KC_V // м and М
21#define RU_EN KC_Y // н and Н
22#define RU_O KC_J // о and О
23#define RU_PE KC_G // п and П
24#define RU_ER KC_H // р and Р
25#define RU_ES KC_C // с and С
26#define RU_TE KC_N // т and Т
27#define RU_U KC_E // у and У
28#define RU_EF KC_A // ф and Ф
29#define RU_HA KC_LBRC // х and Х
30#define RU_TSE KC_W // ц and Ц
31#define RU_CHE KC_X // ч and Ч
32#define RU_SHA KC_I // ш and Ш
33#define RU_SHCHA KC_O // щ and Щ
34#define RU_HSIGN KC_RBRC // ъ and Ъ
35#define RU_YERU KC_S // ы and Ы
36#define RU_SSIGN KC_M // ь and Ь
37#define RU_E KC_QUOT // э and Э
38#define RU_YU KC_DOT // ю and Ю
39#define RU_YA KC_Z // я and Я
40
41#define RU_1 KC_1 // 1 and !
42#define RU_2 KC_2 // 2 and "
43#define RU_3 KC_3 // 3 and №
44#define RU_4 KC_4 // 4 and ;
45#define RU_5 KC_5 // 5 and %
46#define RU_6 KC_6 // 6 and :
47#define RU_7 KC_7 // 7 and ?
48#define RU_8 KC_8 // 8 and *
49#define RU_9 KC_9 // 9 and (
50#define RU_0 KC_0 // 0 and )
51
52#define RU_MINS KC_MINS // - and _
53#define RU_EQL KC_EQL // = and +
54#define RU_BSLS KC_BSLS // \ and /
55#define RU_DOT KC_SLSH // . and ,
56
57// Shifted Chracters
58#define RU_EXLM LSFT(RU_1) // !
59#define RU_DQUT LSFT(RU_2) // "
60#define RU_NMRO LSFT(RU_3) // №
61#define RU_SCLN LSFT(RU_4) // ;
62#define RU_PERC LSFT(RU_5) // %
63#define RU_COLN LSFT(RU_6) // :
64#define RU_QUES LSFT(RU_7) // ?
65#define RU_ASTR LSFT(RU_8) // *
66#define RU_LPRN LSFT(RU_9) // (
67#define RU_RPRN LSFT(RU_0) // )
68
69#define RU_UNDR LSFT(RU_MINS) // _
70#define RU_PLUS LSFT(RU_EQL) // +
71#define RU_SLSH LSFT(RU_BSLS) // /
72#define RU_COMM LSFT(RU_DOT) // ,
73
74// Alt Gr-ed characters
75#define RU_RUBL RALT(RU_8) // ₽
76
77#endif
diff --git a/quantum/keymap_extras/keymap_spanish.h b/quantum/keymap_extras/keymap_spanish.h
index 4ba568af2..3a5787e9c 100644
--- a/quantum/keymap_extras/keymap_spanish.h
+++ b/quantum/keymap_extras/keymap_spanish.h
@@ -1,3 +1,18 @@
1/* Copyright 2015-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 */
1#ifndef KEYMAP_SPANISH_H 16#ifndef KEYMAP_SPANISH_H
2#define KEYMAP_SPANISH_H 17#define KEYMAP_SPANISH_H
3 18
diff --git a/quantum/keymap_extras/keymap_uk.h b/quantum/keymap_extras/keymap_uk.h
index 00c87afc3..9d02efe04 100644
--- a/quantum/keymap_extras/keymap_uk.h
+++ b/quantum/keymap_extras/keymap_uk.h
@@ -1,3 +1,18 @@
1/* Copyright 2015-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 */
1#ifndef KEYMAP_UK_H 16#ifndef KEYMAP_UK_H
2#define KEYMAP_UK_H 17#define KEYMAP_UK_H
3 18
diff --git a/quantum/keymap_extras/keymap_unicode_cyrillic.h b/quantum/keymap_extras/keymap_unicode_cyrillic.h
deleted file mode 100644
index a40626d91..000000000
--- a/quantum/keymap_extras/keymap_unicode_cyrillic.h
+++ /dev/null
@@ -1,163 +0,0 @@
1#ifndef KEYMAP_CYRILLIC_H
2#define KEYMAP_CYRILLIC_H
3
4#include "keymap.h"
5
6/*
7 * This is based off of
8 * https://en.wikipedia.org/wiki/Cyrillic_script
9 *
10 * Unicode is iffy, a software implementation is preferred
11 */
12
13// Capital Char russian/ukrainian/bulgarian
14#define CY_A UC(0x0410) // А rus ukr bul
15#define CY_BE UC(0x0411) // Б rus ukr bul
16#define CY_VE UC(0x0412) // В rus ukr bul
17#define CY_GHE UC(0x0413) // Г rus ukr bul
18#define CY_GHEUP UC(0x0490) // Ґ ukr
19#define CY_DE UC(0x0414) // Д rus ukr bul
20#define CY_DJE UC(0x0402) // Ђ
21#define CY_GJE UC(0x0403) // Ѓ
22#define CY_IE UC(0x0415) // Е rus ukr bul
23#define CY_IO UC(0x0401) // Ё rus
24#define CY_UIE UC(0x0404) // Є ukr
25#define CY_ZHE UC(0x0416) // Ж rus ukr bul
26#define CY_ZE UC(0x0417) // З rus ukr bul
27#define CY_DZE UC(0x0405) // Ѕ
28#define CY_I UC(0x0418) // И rus ukr bul
29#define CY_B_U_I UC(0x0406) // І ukr
30#define CY_YI UC(0x0407) // Ї ukr
31#define CY_SRT_I UC(0x0419) // Й rus ukr bul
32#define CY_JE UC(0x0408) // Ј
33#define CY_KA UC(0x041a) // К rus ukr bul
34#define CY_EL UC(0x041b) // Л rus ukr bul
35#define CY_LJE UC(0x0409) // Љ
36#define CY_EM UC(0x041c) // М rus ukr bul
37#define CY_EN UC(0x041d) // Н rus ukr bul
38#define CY_NJE UC(0x040a) // Њ
39#define CY_O UC(0x041e) // О rus ukr bul
40#define CY_PE UC(0x041f) // П rus ukr bul
41#define CY_ER UC(0x0420) // Р rus ukr bul
42#define CY_ES UC(0x0421) // С rus ukr bul
43#define CY_TE UC(0x0422) // Т rus ukr bul
44#define CY_TSHE UC(0x040b) // Ћ
45#define CY_KJE UC(0x040c) // Ќ
46#define CY_U UC(0x0423) // У rus ukr bul
47#define CY_SRT_U UC(0x040e) // Ў
48#define CY_EF UC(0x0424) // Ф rus ukr bul
49#define CY_HA UC(0x0425) // Х rus bul
50#define CY_TSE UC(0x0426) // Ц rus ukr bul
51#define CY_CHE UC(0x0427) // Ч rus ukr bul
52#define CY_DZHE UC(0x040f) // Џ
53#define CY_SHA UC(0x0428) // Ш rus ukr bul
54#define CY_SHCHA UC(0x0429) // Щ rus ukr bul
55#define CY_HSIGN UC(0x042a) // Ъ rus bul
56#define CY_YERU UC(0x042b) // Ы rus
57#define CY_SSIGN UC(0x042c) // Ь rus ukr bul
58#define CY_E UC(0x042d) // Э rus
59#define CY_YU UC(0x042e) // Ю rus ukr bul
60#define CY_YA UC(0x042f) // Я rus ukr bul
61// Important Cyrillic non-Slavic letters
62#define CY_PALOCHKA UC(0x04c0) // Ӏ
63#define CY_SCHWA UC(0x04d8) // Ә
64#define CY_GHE_S UC(0x0492) // Ғ
65#define CY_ZE_D UC(0x0498) // Ҙ
66#define CY_ES_D UC(0x04aa) // Ҫ
67#define CY_BR_KA UC(0x04a0) // Ҡ
68#define CY_ZHE_D UC(0x0496) // Җ
69#define CY_KA_D UC(0x049a) // Қ
70#define CY_EN_D UC(0x04a2) // Ң
71#define CY_ENGHE UC(0x04a4) // Ҥ
72#define CY_BRD_O UC(0x04e8) // Ө
73#define CY_STR_U UC(0x04ae) // Ү
74#define CY_S_U_S UC(0x04b0) // Ұ
75#define CY_SHHA UC(0x04ba) // Һ
76#define CY_HA_D UC(0x04b2) // Ҳ
77
78
79// Small
80#define CY_a UC(0x0430) // a rus ukr bul
81#define CY_be UC(0x0431) // б rus ukr bul
82#define CY_ve UC(0x0432) // в rus ukr bul
83#define CY_ghe UC(0x0433) // г rus ukr bul
84#define CY_gheup UC(0x0491) // ґ ukr
85#define CY_de UC(0x0434) // д rus ukr bul
86#define CY_dje UC(0x0452) // ђ
87#define CY_gje UC(0x0453) // ѓ
88#define CY_ie UC(0x0435) // е rus ukr bul
89#define CY_io UC(0x0451) // ё rus
90#define CY_uie UC(0x0454) // є ukr
91#define CY_zhe UC(0x0436) // ж rus ukr bul
92#define CY_ze UC(0x0437) // з rus ukr bul
93#define CY_dze UC(0x0455) // ѕ
94#define CY_i UC(0x0438) // и rus ukr bul
95#define CY_b_u_i UC(0x0456) // і ukr
96#define CY_yi UC(0x0457) // ї ukr
97#define CY_srt_i UC(0x0439) // й rus ukr bul
98#define CY_je UC(0x0458) // ј
99#define CY_ka UC(0x043a) // к rus ukr bul
100#define CY_el UC(0x043b) // л rus ukr bul
101#define CY_lje UC(0x0459) // љ
102#define CY_em UC(0x043c) // м rus ukr bul
103#define CY_en UC(0x043d) // н rus ukr bul
104#define CY_nje UC(0x045a) // њ
105#define CY_o UC(0x043e) // о rus ukr bul
106#define CY_pe UC(0x043f) // п rus ukr bul
107#define CY_er UC(0x0440) // р rus ukr bul
108#define CY_es UC(0x0441) // с rus ukr bul
109#define CY_te UC(0x0442) // т rus ukr bul
110#define CY_tshe UC(0x045b) // ћ
111#define CY_kje UC(0x045c) // ќ
112#define CY_u UC(0x0443) // у rus ukr bul
113#define CY_srt_u UC(0x045e) // ў
114#define CY_ef UC(0x0444) // ф rus ukr bul
115#define CY_ha UC(0x0445) // х rus ukr bul
116#define CY_tse UC(0x0446) // ц rus ukr bul
117#define CY_che UC(0x0447) // ч rus ukr bul
118#define CY_dzhe UC(0x045f) // џ
119#define CY_sha UC(0x0448) // ш rus ukr bul
120#define CY_shcha UC(0x0449) // щ rus ukr bul
121#define CY_hsign UC(0x044a) // ъ rus bul
122#define CY_yeru UC(0x044b) // ы rus
123#define CY_ssign UC(0x044c) // ь rus ukr bul
124#define CY_e UC(0x044d) // э rus
125#define CY_yu UC(0x044e) // ю rus ukr bul
126#define CY_ya UC(0x044f) // я rus ukr bul
127// Important Cyrillic non-Slavic letters
128#define CY_palochka UC(0x04cf) // ӏ
129#define CY_schwa UC(0x04d9) // ә
130#define CY_ghe_s UC(0x0493) // ғ
131#define CY_ze_d UC(0x0499) // ҙ
132#define CY_es_d UC(0x04ab) // ҫ
133#define CY_br_ka UC(0x04a1) // ҡ
134#define CY_zhe_d UC(0x0497) // җ
135#define CY_ka_d UC(0x049b) // қ
136#define CY_en_d UC(0x04a3) // ң
137#define CY_enghe UC(0x04a5) // ҥ
138#define CY_brd_o UC(0x04e9) // ө
139#define CY_str_u UC(0x04af) // ү
140#define CY_s_u_s UC(0x04b1) // ұ
141#define CY_shha UC(0x04bb) // һ
142#define CY_ha_d UC(0x04b3) // ҳ
143
144
145// Extra
146#define CY_slr_ve UC(0x1c80) // ᲀ CYRILLIC SMALL LETTER ROUNDED VE
147#define CY_ll_de UC(0x1c81) // ᲁ CYRILLIC SMALL LETTER LONG-LEGGED DE
148#define CY_ZEMLYA UC(0xa640) // Ꙁ CYRILLIC CAPITAL LETTER ZEMLYA
149#define CY_zemlya UC(0xa641) // ꙁ CYRILLIC SMALL LETTER ZEMLYA
150#define CY_RV_DZE UC(0xa644) // Ꙅ CYRILLIC CAPITAL LETTER REVERSED DZE
151#define CY_rv_DZE UC(0xa645) // ꙅ CYRILLIC SMALL LETTER REVERSED DZE
152#define CY_slw_es UC(0x1c83) // ᲃ CYRILLIC SMALL LETTER WIDE ES
153#define CY_st_te UC(0x1c84) // ᲄ CYRILLIC SMALL LETTER TALL TE
154#define CY_3l_te UC(0x1c85) // ᲅ CYRILLIC SMALL LETTER THREE-LEGGED TE
155#define CY_thsign UC(0x1c86) // ᲆ CYRILLIC SMALL LETTER TALL HARD SIGN
156#define CY_YERUBY UC(0xa650) // Ꙑ CYRILLIC CAPITAL LETTER YERU WITH BACK YER
157#define CY_yeruby UC(0xa651) // ꙑ CYRILLIC SMALL LETTER YERU WITH BACK YER
158#define CY_RUBL UC(0x20bd) // ₽
159#define CY_NMRO UC(0x2116) // №
160
161// The letters Zje and Sje are made for other letters and accent marks
162
163#endif
diff --git a/quantum/light_ws2812.c b/quantum/light_ws2812.c
index 401845e85..2506e3d8e 100755
--- a/quantum/light_ws2812.c
+++ b/quantum/light_ws2812.c
@@ -7,7 +7,18 @@
7* Jan 18th, 2014 v2.0b Initial Version 7* Jan 18th, 2014 v2.0b Initial Version
8* Nov 29th, 2015 v2.3 Added SK6812RGBW support 8* Nov 29th, 2015 v2.3 Added SK6812RGBW support
9* 9*
10* License: GNU GPL v2 (see License.txt) 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/>.
11*/ 22*/
12 23
13#include "light_ws2812.h" 24#include "light_ws2812.h"
@@ -16,14 +27,128 @@
16#include <util/delay.h> 27#include <util/delay.h>
17#include "debug.h" 28#include "debug.h"
18 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
19// Setleds for standard RGB 144// Setleds for standard RGB
20void inline ws2812_setleds(struct cRGB *ledarray, uint16_t leds) 145void inline ws2812_setleds(LED_TYPE *ledarray, uint16_t leds)
21{ 146{
22 // ws2812_setleds_pin(ledarray,leds, _BV(ws2812_pin)); 147 // ws2812_setleds_pin(ledarray,leds, _BV(ws2812_pin));
23 ws2812_setleds_pin(ledarray,leds, _BV(RGB_DI_PIN & 0xF)); 148 ws2812_setleds_pin(ledarray,leds, _BV(RGB_DI_PIN & 0xF));
24} 149}
25 150
26void inline ws2812_setleds_pin(struct cRGB *ledarray, uint16_t leds, uint8_t pinmask) 151void inline ws2812_setleds_pin(LED_TYPE *ledarray, uint16_t leds, uint8_t pinmask)
27{ 152{
28 // ws2812_DDRREG |= pinmask; // Enable DDR 153 // ws2812_DDRREG |= pinmask; // Enable DDR
29 // new universal format (DDR) 154 // new universal format (DDR)
@@ -34,14 +159,41 @@ void inline ws2812_setleds_pin(struct cRGB *ledarray, uint16_t leds, uint8_t pin
34} 159}
35 160
36// Setleds for SK6812RGBW 161// Setleds for SK6812RGBW
37void inline ws2812_setleds_rgbw(struct cRGBW *ledarray, uint16_t leds) 162void inline ws2812_setleds_rgbw(LED_TYPE *ledarray, uint16_t leds)
38{ 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
39 // ws2812_DDRREG |= _BV(ws2812_pin); // Enable DDR 187 // ws2812_DDRREG |= _BV(ws2812_pin); // Enable DDR
40 // new universal format (DDR) 188 // new universal format (DDR)
41 _SFR_IO8((RGB_DI_PIN >> 4) + 1) |= _BV(RGB_DI_PIN & 0xF); 189 _SFR_IO8((RGB_DI_PIN >> 4) + 1) |= _BV(RGB_DI_PIN & 0xF);
42 190
43 ws2812_sendarray_mask((uint8_t*)ledarray,leds<<2,_BV(RGB_DI_PIN & 0xF)); 191 ws2812_sendarray_mask((uint8_t*)ledarray,leds<<2,_BV(RGB_DI_PIN & 0xF));
44 _delay_us(80); 192
193
194 #ifndef RGBW_BB_TWI
195 _delay_us(80);
196 #endif
45} 197}
46 198
47void ws2812_sendarray(uint8_t *data,uint16_t datlen) 199void ws2812_sendarray(uint8_t *data,uint16_t datlen)
@@ -123,7 +275,7 @@ void inline ws2812_sendarray_mask(uint8_t *data,uint16_t datlen,uint8_t maskhi)
123 cli(); 275 cli();
124 276
125 while (datlen--) { 277 while (datlen--) {
126 curbyte=*data++; 278 curbyte=(*data++);
127 279
128 asm volatile( 280 asm volatile(
129 " ldi %0,8 \n\t" 281 " ldi %0,8 \n\t"
diff --git a/quantum/light_ws2812.h b/quantum/light_ws2812.h
index 54eef22d9..60924a0fb 100755
--- a/quantum/light_ws2812.h
+++ b/quantum/light_ws2812.h
@@ -6,8 +6,18 @@
6 * 6 *
7 * Please do not change this file! All configuration is handled in "ws2812_config.h" 7 * Please do not change this file! All configuration is handled in "ws2812_config.h"
8 * 8 *
9 * License: GNU GPL v2 (see License.txt) 9 * This program is free software: you can redistribute it and/or modify
10 + 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/>.
11 */ 21 */
12 22
13#ifndef LIGHT_WS2812_H_ 23#ifndef LIGHT_WS2812_H_
@@ -16,6 +26,14 @@
16#include <avr/io.h> 26#include <avr/io.h>
17#include <avr/interrupt.h> 27#include <avr/interrupt.h>
18//#include "ws2812_config.h" 28//#include "ws2812_config.h"
29//#include "i2cmaster.h"
30
31#ifdef RGBW
32 #define LED_TYPE struct cRGBW
33#else
34 #define LED_TYPE struct cRGB
35#endif
36
19 37
20/* 38/*
21 * Structure of the LED array 39 * Structure of the LED array
@@ -42,9 +60,9 @@ struct cRGBW { uint8_t g; uint8_t r; uint8_t b; uint8_t w;};
42 * - Wait 50�s to reset the LEDs 60 * - Wait 50�s to reset the LEDs
43 */ 61 */
44 62
45void ws2812_setleds (struct cRGB *ledarray, uint16_t number_of_leds); 63void ws2812_setleds (LED_TYPE *ledarray, uint16_t number_of_leds);
46void ws2812_setleds_pin (struct cRGB *ledarray, uint16_t number_of_leds,uint8_t pinmask); 64void ws2812_setleds_pin (LED_TYPE *ledarray, uint16_t number_of_leds,uint8_t pinmask);
47void ws2812_setleds_rgbw(struct cRGBW *ledarray, uint16_t number_of_leds); 65void ws2812_setleds_rgbw(LED_TYPE *ledarray, uint16_t number_of_leds);
48 66
49/* 67/*
50 * Old interface / Internal functions 68 * Old interface / Internal functions
diff --git a/quantum/matrix.c b/quantum/matrix.c
index 3174e0739..5337e2626 100644
--- a/quantum/matrix.c
+++ b/quantum/matrix.c
@@ -1,6 +1,5 @@
1/* 1/*
2Copyright 2012 Jun Wako 2Copyright 2012-2017 Jun Wako, Jack Humbert
3Copyright 2014 Jack Humbert
4 3
5This program is free software: you can redistribute it and/or modify 4This program is free software: you can redistribute it and/or modify
6it under the terms of the GNU General Public License as published by 5it under the terms of the GNU General Public License as published by
@@ -25,37 +24,66 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
25#include "debug.h" 24#include "debug.h"
26#include "util.h" 25#include "util.h"
27#include "matrix.h" 26#include "matrix.h"
27#include "timer.h"
28
28 29
29/* Set 0 if debouncing isn't needed */ 30/* Set 0 if debouncing isn't needed */
30 31
31#ifndef DEBOUNCING_DELAY 32#ifndef DEBOUNCING_DELAY
32# define DEBOUNCING_DELAY 5 33# define DEBOUNCING_DELAY 5
33#endif 34#endif
34static uint8_t debouncing = DEBOUNCING_DELAY;
35 35
36#if (DEBOUNCING_DELAY > 0)
37 static uint16_t debouncing_time;
38 static bool debouncing = false;
39#endif
40
41#if (MATRIX_COLS <= 8)
42# define print_matrix_header() print("\nr/c 01234567\n")
43# define print_matrix_row(row) print_bin_reverse8(matrix_get_row(row))
44# define matrix_bitpop(i) bitpop(matrix[i])
45# define ROW_SHIFTER ((uint8_t)1)
46#elif (MATRIX_COLS <= 16)
47# define print_matrix_header() print("\nr/c 0123456789ABCDEF\n")
48# define print_matrix_row(row) print_bin_reverse16(matrix_get_row(row))
49# define matrix_bitpop(i) bitpop16(matrix[i])
50# define ROW_SHIFTER ((uint16_t)1)
51#elif (MATRIX_COLS <= 32)
52# define print_matrix_header() print("\nr/c 0123456789ABCDEF0123456789ABCDEF\n")
53# define print_matrix_row(row) print_bin_reverse32(matrix_get_row(row))
54# define matrix_bitpop(i) bitpop32(matrix[i])
55# define ROW_SHIFTER ((uint32_t)1)
56#endif
57
58#ifdef MATRIX_MASKED
59 extern const matrix_row_t matrix_mask[];
60#endif
61
62#if (DIODE_DIRECTION == ROW2COL) || (DIODE_DIRECTION == COL2ROW)
36static const uint8_t row_pins[MATRIX_ROWS] = MATRIX_ROW_PINS; 63static const uint8_t row_pins[MATRIX_ROWS] = MATRIX_ROW_PINS;
37static const uint8_t col_pins[MATRIX_COLS] = MATRIX_COL_PINS; 64static const uint8_t col_pins[MATRIX_COLS] = MATRIX_COL_PINS;
65#endif
38 66
39/* matrix state(1:on, 0:off) */ 67/* matrix state(1:on, 0:off) */
40static matrix_row_t matrix[MATRIX_ROWS]; 68static matrix_row_t matrix[MATRIX_ROWS];
69
41static matrix_row_t matrix_debouncing[MATRIX_ROWS]; 70static matrix_row_t matrix_debouncing[MATRIX_ROWS];
42 71
43#if DIODE_DIRECTION == ROW2COL
44 static matrix_row_t matrix_reversed[MATRIX_COLS];
45 static matrix_row_t matrix_reversed_debouncing[MATRIX_COLS];
46#endif
47 72
48#if MATRIX_COLS > 16 73#if (DIODE_DIRECTION == COL2ROW)
49 #define SHIFTER 1UL 74 static void init_cols(void);
50#else 75 static bool read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row);
51 #define SHIFTER 1 76 static void unselect_rows(void);
77 static void select_row(uint8_t row);
78 static void unselect_row(uint8_t row);
79#elif (DIODE_DIRECTION == ROW2COL)
80 static void init_rows(void);
81 static bool read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col);
82 static void unselect_cols(void);
83 static void unselect_col(uint8_t col);
84 static void select_col(uint8_t col);
52#endif 85#endif
53 86
54static matrix_row_t read_cols(void);
55static void init_cols(void);
56static void unselect_rows(void);
57static void select_row(uint8_t row);
58
59__attribute__ ((weak)) 87__attribute__ ((weak))
60void matrix_init_quantum(void) { 88void matrix_init_quantum(void) {
61 matrix_init_kb(); 89 matrix_init_kb();
@@ -95,7 +123,7 @@ uint8_t matrix_cols(void) {
95} 123}
96 124
97// void matrix_power_up(void) { 125// void matrix_power_up(void) {
98// #if DIODE_DIRECTION == COL2ROW 126// #if (DIODE_DIRECTION == COL2ROW)
99// for (int8_t r = MATRIX_ROWS - 1; r >= 0; --r) { 127// for (int8_t r = MATRIX_ROWS - 1; r >= 0; --r) {
100// /* DDRxn */ 128// /* DDRxn */
101// _SFR_IO8((row_pins[r] >> 4) + 1) |= _BV(row_pins[r] & 0xF); 129// _SFR_IO8((row_pins[r] >> 4) + 1) |= _BV(row_pins[r] & 0xF);
@@ -105,7 +133,7 @@ uint8_t matrix_cols(void) {
105// /* PORTxn */ 133// /* PORTxn */
106// _SFR_IO8((col_pins[c] >> 4) + 2) |= _BV(col_pins[c] & 0xF); 134// _SFR_IO8((col_pins[c] >> 4) + 2) |= _BV(col_pins[c] & 0xF);
107// } 135// }
108// #else 136// #elif (DIODE_DIRECTION == ROW2COL)
109// for (int8_t c = MATRIX_COLS - 1; c >= 0; --c) { 137// for (int8_t c = MATRIX_COLS - 1; c >= 0; --c) {
110// /* DDRxn */ 138// /* DDRxn */
111// _SFR_IO8((col_pins[c] >> 4) + 1) |= _BV(col_pins[c] & 0xF); 139// _SFR_IO8((col_pins[c] >> 4) + 1) |= _BV(col_pins[c] & 0xF);
@@ -119,15 +147,21 @@ uint8_t matrix_cols(void) {
119// } 147// }
120 148
121void matrix_init(void) { 149void matrix_init(void) {
150
122 // To use PORTF disable JTAG with writing JTD bit twice within four cycles. 151 // To use PORTF disable JTAG with writing JTD bit twice within four cycles.
123 #ifdef __AVR_ATmega32U4__ 152 #if (defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB1287__) || defined(__AVR_ATmega32U4__))
124 MCUCR |= _BV(JTD); 153 MCUCR |= _BV(JTD);
125 MCUCR |= _BV(JTD); 154 MCUCR |= _BV(JTD);
126 #endif 155 #endif
127 156
128 // initialize row and col 157 // initialize row and col
158#if (DIODE_DIRECTION == COL2ROW)
129 unselect_rows(); 159 unselect_rows();
130 init_cols(); 160 init_cols();
161#elif (DIODE_DIRECTION == ROW2COL)
162 unselect_cols();
163 init_rows();
164#endif
131 165
132 // initialize matrix state: all keys off 166 // initialize matrix state: all keys off
133 for (uint8_t i=0; i < MATRIX_ROWS; i++) { 167 for (uint8_t i=0; i < MATRIX_ROWS; i++) {
@@ -141,71 +175,60 @@ void matrix_init(void) {
141uint8_t matrix_scan(void) 175uint8_t matrix_scan(void)
142{ 176{
143 177
144#if DIODE_DIRECTION == COL2ROW 178#if (DIODE_DIRECTION == COL2ROW)
145 for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
146 select_row(i);
147 wait_us(30); // without this wait read unstable value.
148 matrix_row_t cols = read_cols();
149 if (matrix_debouncing[i] != cols) {
150 matrix_debouncing[i] = cols;
151 if (debouncing) {
152 debug("bounce!: "); debug_hex(debouncing); debug("\n");
153 }
154 debouncing = DEBOUNCING_DELAY;
155 }
156 unselect_rows();
157 }
158 179
159 if (debouncing) { 180 // Set row, read cols
160 if (--debouncing) { 181 for (uint8_t current_row = 0; current_row < MATRIX_ROWS; current_row++) {
161 wait_ms(1); 182# if (DEBOUNCING_DELAY > 0)
162 } else { 183 bool matrix_changed = read_cols_on_row(matrix_debouncing, current_row);
163 for (uint8_t i = 0; i < MATRIX_ROWS; i++) { 184
164 matrix[i] = matrix_debouncing[i]; 185 if (matrix_changed) {
186 debouncing = true;
187 debouncing_time = timer_read();
165 } 188 }
166 } 189
190# else
191 read_cols_on_row(matrix, current_row);
192# endif
193
167 } 194 }
168#else 195
169 for (uint8_t i = 0; i < MATRIX_COLS; i++) { 196#elif (DIODE_DIRECTION == ROW2COL)
170 select_row(i); 197
171 wait_us(30); // without this wait read unstable value. 198 // Set col, read rows
172 matrix_row_t rows = read_cols(); 199 for (uint8_t current_col = 0; current_col < MATRIX_COLS; current_col++) {
173 if (matrix_reversed_debouncing[i] != rows) { 200# if (DEBOUNCING_DELAY > 0)
174 matrix_reversed_debouncing[i] = rows; 201 bool matrix_changed = read_rows_on_col(matrix_debouncing, current_col);
175 if (debouncing) { 202 if (matrix_changed) {
176 debug("bounce!: "); debug_hex(debouncing); debug("\n"); 203 debouncing = true;
204 debouncing_time = timer_read();
177 } 205 }
178 debouncing = DEBOUNCING_DELAY; 206# else
179 } 207 read_rows_on_col(matrix, current_col);
180 unselect_rows(); 208# endif
209
181 } 210 }
182 211
183 if (debouncing) { 212#endif
184 if (--debouncing) { 213
185 wait_ms(1); 214# if (DEBOUNCING_DELAY > 0)
186 } else { 215 if (debouncing && (timer_elapsed(debouncing_time) > DEBOUNCING_DELAY)) {
187 for (uint8_t i = 0; i < MATRIX_COLS; i++) { 216 for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
188 matrix_reversed[i] = matrix_reversed_debouncing[i]; 217 matrix[i] = matrix_debouncing[i];
189 } 218 }
219 debouncing = false;
190 } 220 }
191 } 221# endif
192 for (uint8_t y = 0; y < MATRIX_ROWS; y++) {
193 matrix_row_t row = 0;
194 for (uint8_t x = 0; x < MATRIX_COLS; x++) {
195 row |= ((matrix_reversed[x] & (1<<y)) >> y) << x;
196 }
197 matrix[y] = row;
198 }
199#endif
200 222
201 matrix_scan_quantum(); 223 matrix_scan_quantum();
202
203 return 1; 224 return 1;
204} 225}
205 226
206bool matrix_is_modified(void) 227bool matrix_is_modified(void)
207{ 228{
229#if (DEBOUNCING_DELAY > 0)
208 if (debouncing) return false; 230 if (debouncing) return false;
231#endif
209 return true; 232 return true;
210} 233}
211 234
@@ -218,15 +241,22 @@ bool matrix_is_on(uint8_t row, uint8_t col)
218inline 241inline
219matrix_row_t matrix_get_row(uint8_t row) 242matrix_row_t matrix_get_row(uint8_t row)
220{ 243{
244 // Matrix mask lets you disable switches in the returned matrix data. For example, if you have a
245 // switch blocker installed and the switch is always pressed.
246#ifdef MATRIX_MASKED
247 return matrix[row] & matrix_mask[row];
248#else
221 return matrix[row]; 249 return matrix[row];
250#endif
222} 251}
223 252
224void matrix_print(void) 253void matrix_print(void)
225{ 254{
226 print("\nr/c 0123456789ABCDEF\n"); 255 print_matrix_header();
256
227 for (uint8_t row = 0; row < MATRIX_ROWS; row++) { 257 for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
228 phex(row); print(": "); 258 phex(row); print(": ");
229 pbin_reverse16(matrix_get_row(row)); 259 print_matrix_row(row);
230 print("\n"); 260 print("\n");
231 } 261 }
232} 262}
@@ -235,63 +265,148 @@ uint8_t matrix_key_count(void)
235{ 265{
236 uint8_t count = 0; 266 uint8_t count = 0;
237 for (uint8_t i = 0; i < MATRIX_ROWS; i++) { 267 for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
238 count += bitpop16(matrix[i]); 268 count += matrix_bitpop(i);
239 } 269 }
240 return count; 270 return count;
241} 271}
242 272
273
274
275#if (DIODE_DIRECTION == COL2ROW)
276
243static void init_cols(void) 277static void init_cols(void)
244{ 278{
245#if DIODE_DIRECTION == COL2ROW 279 for(uint8_t x = 0; x < MATRIX_COLS; x++) {
246 for(int x = 0; x < MATRIX_COLS; x++) { 280 uint8_t pin = col_pins[x];
247 int pin = col_pins[x]; 281 _SFR_IO8((pin >> 4) + 1) &= ~_BV(pin & 0xF); // IN
248#else 282 _SFR_IO8((pin >> 4) + 2) |= _BV(pin & 0xF); // HI
249 for(int x = 0; x < MATRIX_ROWS; x++) {
250 int pin = row_pins[x];
251#endif
252 _SFR_IO8((pin >> 4) + 1) &= ~_BV(pin & 0xF);
253 _SFR_IO8((pin >> 4) + 2) |= _BV(pin & 0xF);
254 } 283 }
255} 284}
256 285
257static matrix_row_t read_cols(void) 286static bool read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row)
258{ 287{
259 matrix_row_t result = 0; 288 // Store last value of row prior to reading
289 matrix_row_t last_row_value = current_matrix[current_row];
260 290
261#if DIODE_DIRECTION == COL2ROW 291 // Clear data in matrix row
262 for(int x = 0; x < MATRIX_COLS; x++) { 292 current_matrix[current_row] = 0;
263 int pin = col_pins[x]; 293
264#else 294 // Select row and wait for row selecton to stabilize
265 for(int x = 0; x < MATRIX_ROWS; x++) { 295 select_row(current_row);
266 int pin = row_pins[x]; 296 wait_us(30);
267#endif 297
268 result |= (_SFR_IO8(pin >> 4) & _BV(pin & 0xF)) ? 0 : (SHIFTER << x); 298 // For each col...
299 for(uint8_t col_index = 0; col_index < MATRIX_COLS; col_index++) {
300
301 // Select the col pin to read (active low)
302 uint8_t pin = col_pins[col_index];
303 uint8_t pin_state = (_SFR_IO8(pin >> 4) & _BV(pin & 0xF));
304
305 // Populate the matrix row with the state of the col pin
306 current_matrix[current_row] |= pin_state ? 0 : (ROW_SHIFTER << col_index);
269 } 307 }
270 return result; 308
309 // Unselect row
310 unselect_row(current_row);
311
312 return (last_row_value != current_matrix[current_row]);
313}
314
315static void select_row(uint8_t row)
316{
317 uint8_t pin = row_pins[row];
318 _SFR_IO8((pin >> 4) + 1) |= _BV(pin & 0xF); // OUT
319 _SFR_IO8((pin >> 4) + 2) &= ~_BV(pin & 0xF); // LOW
320}
321
322static void unselect_row(uint8_t row)
323{
324 uint8_t pin = row_pins[row];
325 _SFR_IO8((pin >> 4) + 1) &= ~_BV(pin & 0xF); // IN
326 _SFR_IO8((pin >> 4) + 2) |= _BV(pin & 0xF); // HI
271} 327}
272 328
273static void unselect_rows(void) 329static void unselect_rows(void)
274{ 330{
275#if DIODE_DIRECTION == COL2ROW 331 for(uint8_t x = 0; x < MATRIX_ROWS; x++) {
276 for(int x = 0; x < MATRIX_ROWS; x++) { 332 uint8_t pin = row_pins[x];
277 int pin = row_pins[x]; 333 _SFR_IO8((pin >> 4) + 1) &= ~_BV(pin & 0xF); // IN
278#else 334 _SFR_IO8((pin >> 4) + 2) |= _BV(pin & 0xF); // HI
279 for(int x = 0; x < MATRIX_COLS; x++) {
280 int pin = col_pins[x];
281#endif
282 _SFR_IO8((pin >> 4) + 1) &= ~_BV(pin & 0xF);
283 _SFR_IO8((pin >> 4) + 2) |= _BV(pin & 0xF);
284 } 335 }
285} 336}
286 337
287static void select_row(uint8_t row) 338#elif (DIODE_DIRECTION == ROW2COL)
339
340static void init_rows(void)
288{ 341{
342 for(uint8_t x = 0; x < MATRIX_ROWS; x++) {
343 uint8_t pin = row_pins[x];
344 _SFR_IO8((pin >> 4) + 1) &= ~_BV(pin & 0xF); // IN
345 _SFR_IO8((pin >> 4) + 2) |= _BV(pin & 0xF); // HI
346 }
347}
289 348
290#if DIODE_DIRECTION == COL2ROW 349static bool read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col)
291 int pin = row_pins[row]; 350{
292#else 351 bool matrix_changed = false;
293 int pin = col_pins[row]; 352
294#endif 353 // Select col and wait for col selecton to stabilize
295 _SFR_IO8((pin >> 4) + 1) |= _BV(pin & 0xF); 354 select_col(current_col);
296 _SFR_IO8((pin >> 4) + 2) &= ~_BV(pin & 0xF); 355 wait_us(30);
356
357 // For each row...
358 for(uint8_t row_index = 0; row_index < MATRIX_ROWS; row_index++)
359 {
360
361 // Store last value of row prior to reading
362 matrix_row_t last_row_value = current_matrix[row_index];
363
364 // Check row pin state
365 if ((_SFR_IO8(row_pins[row_index] >> 4) & _BV(row_pins[row_index] & 0xF)) == 0)
366 {
367 // Pin LO, set col bit
368 current_matrix[row_index] |= (ROW_SHIFTER << current_col);
369 }
370 else
371 {
372 // Pin HI, clear col bit
373 current_matrix[row_index] &= ~(ROW_SHIFTER << current_col);
374 }
375
376 // Determine if the matrix changed state
377 if ((last_row_value != current_matrix[row_index]) && !(matrix_changed))
378 {
379 matrix_changed = true;
380 }
381 }
382
383 // Unselect col
384 unselect_col(current_col);
385
386 return matrix_changed;
297} 387}
388
389static void select_col(uint8_t col)
390{
391 uint8_t pin = col_pins[col];
392 _SFR_IO8((pin >> 4) + 1) |= _BV(pin & 0xF); // OUT
393 _SFR_IO8((pin >> 4) + 2) &= ~_BV(pin & 0xF); // LOW
394}
395
396static void unselect_col(uint8_t col)
397{
398 uint8_t pin = col_pins[col];
399 _SFR_IO8((pin >> 4) + 1) &= ~_BV(pin & 0xF); // IN
400 _SFR_IO8((pin >> 4) + 2) |= _BV(pin & 0xF); // HI
401}
402
403static void unselect_cols(void)
404{
405 for(uint8_t x = 0; x < MATRIX_COLS; x++) {
406 uint8_t pin = col_pins[x];
407 _SFR_IO8((pin >> 4) + 1) &= ~_BV(pin & 0xF); // IN
408 _SFR_IO8((pin >> 4) + 2) |= _BV(pin & 0xF); // HI
409 }
410}
411
412#endif
diff --git a/quantum/pincontrol.h b/quantum/pincontrol.h
new file mode 100644
index 000000000..d77977ebe
--- /dev/null
+++ b/quantum/pincontrol.h
@@ -0,0 +1,52 @@
1/* Copyright 2016 Wez Furlong
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#pragma once
17// Some helpers for controlling gpio pins
18#include <avr/io.h>
19
20enum {
21 PinDirectionInput = 0,
22 PinDirectionOutput = 1,
23 PinLevelHigh = 1,
24 PinLevelLow = 0,
25};
26
27// ex: pinMode(B0, PinDirectionOutput);
28static inline void pinMode(uint8_t pin, int mode) {
29 uint8_t bv = _BV(pin & 0xf);
30 if (mode == PinDirectionOutput) {
31 _SFR_IO8((pin >> 4) + 1) |= bv;
32 } else {
33 _SFR_IO8((pin >> 4) + 1) &= ~bv;
34 _SFR_IO8((pin >> 4) + 2) &= ~bv;
35 }
36}
37
38// ex: digitalWrite(B0, PinLevelHigh);
39static inline void digitalWrite(uint8_t pin, int mode) {
40 uint8_t bv = _BV(pin & 0xf);
41 if (mode == PinLevelHigh) {
42 _SFR_IO8((pin >> 4) + 2) |= bv;
43 } else {
44 _SFR_IO8((pin >> 4) + 2) &= ~bv;
45 }
46}
47
48// Return true if the pin is HIGH
49// digitalRead(B0)
50static inline bool digitalRead(uint8_t pin) {
51 return _SFR_IO8(pin >> 4) & _BV(pin & 0xf);
52}
diff --git a/quantum/process_keycode/process_audio.c b/quantum/process_keycode/process_audio.c
new file mode 100644
index 000000000..0b6380ed3
--- /dev/null
+++ b/quantum/process_keycode/process_audio.c
@@ -0,0 +1,62 @@
1#include "audio.h"
2#include "process_audio.h"
3
4static float compute_freq_for_midi_note(uint8_t note)
5{
6 // https://en.wikipedia.org/wiki/MIDI_tuning_standard
7 return pow(2.0, (note - 69) / 12.0) * 440.0f;
8}
9
10bool process_audio(uint16_t keycode, keyrecord_t *record) {
11
12 if (keycode == AU_ON && record->event.pressed) {
13 audio_on();
14 return false;
15 }
16
17 if (keycode == AU_OFF && record->event.pressed) {
18 audio_off();
19 return false;
20 }
21
22 if (keycode == AU_TOG && record->event.pressed) {
23 if (is_audio_on())
24 {
25 audio_off();
26 }
27 else
28 {
29 audio_on();
30 }
31 return false;
32 }
33
34 if (keycode == MUV_IN && record->event.pressed) {
35 voice_iterate();
36 music_scale_user();
37 return false;
38 }
39
40 if (keycode == MUV_DE && record->event.pressed) {
41 voice_deiterate();
42 music_scale_user();
43 return false;
44 }
45
46 return true;
47}
48
49void process_audio_noteon(uint8_t note) {
50 play_note(compute_freq_for_midi_note(note), 0xF);
51}
52
53void process_audio_noteoff(uint8_t note) {
54 stop_note(compute_freq_for_midi_note(note));
55}
56
57void process_audio_all_notes_off(void) {
58 stop_all_notes();
59}
60
61__attribute__ ((weak))
62void audio_on_user() {} \ No newline at end of file
diff --git a/quantum/process_keycode/process_audio.h b/quantum/process_keycode/process_audio.h
new file mode 100644
index 000000000..7ac15b733
--- /dev/null
+++ b/quantum/process_keycode/process_audio.h
@@ -0,0 +1,11 @@
1#ifndef PROCESS_AUDIO_H
2#define PROCESS_AUDIO_H
3
4bool process_audio(uint16_t keycode, keyrecord_t *record);
5void process_audio_noteon(uint8_t note);
6void process_audio_noteoff(uint8_t note);
7void process_audio_all_notes_off(void);
8
9void audio_on_user(void);
10
11#endif \ No newline at end of file
diff --git a/quantum/process_keycode/process_chording.c b/quantum/process_keycode/process_chording.c
index d7814629f..6c6ebe300 100644
--- a/quantum/process_keycode/process_chording.c
+++ b/quantum/process_keycode/process_chording.c
@@ -1,3 +1,19 @@
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
1#include "process_chording.h" 17#include "process_chording.h"
2 18
3bool keys_chord(uint8_t keys[]) { 19bool keys_chord(uint8_t keys[]) {
@@ -57,4 +73,4 @@ bool process_chording(uint16_t keycode, keyrecord_t *record) {
57 } 73 }
58 } 74 }
59 return true; 75 return true;
60} \ No newline at end of file 76}
diff --git a/quantum/process_keycode/process_chording.h b/quantum/process_keycode/process_chording.h
index 49c97db3b..8c0f4862a 100644
--- a/quantum/process_keycode/process_chording.h
+++ b/quantum/process_keycode/process_chording.h
@@ -1,3 +1,19 @@
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
1#ifndef PROCESS_CHORDING_H 17#ifndef PROCESS_CHORDING_H
2#define PROCESS_CHORDING_H 18#define PROCESS_CHORDING_H
3 19
@@ -13,4 +29,4 @@ uint8_t chord_key_down = 0;
13 29
14bool process_chording(uint16_t keycode, keyrecord_t *record); 30bool process_chording(uint16_t keycode, keyrecord_t *record);
15 31
16#endif \ No newline at end of file 32#endif
diff --git a/quantum/process_keycode/process_combo.c b/quantum/process_keycode/process_combo.c
new file mode 100644
index 000000000..58d45add2
--- /dev/null
+++ b/quantum/process_keycode/process_combo.c
@@ -0,0 +1,150 @@
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
17#include "process_combo.h"
18#include "print.h"
19
20
21#define COMBO_TIMER_ELAPSED -1
22
23
24__attribute__ ((weak))
25combo_t key_combos[] = {
26
27};
28
29__attribute__ ((weak))
30void process_combo_event(uint8_t combo_index, bool pressed) {
31
32}
33
34static uint8_t current_combo_index = 0;
35
36static inline void send_combo(uint16_t action, bool pressed)
37{
38 if (action) {
39 if (pressed) {
40 register_code16(action);
41 } else {
42 unregister_code16(action);
43 }
44 } else {
45 process_combo_event(current_combo_index, pressed);
46 }
47}
48
49#define ALL_COMBO_KEYS_ARE_DOWN (((1<<count)-1) == combo->state)
50#define NO_COMBO_KEYS_ARE_DOWN (0 == combo->state)
51#define KEY_STATE_DOWN(key) do{ combo->state |= (1<<key); } while(0)
52#define KEY_STATE_UP(key) do{ combo->state &= ~(1<<key); } while(0)
53static bool process_single_combo(combo_t *combo, uint16_t keycode, keyrecord_t *record)
54{
55 uint8_t count = 0;
56 uint8_t index = -1;
57 /* Find index of keycode and number of combo keys */
58 for (const uint16_t *keys = combo->keys; ;++count) {
59 uint16_t key = pgm_read_word(&keys[count]);
60 if (keycode == key) index = count;
61 if (COMBO_END == key) break;
62 }
63
64 /* Return if not a combo key */
65 if (-1 == (int8_t)index) return false;
66
67 /* The combos timer is used to signal whether the combo is active */
68 bool is_combo_active = COMBO_TIMER_ELAPSED == combo->timer ? false : true;
69
70 if (record->event.pressed) {
71 KEY_STATE_DOWN(index);
72
73 if (is_combo_active) {
74 if (ALL_COMBO_KEYS_ARE_DOWN) { /* Combo was pressed */
75 send_combo(combo->keycode, true);
76 combo->timer = COMBO_TIMER_ELAPSED;
77 } else { /* Combo key was pressed */
78 combo->timer = timer_read();
79#ifdef COMBO_ALLOW_ACTION_KEYS
80 combo->prev_record = *record;
81#else
82 combo->prev_key = keycode;
83#endif
84 }
85 }
86 } else {
87 if (ALL_COMBO_KEYS_ARE_DOWN) { /* Combo was released */
88 send_combo(combo->keycode, false);
89 }
90
91 if (is_combo_active) { /* Combo key was tapped */
92#ifdef COMBO_ALLOW_ACTION_KEYS
93 record->event.pressed = true;
94 process_action(record, store_or_get_action(record->event.pressed, record->event.key));
95 record->event.pressed = false;
96 process_action(record, store_or_get_action(record->event.pressed, record->event.key));
97#else
98 register_code16(keycode);
99 send_keyboard_report();
100 unregister_code16(keycode);
101#endif
102 combo->timer = 0;
103 }
104
105 KEY_STATE_UP(index);
106 }
107
108 if (NO_COMBO_KEYS_ARE_DOWN) {
109 combo->timer = 0;
110 }
111
112 return is_combo_active;
113}
114
115bool process_combo(uint16_t keycode, keyrecord_t *record)
116{
117 bool is_combo_key = false;
118
119 for (current_combo_index = 0; current_combo_index < COMBO_COUNT; ++current_combo_index) {
120 combo_t *combo = &key_combos[current_combo_index];
121 is_combo_key |= process_single_combo(combo, keycode, record);
122 }
123
124 return !is_combo_key;
125}
126
127void matrix_scan_combo(void)
128{
129 for (int i = 0; i < COMBO_COUNT; ++i) {
130 combo_t *combo = &key_combos[i];
131 if (combo->timer &&
132 combo->timer != COMBO_TIMER_ELAPSED &&
133 timer_elapsed(combo->timer) > COMBO_TERM) {
134
135 /* This disables the combo, meaning key events for this
136 * combo will be handled by the next processors in the chain
137 */
138 combo->timer = COMBO_TIMER_ELAPSED;
139
140#ifdef COMBO_ALLOW_ACTION_KEYS
141 process_action(&combo->prev_record,
142 store_or_get_action(combo->prev_record.event.pressed,
143 combo->prev_record.event.key));
144#else
145 unregister_code16(combo->prev_key);
146 register_code16(combo->prev_key);
147#endif
148 }
149 }
150}
diff --git a/quantum/process_keycode/process_combo.h b/quantum/process_keycode/process_combo.h
new file mode 100644
index 000000000..a5dbd788a
--- /dev/null
+++ b/quantum/process_keycode/process_combo.h
@@ -0,0 +1,59 @@
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
17#ifndef PROCESS_COMBO_H
18#define PROCESS_COMBO_H
19
20#include <stdint.h>
21#include "progmem.h"
22#include "quantum.h"
23
24typedef struct
25{
26 const uint16_t *keys;
27 uint16_t keycode;
28#ifdef EXTRA_EXTRA_LONG_COMBOS
29 uint32_t state;
30#elif EXTRA_LONG_COMBOS
31 uint16_t state;
32#else
33 uint8_t state;
34#endif
35 uint16_t timer;
36#ifdef COMBO_ALLOW_ACTION_KEYS
37 keyrecord_t prev_record;
38#else
39 uint16_t prev_key;
40#endif
41} combo_t;
42
43
44#define COMBO(ck, ca) {.keys = &(ck)[0], .keycode = (ca)}
45#define COMBO_ACTION(ck) {.keys = &(ck)[0]}
46
47#define COMBO_END 0
48#ifndef COMBO_COUNT
49#define COMBO_COUNT 0
50#endif
51#ifndef COMBO_TERM
52#define COMBO_TERM TAPPING_TERM
53#endif
54
55bool process_combo(uint16_t keycode, keyrecord_t *record);
56void matrix_scan_combo(void);
57void process_combo_event(uint8_t combo_index, bool pressed);
58
59#endif
diff --git a/quantum/process_keycode/process_leader.c b/quantum/process_keycode/process_leader.c
index e53d221e7..473906d65 100644
--- a/quantum/process_keycode/process_leader.c
+++ b/quantum/process_keycode/process_leader.c
@@ -1,3 +1,19 @@
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
1#include "process_leader.h" 17#include "process_leader.h"
2 18
3__attribute__ ((weak)) 19__attribute__ ((weak))
@@ -35,4 +51,4 @@ bool process_leader(uint16_t keycode, keyrecord_t *record) {
35 } 51 }
36 } 52 }
37 return true; 53 return true;
38} \ No newline at end of file 54}
diff --git a/quantum/process_keycode/process_leader.h b/quantum/process_keycode/process_leader.h
index c83db8abb..da7a3d2ef 100644
--- a/quantum/process_keycode/process_leader.h
+++ b/quantum/process_keycode/process_leader.h
@@ -1,3 +1,19 @@
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
1#ifndef PROCESS_LEADER_H 17#ifndef PROCESS_LEADER_H
2#define PROCESS_LEADER_H 18#define PROCESS_LEADER_H
3 19
@@ -20,4 +36,4 @@ void leader_end(void);
20#define LEADER_EXTERNS() extern bool leading; extern uint16_t leader_time; extern uint16_t leader_sequence[5]; extern uint8_t leader_sequence_size 36#define LEADER_EXTERNS() extern bool leading; extern uint16_t leader_time; extern uint16_t leader_sequence[5]; extern uint8_t leader_sequence_size
21#define LEADER_DICTIONARY() if (leading && timer_elapsed(leader_time) > LEADER_TIMEOUT) 37#define LEADER_DICTIONARY() if (leading && timer_elapsed(leader_time) > LEADER_TIMEOUT)
22 38
23#endif \ No newline at end of file 39#endif
diff --git a/quantum/process_keycode/process_midi.c b/quantum/process_keycode/process_midi.c
index 577dad43a..9184feaae 100644
--- a/quantum/process_keycode/process_midi.c
+++ b/quantum/process_keycode/process_midi.c
@@ -1,68 +1,253 @@
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 */
1#include "process_midi.h" 16#include "process_midi.h"
2 17
3bool midi_activated = false; 18#ifdef MIDI_ENABLE
4uint8_t midi_starting_note = 0x0C; 19#include "midi.h"
5int midi_offset = 7; 20
6 21#ifdef MIDI_BASIC
7bool process_midi(uint16_t keycode, keyrecord_t *record) { 22
8 if (keycode == MI_ON && record->event.pressed) { 23void process_midi_basic_noteon(uint8_t note)
9 midi_activated = true; 24{
10#ifdef AUDIO_ENABLE 25 midi_send_noteon(&midi_device, 0, note, 128);
11 music_scale_user(); 26}
12#endif 27
13 return false; 28void process_midi_basic_noteoff(uint8_t note)
14 } 29{
30 midi_send_noteoff(&midi_device, 0, note, 0);
31}
32
33void process_midi_all_notes_off(void)
34{
35 midi_send_cc(&midi_device, 0, 0x7B, 0);
36}
37
38#endif // MIDI_BASIC
39
40#ifdef MIDI_ADVANCED
41
42#include "timer.h"
43
44static uint8_t tone_status[MIDI_TONE_COUNT];
45
46static uint8_t midi_modulation;
47static int8_t midi_modulation_step;
48static uint16_t midi_modulation_timer;
49
50inline uint8_t compute_velocity(uint8_t setting)
51{
52 return (setting + 1) * (128 / (MIDI_VELOCITY_MAX - MIDI_VELOCITY_MIN + 1));
53}
15 54
16 if (keycode == MI_OFF && record->event.pressed) { 55void midi_init(void)
17 midi_activated = false; 56{
18 midi_send_cc(&midi_device, 0, 0x7B, 0); 57 midi_config.octave = MI_OCT_2 - MIDI_OCTAVE_MIN;
19 return false; 58 midi_config.transpose = 0;
59 midi_config.velocity = (MIDI_VELOCITY_MAX - MIDI_VELOCITY_MIN);
60 midi_config.channel = 0;
61 midi_config.modulation_interval = 8;
62
63 for (uint8_t i = 0; i < MIDI_TONE_COUNT; i++)
64 {
65 tone_status[i] = MIDI_INVALID_NOTE;
20 } 66 }
21 67
22 if (midi_activated) { 68 midi_modulation = 0;
23 if (record->event.key.col == (MATRIX_COLS - 1) && record->event.key.row == (MATRIX_ROWS - 1)) { 69 midi_modulation_step = 0;
24 if (record->event.pressed) { 70 midi_modulation_timer = 0;
25 midi_starting_note++; // Change key 71}
26 midi_send_cc(&midi_device, 0, 0x7B, 0); 72
27 } 73void midi_task(void)
28 return false; 74{
29 } 75 if (timer_elapsed(midi_modulation_timer) < midi_config.modulation_interval)
30 if (record->event.key.col == (MATRIX_COLS - 2) && record->event.key.row == (MATRIX_ROWS - 1)) { 76 return;
31 if (record->event.pressed) { 77 midi_modulation_timer = timer_read();
32 midi_starting_note--; // Change key 78
33 midi_send_cc(&midi_device, 0, 0x7B, 0); 79 if (midi_modulation_step != 0)
34 } 80 {
35 return false; 81 dprintf("midi modulation %d\n", midi_modulation);
36 } 82 midi_send_cc(&midi_device, midi_config.channel, 0x1, midi_modulation);
37 if (record->event.key.col == (MATRIX_COLS - 3) && record->event.key.row == (MATRIX_ROWS - 1) && record->event.pressed) { 83
38 midi_offset++; // Change scale 84 if (midi_modulation_step < 0 && midi_modulation < -midi_modulation_step) {
39 midi_send_cc(&midi_device, 0, 0x7B, 0); 85 midi_modulation = 0;
40 return false; 86 midi_modulation_step = 0;
41 } 87 return;
42 if (record->event.key.col == (MATRIX_COLS - 4) && record->event.key.row == (MATRIX_ROWS - 1) && record->event.pressed) { 88 }
43 midi_offset--; // Change scale 89
44 midi_send_cc(&midi_device, 0, 0x7B, 0); 90 midi_modulation += midi_modulation_step;
45 return false; 91
46 } 92 if (midi_modulation > 127)
47 // basic 93 midi_modulation = 127;
48 // uint8_t note = (midi_starting_note + SCALE[record->event.key.col + midi_offset])+12*(MATRIX_ROWS - record->event.key.row);
49 // advanced
50 // uint8_t note = (midi_starting_note + record->event.key.col + midi_offset)+12*(MATRIX_ROWS - record->event.key.row);
51 // guitar
52 uint8_t note = (midi_starting_note + record->event.key.col + midi_offset)+5*(MATRIX_ROWS - record->event.key.row);
53 // violin
54 // uint8_t note = (midi_starting_note + record->event.key.col + midi_offset)+7*(MATRIX_ROWS - record->event.key.row);
55
56 if (record->event.pressed) {
57 // midi_send_noteon(&midi_device, record->event.key.row, midi_starting_note + SCALE[record->event.key.col], 127);
58 midi_send_noteon(&midi_device, 0, note, 127);
59 } else {
60 // midi_send_noteoff(&midi_device, record->event.key.row, midi_starting_note + SCALE[record->event.key.col], 127);
61 midi_send_noteoff(&midi_device, 0, note, 127);
62 }
63
64 if (keycode < 0xFF) // ignores all normal keycodes, but lets RAISE, LOWER, etc through
65 return false;
66 } 94 }
67 return true;
68} 95}
96
97uint8_t midi_compute_note(uint16_t keycode)
98{
99 return 12 * midi_config.octave + (keycode - MIDI_TONE_MIN) + midi_config.transpose;
100}
101
102bool process_midi(uint16_t keycode, keyrecord_t *record)
103{
104 switch (keycode) {
105 case MIDI_TONE_MIN ... MIDI_TONE_MAX:
106 {
107 uint8_t channel = midi_config.channel;
108 uint8_t tone = keycode - MIDI_TONE_MIN;
109 uint8_t velocity = compute_velocity(midi_config.velocity);
110 if (record->event.pressed) {
111 uint8_t note = midi_compute_note(keycode);
112 midi_send_noteon(&midi_device, channel, note, velocity);
113 dprintf("midi noteon channel:%d note:%d velocity:%d\n", channel, note, velocity);
114 tone_status[tone] = note;
115 }
116 else {
117 uint8_t note = tone_status[tone];
118 if (note != MIDI_INVALID_NOTE)
119 {
120 midi_send_noteoff(&midi_device, channel, note, velocity);
121 dprintf("midi noteoff channel:%d note:%d velocity:%d\n", channel, note, velocity);
122 }
123 tone_status[tone] = MIDI_INVALID_NOTE;
124 }
125 return false;
126 }
127 case MIDI_OCTAVE_MIN ... MIDI_OCTAVE_MAX:
128 if (record->event.pressed) {
129 midi_config.octave = keycode - MIDI_OCTAVE_MIN;
130 dprintf("midi octave %d\n", midi_config.octave);
131 }
132 return false;
133 case MI_OCTD:
134 if (record->event.pressed && midi_config.octave > 0) {
135 midi_config.octave--;
136 dprintf("midi octave %d\n", midi_config.octave);
137 }
138 return false;
139 case MI_OCTU:
140 if (record->event.pressed && midi_config.octave < (MIDI_OCTAVE_MAX - MIDI_OCTAVE_MIN)) {
141 midi_config.octave++;
142 dprintf("midi octave %d\n", midi_config.octave);
143 }
144 return false;
145 case MIDI_TRANSPOSE_MIN ... MIDI_TRANSPOSE_MAX:
146 if (record->event.pressed) {
147 midi_config.transpose = keycode - MI_TRNS_0;
148 dprintf("midi transpose %d\n", midi_config.transpose);
149 }
150 return false;
151 case MI_TRNSD:
152 if (record->event.pressed && midi_config.transpose > (MIDI_TRANSPOSE_MIN - MI_TRNS_0)) {
153 midi_config.transpose--;
154 dprintf("midi transpose %d\n", midi_config.transpose);
155 }
156 return false;
157 case MI_TRNSU:
158 if (record->event.pressed && midi_config.transpose < (MIDI_TRANSPOSE_MAX - MI_TRNS_0)) {
159 const bool positive = midi_config.transpose > 0;
160 midi_config.transpose++;
161 if (positive && midi_config.transpose < 0)
162 midi_config.transpose--;
163 dprintf("midi transpose %d\n", midi_config.transpose);
164 }
165 return false;
166 case MIDI_VELOCITY_MIN ... MIDI_VELOCITY_MAX:
167 if (record->event.pressed) {
168 midi_config.velocity = keycode - MIDI_VELOCITY_MIN;
169 dprintf("midi velocity %d\n", midi_config.velocity);
170 }
171 return false;
172 case MI_VELD:
173 if (record->event.pressed && midi_config.velocity > 0) {
174 midi_config.velocity--;
175 dprintf("midi velocity %d\n", midi_config.velocity);
176 }
177 return false;
178 case MI_VELU:
179 if (record->event.pressed) {
180 midi_config.velocity++;
181 dprintf("midi velocity %d\n", midi_config.velocity);
182 }
183 return false;
184 case MIDI_CHANNEL_MIN ... MIDI_CHANNEL_MAX:
185 if (record->event.pressed) {
186 midi_config.channel = keycode - MIDI_CHANNEL_MIN;
187 dprintf("midi channel %d\n", midi_config.channel);
188 }
189 return false;
190 case MI_CHD:
191 if (record->event.pressed) {
192 midi_config.channel--;
193 dprintf("midi channel %d\n", midi_config.channel);
194 }
195 return false;
196 case MI_CHU:
197 if (record->event.pressed) {
198 midi_config.channel++;
199 dprintf("midi channel %d\n", midi_config.channel);
200 }
201 return false;
202 case MI_ALLOFF:
203 if (record->event.pressed) {
204 midi_send_cc(&midi_device, midi_config.channel, 0x7B, 0);
205 dprintf("midi all notes off\n");
206 }
207 return false;
208 case MI_SUS:
209 midi_send_cc(&midi_device, midi_config.channel, 0x40, record->event.pressed ? 127 : 0);
210 dprintf("midi sustain %d\n", record->event.pressed);
211 return false;
212 case MI_PORT:
213 midi_send_cc(&midi_device, midi_config.channel, 0x41, record->event.pressed ? 127 : 0);
214 dprintf("midi portamento %d\n", record->event.pressed);
215 return false;
216 case MI_SOST:
217 midi_send_cc(&midi_device, midi_config.channel, 0x42, record->event.pressed ? 127 : 0);
218 dprintf("midi sostenuto %d\n", record->event.pressed);
219 return false;
220 case MI_SOFT:
221 midi_send_cc(&midi_device, midi_config.channel, 0x43, record->event.pressed ? 127 : 0);
222 dprintf("midi soft %d\n", record->event.pressed);
223 return false;
224 case MI_LEG:
225 midi_send_cc(&midi_device, midi_config.channel, 0x43, record->event.pressed ? 127 : 0);
226 dprintf("midi legato %d\n", record->event.pressed);
227 return false;
228 case MI_MOD:
229 midi_modulation_step = record->event.pressed ? 1 : -1;
230 return false;
231 case MI_MODSD:
232 if (record->event.pressed) {
233 midi_config.modulation_interval++;
234 // prevent overflow
235 if (midi_config.modulation_interval == 0)
236 midi_config.modulation_interval--;
237 dprintf("midi modulation interval %d\n", midi_config.modulation_interval);
238 }
239 return false;
240 case MI_MODSU:
241 if (record->event.pressed && midi_config.modulation_interval > 0) {
242 midi_config.modulation_interval--;
243 dprintf("midi modulation interval %d\n", midi_config.modulation_interval);
244 }
245 return false;
246 };
247
248 return true;
249}
250
251#endif // MIDI_ADVANCED
252
253#endif // MIDI_ENABLE
diff --git a/quantum/process_keycode/process_midi.h b/quantum/process_keycode/process_midi.h
index acd4fc1b1..ccac8981a 100644
--- a/quantum/process_keycode/process_midi.h
+++ b/quantum/process_keycode/process_midi.h
@@ -1,207 +1,56 @@
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
1#ifndef PROCESS_MIDI_H 17#ifndef PROCESS_MIDI_H
2#define PROCESS_MIDI_H 18#define PROCESS_MIDI_H
3 19
4#include "quantum.h" 20#include "quantum.h"
5 21
6bool process_midi(uint16_t keycode, keyrecord_t *record); 22#ifdef MIDI_ENABLE
23
24#ifdef MIDI_BASIC
25void process_midi_basic_noteon(uint8_t note);
26void process_midi_basic_noteoff(uint8_t note);
27void process_midi_all_notes_off(void);
28#endif
7 29
8#define MIDI(n) ((n) | 0x6000) 30#ifdef MIDI_ADVANCED
9#define MIDI12 0x6000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6000 31typedef union {
32 uint32_t raw;
33 struct {
34 uint8_t octave :4;
35 int8_t transpose :4;
36 uint8_t velocity :4;
37 uint8_t channel :4;
38 uint8_t modulation_interval :4;
39 };
40} midi_config_t;
41
42midi_config_t midi_config;
43
44void midi_init(void);
45void midi_task(void);
46bool process_midi(uint16_t keycode, keyrecord_t *record);
10 47
11#define CHNL(note, channel) (note + (channel << 8)) 48#define MIDI_INVALID_NOTE 0xFF
49#define MIDI_TONE_COUNT (MIDI_TONE_MAX - MIDI_TONE_MIN + 1)
12 50
13#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), \ 51uint8_t midi_compute_note(uint16_t keycode);
14 0 + (12*1), 2 + (12*1), 4 + (12*1), 5 + (12*1), 7 + (12*1), 9 + (12*1), 11 + (12*1), \ 52#endif // MIDI_ADVANCED
15 0 + (12*2), 2 + (12*2), 4 + (12*2), 5 + (12*2), 7 + (12*2), 9 + (12*2), 11 + (12*2), \
16 0 + (12*3), 2 + (12*3), 4 + (12*3), 5 + (12*3), 7 + (12*3), 9 + (12*3), 11 + (12*3), \
17 0 + (12*4), 2 + (12*4), 4 + (12*4), 5 + (12*4), 7 + (12*4), 9 + (12*4), 11 + (12*4), }
18 53
19#define N_CN1 (0x600C + (12 * -1) + 0 ) 54#endif // MIDI_ENABLE
20#define N_CN1S (0x600C + (12 * -1) + 1 )
21#define N_DN1F (0x600C + (12 * -1) + 1 )
22#define N_DN1 (0x600C + (12 * -1) + 2 )
23#define N_DN1S (0x600C + (12 * -1) + 3 )
24#define N_EN1F (0x600C + (12 * -1) + 3 )
25#define N_EN1 (0x600C + (12 * -1) + 4 )
26#define N_FN1 (0x600C + (12 * -1) + 5 )
27#define N_FN1S (0x600C + (12 * -1) + 6 )
28#define N_GN1F (0x600C + (12 * -1) + 6 )
29#define N_GN1 (0x600C + (12 * -1) + 7 )
30#define N_GN1S (0x600C + (12 * -1) + 8 )
31#define N_AN1F (0x600C + (12 * -1) + 8 )
32#define N_AN1 (0x600C + (12 * -1) + 9 )
33#define N_AN1S (0x600C + (12 * -1) + 10)
34#define N_BN1F (0x600C + (12 * -1) + 10)
35#define N_BN1 (0x600C + (12 * -1) + 11)
36#define N_C0 (0x600C + (12 * 0) + 0 )
37#define N_C0S (0x600C + (12 * 0) + 1 )
38#define N_D0F (0x600C + (12 * 0) + 1 )
39#define N_D0 (0x600C + (12 * 0) + 2 )
40#define N_D0S (0x600C + (12 * 0) + 3 )
41#define N_E0F (0x600C + (12 * 0) + 3 )
42#define N_E0 (0x600C + (12 * 0) + 4 )
43#define N_F0 (0x600C + (12 * 0) + 5 )
44#define N_F0S (0x600C + (12 * 0) + 6 )
45#define N_G0F (0x600C + (12 * 0) + 6 )
46#define N_G0 (0x600C + (12 * 0) + 7 )
47#define N_G0S (0x600C + (12 * 0) + 8 )
48#define N_A0F (0x600C + (12 * 0) + 8 )
49#define N_A0 (0x600C + (12 * 0) + 9 )
50#define N_A0S (0x600C + (12 * 0) + 10)
51#define N_B0F (0x600C + (12 * 0) + 10)
52#define N_B0 (0x600C + (12 * 0) + 11)
53#define N_C1 (0x600C + (12 * 1) + 0 )
54#define N_C1S (0x600C + (12 * 1) + 1 )
55#define N_D1F (0x600C + (12 * 1) + 1 )
56#define N_D1 (0x600C + (12 * 1) + 2 )
57#define N_D1S (0x600C + (12 * 1) + 3 )
58#define N_E1F (0x600C + (12 * 1) + 3 )
59#define N_E1 (0x600C + (12 * 1) + 4 )
60#define N_F1 (0x600C + (12 * 1) + 5 )
61#define N_F1S (0x600C + (12 * 1) + 6 )
62#define N_G1F (0x600C + (12 * 1) + 6 )
63#define N_G1 (0x600C + (12 * 1) + 7 )
64#define N_G1S (0x600C + (12 * 1) + 8 )
65#define N_A1F (0x600C + (12 * 1) + 8 )
66#define N_A1 (0x600C + (12 * 1) + 9 )
67#define N_A1S (0x600C + (12 * 1) + 10)
68#define N_B1F (0x600C + (12 * 1) + 10)
69#define N_B1 (0x600C + (12 * 1) + 11)
70#define N_C2 (0x600C + (12 * 2) + 0 )
71#define N_C2S (0x600C + (12 * 2) + 1 )
72#define N_D2F (0x600C + (12 * 2) + 1 )
73#define N_D2 (0x600C + (12 * 2) + 2 )
74#define N_D2S (0x600C + (12 * 2) + 3 )
75#define N_E2F (0x600C + (12 * 2) + 3 )
76#define N_E2 (0x600C + (12 * 2) + 4 )
77#define N_F2 (0x600C + (12 * 2) + 5 )
78#define N_F2S (0x600C + (12 * 2) + 6 )
79#define N_G2F (0x600C + (12 * 2) + 6 )
80#define N_G2 (0x600C + (12 * 2) + 7 )
81#define N_G2S (0x600C + (12 * 2) + 8 )
82#define N_A2F (0x600C + (12 * 2) + 8 )
83#define N_A2 (0x600C + (12 * 2) + 9 )
84#define N_A2S (0x600C + (12 * 2) + 10)
85#define N_B2F (0x600C + (12 * 2) + 10)
86#define N_B2 (0x600C + (12 * 2) + 11)
87#define N_C3 (0x600C + (12 * 3) + 0 )
88#define N_C3S (0x600C + (12 * 3) + 1 )
89#define N_D3F (0x600C + (12 * 3) + 1 )
90#define N_D3 (0x600C + (12 * 3) + 2 )
91#define N_D3S (0x600C + (12 * 3) + 3 )
92#define N_E3F (0x600C + (12 * 3) + 3 )
93#define N_E3 (0x600C + (12 * 3) + 4 )
94#define N_F3 (0x600C + (12 * 3) + 5 )
95#define N_F3S (0x600C + (12 * 3) + 6 )
96#define N_G3F (0x600C + (12 * 3) + 6 )
97#define N_G3 (0x600C + (12 * 3) + 7 )
98#define N_G3S (0x600C + (12 * 3) + 8 )
99#define N_A3F (0x600C + (12 * 3) + 8 )
100#define N_A3 (0x600C + (12 * 3) + 9 )
101#define N_A3S (0x600C + (12 * 3) + 10)
102#define N_B3F (0x600C + (12 * 3) + 10)
103#define N_B3 (0x600C + (12 * 3) + 11)
104#define N_C4 (0x600C + (12 * 4) + 0 )
105#define N_C4S (0x600C + (12 * 4) + 1 )
106#define N_D4F (0x600C + (12 * 4) + 1 )
107#define N_D4 (0x600C + (12 * 4) + 2 )
108#define N_D4S (0x600C + (12 * 4) + 3 )
109#define N_E4F (0x600C + (12 * 4) + 3 )
110#define N_E4 (0x600C + (12 * 4) + 4 )
111#define N_F4 (0x600C + (12 * 4) + 5 )
112#define N_F4S (0x600C + (12 * 4) + 6 )
113#define N_G4F (0x600C + (12 * 4) + 6 )
114#define N_G4 (0x600C + (12 * 4) + 7 )
115#define N_G4S (0x600C + (12 * 4) + 8 )
116#define N_A4F (0x600C + (12 * 4) + 8 )
117#define N_A4 (0x600C + (12 * 4) + 9 )
118#define N_A4S (0x600C + (12 * 4) + 10)
119#define N_B4F (0x600C + (12 * 4) + 10)
120#define N_B4 (0x600C + (12 * 4) + 11)
121#define N_C5 (0x600C + (12 * 5) + 0 )
122#define N_C5S (0x600C + (12 * 5) + 1 )
123#define N_D5F (0x600C + (12 * 5) + 1 )
124#define N_D5 (0x600C + (12 * 5) + 2 )
125#define N_D5S (0x600C + (12 * 5) + 3 )
126#define N_E5F (0x600C + (12 * 5) + 3 )
127#define N_E5 (0x600C + (12 * 5) + 4 )
128#define N_F5 (0x600C + (12 * 5) + 5 )
129#define N_F5S (0x600C + (12 * 5) + 6 )
130#define N_G5F (0x600C + (12 * 5) + 6 )
131#define N_G5 (0x600C + (12 * 5) + 7 )
132#define N_G5S (0x600C + (12 * 5) + 8 )
133#define N_A5F (0x600C + (12 * 5) + 8 )
134#define N_A5 (0x600C + (12 * 5) + 9 )
135#define N_A5S (0x600C + (12 * 5) + 10)
136#define N_B5F (0x600C + (12 * 5) + 10)
137#define N_B5 (0x600C + (12 * 5) + 11)
138#define N_C6 (0x600C + (12 * 6) + 0 )
139#define N_C6S (0x600C + (12 * 6) + 1 )
140#define N_D6F (0x600C + (12 * 6) + 1 )
141#define N_D6 (0x600C + (12 * 6) + 2 )
142#define N_D6S (0x600C + (12 * 6) + 3 )
143#define N_E6F (0x600C + (12 * 6) + 3 )
144#define N_E6 (0x600C + (12 * 6) + 4 )
145#define N_F6 (0x600C + (12 * 6) + 5 )
146#define N_F6S (0x600C + (12 * 6) + 6 )
147#define N_G6F (0x600C + (12 * 6) + 6 )
148#define N_G6 (0x600C + (12 * 6) + 7 )
149#define N_G6S (0x600C + (12 * 6) + 8 )
150#define N_A6F (0x600C + (12 * 6) + 8 )
151#define N_A6 (0x600C + (12 * 6) + 9 )
152#define N_A6S (0x600C + (12 * 6) + 10)
153#define N_B6F (0x600C + (12 * 6) + 10)
154#define N_B6 (0x600C + (12 * 6) + 11)
155#define N_C7 (0x600C + (12 * 7) + 0 )
156#define N_C7S (0x600C + (12 * 7) + 1 )
157#define N_D7F (0x600C + (12 * 7) + 1 )
158#define N_D7 (0x600C + (12 * 7) + 2 )
159#define N_D7S (0x600C + (12 * 7) + 3 )
160#define N_E7F (0x600C + (12 * 7) + 3 )
161#define N_E7 (0x600C + (12 * 7) + 4 )
162#define N_F7 (0x600C + (12 * 7) + 5 )
163#define N_F7S (0x600C + (12 * 7) + 6 )
164#define N_G7F (0x600C + (12 * 7) + 6 )
165#define N_G7 (0x600C + (12 * 7) + 7 )
166#define N_G7S (0x600C + (12 * 7) + 8 )
167#define N_A7F (0x600C + (12 * 7) + 8 )
168#define N_A7 (0x600C + (12 * 7) + 9 )
169#define N_A7S (0x600C + (12 * 7) + 10)
170#define N_B7F (0x600C + (12 * 7) + 10)
171#define N_B7 (0x600C + (12 * 7) + 11)
172#define N_C8 (0x600C + (12 * 8) + 0 )
173#define N_C8S (0x600C + (12 * 8) + 1 )
174#define N_D8F (0x600C + (12 * 8) + 1 )
175#define N_D8 (0x600C + (12 * 8) + 2 )
176#define N_D8S (0x600C + (12 * 8) + 3 )
177#define N_E8F (0x600C + (12 * 8) + 3 )
178#define N_E8 (0x600C + (12 * 8) + 4 )
179#define N_F8 (0x600C + (12 * 8) + 5 )
180#define N_F8S (0x600C + (12 * 8) + 6 )
181#define N_G8F (0x600C + (12 * 8) + 6 )
182#define N_G8 (0x600C + (12 * 8) + 7 )
183#define N_G8S (0x600C + (12 * 8) + 8 )
184#define N_A8F (0x600C + (12 * 8) + 8 )
185#define N_A8 (0x600C + (12 * 8) + 9 )
186#define N_A8S (0x600C + (12 * 8) + 10)
187#define N_B8F (0x600C + (12 * 8) + 10)
188#define N_B8 (0x600C + (12 * 8) + 11)
189#define N_C8 (0x600C + (12 * 8) + 0 )
190#define N_C8S (0x600C + (12 * 8) + 1 )
191#define N_D8F (0x600C + (12 * 8) + 1 )
192#define N_D8 (0x600C + (12 * 8) + 2 )
193#define N_D8S (0x600C + (12 * 8) + 3 )
194#define N_E8F (0x600C + (12 * 8) + 3 )
195#define N_E8 (0x600C + (12 * 8) + 4 )
196#define N_F8 (0x600C + (12 * 8) + 5 )
197#define N_F8S (0x600C + (12 * 8) + 6 )
198#define N_G8F (0x600C + (12 * 8) + 6 )
199#define N_G8 (0x600C + (12 * 8) + 7 )
200#define N_G8S (0x600C + (12 * 8) + 8 )
201#define N_A8F (0x600C + (12 * 8) + 8 )
202#define N_A8 (0x600C + (12 * 8) + 9 )
203#define N_A8S (0x600C + (12 * 8) + 10)
204#define N_B8F (0x600C + (12 * 8) + 10)
205#define N_B8 (0x600C + (12 * 8) + 11)
206 55
207#endif \ No newline at end of file 56#endif
diff --git a/quantum/process_keycode/process_music.c b/quantum/process_keycode/process_music.c
index 2d52e47a7..217dca280 100644
--- a/quantum/process_keycode/process_music.c
+++ b/quantum/process_keycode/process_music.c
@@ -1,43 +1,72 @@
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 */
1#include "process_music.h" 16#include "process_music.h"
2 17
18#ifdef AUDIO_ENABLE
19#include "process_audio.h"
20#endif
21#if defined(MIDI_ENABLE) && defined(MIDI_BASIC)
22#include "process_midi.h"
23#endif
24
25#if defined(AUDIO_ENABLE) || (defined(MIDI_ENABLE) && defined(MIDI_BASIC))
26
3bool music_activated = false; 27bool music_activated = false;
4uint8_t starting_note = 0x0C; 28uint8_t music_starting_note = 0x0C;
5int offset = 7; 29int music_offset = 7;
6 30
7// music sequencer 31// music sequencer
8static bool music_sequence_recording = false; 32static bool music_sequence_recording = false;
9static bool music_sequence_recorded = false; 33static bool music_sequence_recorded = false;
10static bool music_sequence_playing = false; 34static bool music_sequence_playing = false;
11static float music_sequence[16] = {0}; 35static uint8_t music_sequence[16] = {0};
12static uint8_t music_sequence_count = 0; 36static uint8_t music_sequence_count = 0;
13static uint8_t music_sequence_position = 0; 37static uint8_t music_sequence_position = 0;
14 38
15static uint16_t music_sequence_timer = 0; 39static uint16_t music_sequence_timer = 0;
16static uint16_t music_sequence_interval = 100; 40static uint16_t music_sequence_interval = 100;
17 41
18bool process_music(uint16_t keycode, keyrecord_t *record) { 42static void music_noteon(uint8_t note) {
43 #ifdef AUDIO_ENABLE
44 process_audio_noteon(note);
45 #endif
46 #if defined(MIDI_ENABLE) && defined(MIDI_BASIC)
47 process_midi_basic_noteon(note);
48 #endif
49}
19 50
20 if (keycode == AU_ON && record->event.pressed) { 51static void music_noteoff(uint8_t note) {
21 audio_on(); 52 #ifdef AUDIO_ENABLE
22 return false; 53 process_audio_noteoff(note);
23 } 54 #endif
55 #if defined(MIDI_ENABLE) && defined(MIDI_BASIC)
56 process_midi_basic_noteoff(note);
57 #endif
58}
24 59
25 if (keycode == AU_OFF && record->event.pressed) { 60void music_all_notes_off(void) {
26 audio_off(); 61 #ifdef AUDIO_ENABLE
27 return false; 62 process_audio_all_notes_off();
28 } 63 #endif
64 #if defined(MIDI_ENABLE) && defined(MIDI_BASIC)
65 process_midi_all_notes_off();
66 #endif
67}
29 68
30 if (keycode == AU_TOG && record->event.pressed) { 69bool process_music(uint16_t keycode, keyrecord_t *record) {
31 if (is_audio_on())
32 {
33 audio_off();
34 }
35 else
36 {
37 audio_on();
38 }
39 return false;
40 }
41 70
42 if (keycode == MU_ON && record->event.pressed) { 71 if (keycode == MU_ON && record->event.pressed) {
43 music_on(); 72 music_on();
@@ -61,22 +90,10 @@ bool process_music(uint16_t keycode, keyrecord_t *record) {
61 return false; 90 return false;
62 } 91 }
63 92
64 if (keycode == MUV_IN && record->event.pressed) {
65 voice_iterate();
66 music_scale_user();
67 return false;
68 }
69
70 if (keycode == MUV_DE && record->event.pressed) {
71 voice_deiterate();
72 music_scale_user();
73 return false;
74 }
75
76 if (music_activated) { 93 if (music_activated) {
77 94
78 if (keycode == KC_LCTL && record->event.pressed) { // Start recording 95 if (keycode == KC_LCTL && record->event.pressed) { // Start recording
79 stop_all_notes(); 96 music_all_notes_off();
80 music_sequence_recording = true; 97 music_sequence_recording = true;
81 music_sequence_recorded = false; 98 music_sequence_recorded = false;
82 music_sequence_playing = false; 99 music_sequence_playing = false;
@@ -85,7 +102,7 @@ bool process_music(uint16_t keycode, keyrecord_t *record) {
85 } 102 }
86 103
87 if (keycode == KC_LALT && record->event.pressed) { // Stop recording/playing 104 if (keycode == KC_LALT && record->event.pressed) { // Stop recording/playing
88 stop_all_notes(); 105 music_all_notes_off();
89 if (music_sequence_recording) { // was recording 106 if (music_sequence_recording) { // was recording
90 music_sequence_recorded = true; 107 music_sequence_recorded = true;
91 } 108 }
@@ -95,7 +112,7 @@ bool process_music(uint16_t keycode, keyrecord_t *record) {
95 } 112 }
96 113
97 if (keycode == KC_LGUI && record->event.pressed && music_sequence_recorded) { // Start playing 114 if (keycode == KC_LGUI && record->event.pressed && music_sequence_recorded) { // Start playing
98 stop_all_notes(); 115 music_all_notes_off();
99 music_sequence_recording = false; 116 music_sequence_recording = false;
100 music_sequence_playing = true; 117 music_sequence_playing = true;
101 music_sequence_position = 0; 118 music_sequence_position = 0;
@@ -115,21 +132,33 @@ bool process_music(uint16_t keycode, keyrecord_t *record) {
115 return false; 132 return false;
116 } 133 }
117 134
118 float freq = ((float)220.0)*pow(2.0, -5.0)*pow(2.0,(starting_note + SCALE[record->event.key.col + offset])/12.0+(MATRIX_ROWS - record->event.key.row)); 135 #define MUSIC_MODE_GUITAR
136
137 #ifdef MUSIC_MODE_CHROMATIC
138 uint8_t note = (music_starting_note + record->event.key.col + music_offset - 3)+12*(MATRIX_ROWS - record->event.key.row);
139 #elif defined(MUSIC_MODE_GUITAR)
140 uint8_t note = (music_starting_note + record->event.key.col + music_offset + 32)+5*(MATRIX_ROWS - record->event.key.row);
141 #elif defined(MUSIC_MODE_VIOLIN)
142 uint8_t note = (music_starting_note + record->event.key.col + music_offset + 32)+7*(MATRIX_ROWS - record->event.key.row);
143 #else
144 uint8_t note = (music_starting_note + SCALE[record->event.key.col + music_offset] - 3)+12*(MATRIX_ROWS - record->event.key.row);
145 #endif
146
119 if (record->event.pressed) { 147 if (record->event.pressed) {
120 play_note(freq, 0xF); 148 music_noteon(note);
121 if (music_sequence_recording) { 149 if (music_sequence_recording) {
122 music_sequence[music_sequence_count] = freq; 150 music_sequence[music_sequence_count] = note;
123 music_sequence_count++; 151 music_sequence_count++;
124 } 152 }
125 } else { 153 } else {
126 stop_note(freq); 154 music_noteoff(note);
127 } 155 }
128 156
129 if (keycode < 0xFF) // ignores all normal keycodes, but lets RAISE, LOWER, etc through 157 if (keycode < 0xFF) // ignores all normal keycodes, but lets RAISE, LOWER, etc through
130 return false; 158 return false;
131 } 159 }
132 return true; 160
161 return true;
133} 162}
134 163
135bool is_music_on(void) { 164bool is_music_on(void) {
@@ -151,26 +180,26 @@ void music_on(void) {
151 180
152void music_off(void) { 181void music_off(void) {
153 music_activated = 0; 182 music_activated = 0;
154 stop_all_notes(); 183 music_all_notes_off();
155} 184}
156 185
157
158__attribute__ ((weak))
159void music_on_user() {}
160
161__attribute__ ((weak))
162void audio_on_user() {}
163
164__attribute__ ((weak))
165void music_scale_user() {}
166
167void matrix_scan_music(void) { 186void matrix_scan_music(void) {
168 if (music_sequence_playing) { 187 if (music_sequence_playing) {
169 if ((music_sequence_timer == 0) || (timer_elapsed(music_sequence_timer) > music_sequence_interval)) { 188 if ((music_sequence_timer == 0) || (timer_elapsed(music_sequence_timer) > music_sequence_interval)) {
170 music_sequence_timer = timer_read(); 189 music_sequence_timer = timer_read();
171 stop_note(music_sequence[(music_sequence_position - 1 < 0)?(music_sequence_position - 1 + music_sequence_count):(music_sequence_position - 1)]); 190 uint8_t prev_note = music_sequence[(music_sequence_position - 1 < 0)?(music_sequence_position - 1 + music_sequence_count):(music_sequence_position - 1)];
172 play_note(music_sequence[music_sequence_position], 0xF); 191 uint8_t next_note = music_sequence[music_sequence_position];
192 music_noteoff(prev_note);
193 music_noteon(next_note);
173 music_sequence_position = (music_sequence_position + 1) % music_sequence_count; 194 music_sequence_position = (music_sequence_position + 1) % music_sequence_count;
174 } 195 }
175 } 196 }
176} 197}
198
199__attribute__ ((weak))
200void music_on_user() {}
201
202__attribute__ ((weak))
203void music_scale_user() {}
204
205#endif // defined(AUDIO_ENABLE) || (defined(MIDI_ENABLE) && defined(MIDI_BASIC)) \ No newline at end of file
diff --git a/quantum/process_keycode/process_music.h b/quantum/process_keycode/process_music.h
index 318b3e387..8dfbf041f 100644
--- a/quantum/process_keycode/process_music.h
+++ b/quantum/process_keycode/process_music.h
@@ -1,8 +1,26 @@
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
1#ifndef PROCESS_MUSIC_H 17#ifndef PROCESS_MUSIC_H
2#define PROCESS_MUSIC_H 18#define PROCESS_MUSIC_H
3 19
4#include "quantum.h" 20#include "quantum.h"
5 21
22#if defined(AUDIO_ENABLE) || (defined(MIDI_ENABLE) && defined(MIDI_BASIC))
23
6bool process_music(uint16_t keycode, keyrecord_t *record); 24bool process_music(uint16_t keycode, keyrecord_t *record);
7 25
8bool is_music_on(void); 26bool is_music_on(void);
@@ -10,9 +28,9 @@ void music_toggle(void);
10void music_on(void); 28void music_on(void);
11void music_off(void); 29void music_off(void);
12 30
13void audio_on_user(void);
14void music_on_user(void); 31void music_on_user(void);
15void music_scale_user(void); 32void music_scale_user(void);
33void music_all_notes_off(void);
16 34
17void matrix_scan_music(void); 35void matrix_scan_music(void);
18 36
@@ -24,4 +42,6 @@ void matrix_scan_music(void);
24 0 + (12*4), 2 + (12*4), 4 + (12*4), 5 + (12*4), 7 + (12*4), 9 + (12*4), 11 + (12*4), } 42 0 + (12*4), 2 + (12*4), 4 + (12*4), 5 + (12*4), 7 + (12*4), 9 + (12*4), 11 + (12*4), }
25#endif 43#endif
26 44
27#endif \ No newline at end of file 45#endif // defined(AUDIO_ENABLE) || (defined(MIDI_ENABLE) && defined(MIDI_BASIC))
46
47#endif
diff --git a/quantum/process_keycode/process_printer.c b/quantum/process_keycode/process_printer.c
new file mode 100644
index 000000000..807f7a0b9
--- /dev/null
+++ b/quantum/process_keycode/process_printer.c
@@ -0,0 +1,270 @@
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
17#include "process_printer.h"
18#include "action_util.h"
19
20bool printing_enabled = false;
21uint8_t character_shift = 0;
22
23void enabled_printing() {
24 printing_enabled = true;
25 serial_init();
26}
27
28void disable_printing() {
29 printing_enabled = false;
30}
31
32uint8_t shifted_numbers[10] = {0x21, 0x40, 0x23, 0x24, 0x25, 0x5E, 0x26, 0x2A, 0x28, 0x29};
33
34// uint8_t keycode_to_ascii[0xFF][2];
35
36// keycode_to_ascii[KC_MINS] = {0x2D, 0x5F};
37
38void print_char(char c) {
39 USB_Disable();
40 serial_send(c);
41 USB_Init();
42}
43
44void print_box_string(uint8_t text[]) {
45 uint8_t len = strlen(text);
46 uint8_t out[len * 3 + 8];
47 out[0] = 0xDA;
48 for (uint8_t i = 0; i < len; i++) {
49 out[i+1] = 0xC4;
50 }
51 out[len + 1] = 0xBF;
52 out[len + 2] = '\n';
53
54 out[len + 3] = 0xB3;
55 for (uint8_t i = 0; i < len; i++) {
56 out[len + 4 + i] = text[i];
57 }
58 out[len * 2 + 4] = 0xB3;
59 out[len * 2 + 5] = '\n';
60
61
62 out[len * 2 + 6] = 0xC0;
63 for (uint8_t i = 0; i < len; i++) {
64 out[len * 2 + 7 + i] = 0xC4;
65 }
66 out[len * 3 + 7] = 0xD9;
67 out[len * 3 + 8] = '\n';
68
69 print_string(out);
70}
71
72void print_string(char c[]) {
73 for(uint8_t i = 0; i < strlen(c); i++)
74 print_char(c[i]);
75}
76
77bool process_printer(uint16_t keycode, keyrecord_t *record) {
78 if (keycode == PRINT_ON) {
79 enabled_printing();
80 return false;
81 }
82 if (keycode == PRINT_OFF) {
83 disable_printing();
84 return false;
85 }
86
87 if (printing_enabled) {
88 switch(keycode) {
89 case KC_EXLM ... KC_RPRN:
90 case KC_UNDS:
91 case KC_PLUS:
92 case KC_LCBR:
93 case KC_RCBR:
94 case KC_PIPE:
95 case KC_TILD:
96 keycode &= 0xFF;
97 case KC_LSFT:
98 case KC_RSFT:
99 if (record->event.pressed) {
100 character_shift++;
101 } else {
102 character_shift--;
103 }
104 return false;
105 break;
106 }
107
108 switch(keycode) {
109 case KC_F1:
110 if (record->event.pressed) {
111 print_box_string("This is a line of text!");
112 }
113 return false;
114 case KC_ESC:
115 if (record->event.pressed) {
116 print_char(0x1B);
117 }
118 return false;
119 break;
120 case KC_SPC:
121 if (record->event.pressed) {
122 print_char(0x20);
123 }
124 return false;
125 break;
126 case KC_A ... KC_Z:
127 if (record->event.pressed) {
128 if (character_shift) {
129 print_char(0x41 + (keycode - KC_A));
130 } else {
131 print_char(0x61 + (keycode - KC_A));
132 }
133 }
134 return false;
135 break;
136 case KC_1 ... KC_0:
137 if (record->event.pressed) {
138 if (character_shift) {
139 print_char(shifted_numbers[keycode - KC_1]);
140 } else {
141 print_char(0x30 + ((keycode - KC_1 + 1) % 10));
142 }
143 }
144 return false;
145 break;
146 case KC_ENT:
147 if (record->event.pressed) {
148 if (character_shift) {
149 print_char(0x0C);
150 } else {
151 print_char(0x0A);
152 }
153 }
154 return false;
155 break;
156 case KC_BSPC:
157 if (record->event.pressed) {
158 if (character_shift) {
159 print_char(0x18);
160 } else {
161 print_char(0x1A);
162 }
163 }
164 return false;
165 break;
166 case KC_DOT:
167 if (record->event.pressed) {
168 if (character_shift) {
169 print_char(0x3E);
170 } else {
171 print_char(0x2E);
172 }
173 }
174 return false;
175 break;
176 case KC_COMM:
177 if (record->event.pressed) {
178 if (character_shift) {
179 print_char(0x3C);
180 } else {
181 print_char(0x2C);
182 }
183 }
184 return false;
185 break;
186 case KC_SLSH:
187 if (record->event.pressed) {
188 if (character_shift) {
189 print_char(0x3F);
190 } else {
191 print_char(0x2F);
192 }
193 }
194 return false;
195 break;
196 case KC_QUOT:
197 if (record->event.pressed) {
198 if (character_shift) {
199 print_char(0x22);
200 } else {
201 print_char(0x27);
202 }
203 }
204 return false;
205 break;
206 case KC_GRV:
207 if (record->event.pressed) {
208 if (character_shift) {
209 print_char(0x7E);
210 } else {
211 print_char(0x60);
212 }
213 }
214 return false;
215 break;
216 case KC_MINS:
217 if (record->event.pressed) {
218 if (character_shift) {
219 print_char(0x5F);
220 } else {
221 print_char(0x2D);
222 }
223 }
224 return false;
225 break;
226 case KC_EQL:
227 if (record->event.pressed) {
228 if (character_shift) {
229 print_char(0x2B);
230 } else {
231 print_char(0x3D);
232 }
233 }
234 return false;
235 break;
236 case KC_LBRC:
237 if (record->event.pressed) {
238 if (character_shift) {
239 print_char(0x7B);
240 } else {
241 print_char(0x5B);
242 }
243 }
244 return false;
245 break;
246 case KC_RBRC:
247 if (record->event.pressed) {
248 if (character_shift) {
249 print_char(0x7D);
250 } else {
251 print_char(0x5D);
252 }
253 }
254 return false;
255 break;
256 case KC_BSLS:
257 if (record->event.pressed) {
258 if (character_shift) {
259 print_char(0x7C);
260 } else {
261 print_char(0x5C);
262 }
263 }
264 return false;
265 break;
266 }
267 }
268 return true;
269
270}
diff --git a/quantum/process_keycode/process_printer.h b/quantum/process_keycode/process_printer.h
new file mode 100644
index 000000000..aa494ac8a
--- /dev/null
+++ b/quantum/process_keycode/process_printer.h
@@ -0,0 +1,24 @@
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
17#ifndef PROCESS_PRINTER_H
18#define PROCESS_PRINTER_H
19
20#include "quantum.h"
21
22#include "protocol/serial.h"
23
24#endif
diff --git a/quantum/process_keycode/process_printer_bb.c b/quantum/process_keycode/process_printer_bb.c
new file mode 100644
index 000000000..55d3b552b
--- /dev/null
+++ b/quantum/process_keycode/process_printer_bb.c
@@ -0,0 +1,276 @@
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
17#include "process_printer.h"
18#include "action_util.h"
19
20bool printing_enabled = false;
21uint8_t character_shift = 0;
22
23#define SERIAL_PIN_DDR DDRD
24#define SERIAL_PIN_PORT PORTD
25#define SERIAL_PIN_MASK _BV(PD3)
26#define SERIAL_DELAY 52
27
28inline static
29void serial_delay(void) {
30 _delay_us(SERIAL_DELAY);
31}
32
33inline static
34void serial_high(void) {
35 SERIAL_PIN_PORT |= SERIAL_PIN_MASK;
36}
37
38inline static
39void serial_low(void) {
40 SERIAL_PIN_PORT &= ~SERIAL_PIN_MASK;
41}
42
43inline static
44void serial_output(void) {
45 SERIAL_PIN_DDR |= SERIAL_PIN_MASK;
46}
47
48
49void enabled_printing() {
50 printing_enabled = true;
51 serial_output();
52 serial_high();
53}
54
55void disable_printing() {
56 printing_enabled = false;
57}
58
59uint8_t shifted_numbers[10] = {0x21, 0x40, 0x23, 0x24, 0x25, 0x5E, 0x26, 0x2A, 0x28, 0x29};
60
61// uint8_t keycode_to_ascii[0xFF][2];
62
63// keycode_to_ascii[KC_MINS] = {0x2D, 0x5F};
64
65void print_char(char c) {
66 uint8_t b = 8;
67 serial_output();
68 while( b-- ) {
69 if(c & (1 << b)) {
70 serial_high();
71 } else {
72 serial_low();
73 }
74 serial_delay();
75 }
76}
77
78void print_string(char c[]) {
79 for(uint8_t i = 0; i < strlen(c); i++)
80 print_char(c[i]);
81}
82
83bool process_printer(uint16_t keycode, keyrecord_t *record) {
84 if (keycode == PRINT_ON) {
85 enabled_printing();
86 return false;
87 }
88 if (keycode == PRINT_OFF) {
89 disable_printing();
90 return false;
91 }
92
93 if (printing_enabled) {
94 switch(keycode) {
95 case KC_EXLM ... KC_RPRN:
96 case KC_UNDS:
97 case KC_PLUS:
98 case KC_LCBR:
99 case KC_RCBR:
100 case KC_PIPE:
101 case KC_TILD:
102 keycode &= 0xFF;
103 case KC_LSFT:
104 case KC_RSFT:
105 if (record->event.pressed) {
106 character_shift++;
107 } else {
108 character_shift--;
109 }
110 return false;
111 break;
112 }
113
114 switch(keycode) {
115 case KC_F1:
116 if (record->event.pressed) {
117 print_string("This is a line of text!\n\n\n");
118 }
119 return false;
120 case KC_ESC:
121 if (record->event.pressed) {
122 print_char(0x1B);
123 }
124 return false;
125 break;
126 case KC_SPC:
127 if (record->event.pressed) {
128 print_char(0x20);
129 }
130 return false;
131 break;
132 case KC_A ... KC_Z:
133 if (record->event.pressed) {
134 if (character_shift) {
135 print_char(0x41 + (keycode - KC_A));
136 } else {
137 print_char(0x61 + (keycode - KC_A));
138 }
139 }
140 return false;
141 break;
142 case KC_1 ... KC_0:
143 if (record->event.pressed) {
144 if (character_shift) {
145 print_char(shifted_numbers[keycode - KC_1]);
146 } else {
147 print_char(0x30 + ((keycode - KC_1 + 1) % 10));
148 }
149 }
150 return false;
151 break;
152 case KC_ENT:
153 if (record->event.pressed) {
154 if (character_shift) {
155 print_char(0x0C);
156 } else {
157 print_char(0x0A);
158 }
159 }
160 return false;
161 break;
162 case KC_BSPC:
163 if (record->event.pressed) {
164 if (character_shift) {
165 print_char(0x18);
166 } else {
167 print_char(0x1A);
168 }
169 }
170 return false;
171 break;
172 case KC_DOT:
173 if (record->event.pressed) {
174 if (character_shift) {
175 print_char(0x3E);
176 } else {
177 print_char(0x2E);
178 }
179 }
180 return false;
181 break;
182 case KC_COMM:
183 if (record->event.pressed) {
184 if (character_shift) {
185 print_char(0x3C);
186 } else {
187 print_char(0x2C);
188 }
189 }
190 return false;
191 break;
192 case KC_SLSH:
193 if (record->event.pressed) {
194 if (character_shift) {
195 print_char(0x3F);
196 } else {
197 print_char(0x2F);
198 }
199 }
200 return false;
201 break;
202 case KC_QUOT:
203 if (record->event.pressed) {
204 if (character_shift) {
205 print_char(0x22);
206 } else {
207 print_char(0x27);
208 }
209 }
210 return false;
211 break;
212 case KC_GRV:
213 if (record->event.pressed) {
214 if (character_shift) {
215 print_char(0x7E);
216 } else {
217 print_char(0x60);
218 }
219 }
220 return false;
221 break;
222 case KC_MINS:
223 if (record->event.pressed) {
224 if (character_shift) {
225 print_char(0x5F);
226 } else {
227 print_char(0x2D);
228 }
229 }
230 return false;
231 break;
232 case KC_EQL:
233 if (record->event.pressed) {
234 if (character_shift) {
235 print_char(0x2B);
236 } else {
237 print_char(0x3D);
238 }
239 }
240 return false;
241 break;
242 case KC_LBRC:
243 if (record->event.pressed) {
244 if (character_shift) {
245 print_char(0x7B);
246 } else {
247 print_char(0x5B);
248 }
249 }
250 return false;
251 break;
252 case KC_RBRC:
253 if (record->event.pressed) {
254 if (character_shift) {
255 print_char(0x7D);
256 } else {
257 print_char(0x5D);
258 }
259 }
260 return false;
261 break;
262 case KC_BSLS:
263 if (record->event.pressed) {
264 if (character_shift) {
265 print_char(0x7C);
266 } else {
267 print_char(0x5C);
268 }
269 }
270 return false;
271 break;
272 }
273 }
274 return true;
275
276}
diff --git a/quantum/process_keycode/process_tap_dance.c b/quantum/process_keycode/process_tap_dance.c
index 6ae362c4c..68c8425bb 100644
--- a/quantum/process_keycode/process_tap_dance.c
+++ b/quantum/process_keycode/process_tap_dance.c
@@ -1,3 +1,18 @@
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 */
1#include "quantum.h" 16#include "quantum.h"
2#include "action_tapping.h" 17#include "action_tapping.h"
3 18
@@ -43,12 +58,16 @@ static inline void process_tap_dance_action_on_dance_finished (qk_tap_dance_acti
43 if (action->state.finished) 58 if (action->state.finished)
44 return; 59 return;
45 action->state.finished = true; 60 action->state.finished = true;
61 add_mods(action->state.oneshot_mods);
62 send_keyboard_report();
46 _process_tap_dance_action_fn (&action->state, action->user_data, action->fn.on_dance_finished); 63 _process_tap_dance_action_fn (&action->state, action->user_data, action->fn.on_dance_finished);
47} 64}
48 65
49static inline void process_tap_dance_action_on_reset (qk_tap_dance_action_t *action) 66static inline void process_tap_dance_action_on_reset (qk_tap_dance_action_t *action)
50{ 67{
51 _process_tap_dance_action_fn (&action->state, action->user_data, action->fn.on_reset); 68 _process_tap_dance_action_fn (&action->state, action->user_data, action->fn.on_reset);
69 del_mods(action->state.oneshot_mods);
70 send_keyboard_report();
52} 71}
53 72
54bool process_tap_dance(uint16_t keycode, keyrecord_t *record) { 73bool process_tap_dance(uint16_t keycode, keyrecord_t *record) {
@@ -70,6 +89,7 @@ bool process_tap_dance(uint16_t keycode, keyrecord_t *record) {
70 action->state.keycode = keycode; 89 action->state.keycode = keycode;
71 action->state.count++; 90 action->state.count++;
72 action->state.timer = timer_read(); 91 action->state.timer = timer_read();
92 action->state.oneshot_mods = get_oneshot_mods();
73 process_tap_dance_action_on_each_tap (action); 93 process_tap_dance_action_on_each_tap (action);
74 94
75 if (last_td && last_td != keycode) { 95 if (last_td && last_td != keycode) {
@@ -109,7 +129,7 @@ void matrix_scan_tap_dance () {
109 if (highest_td == -1) 129 if (highest_td == -1)
110 return; 130 return;
111 131
112 for (int i = 0; i <= highest_td; i++) { 132for (int i = 0; i <= highest_td; i++) {
113 qk_tap_dance_action_t *action = &tap_dance_actions[i]; 133 qk_tap_dance_action_t *action = &tap_dance_actions[i];
114 134
115 if (action->state.count && timer_elapsed (action->state.timer) > TAPPING_TERM) { 135 if (action->state.count && timer_elapsed (action->state.timer) > TAPPING_TERM) {
diff --git a/quantum/process_keycode/process_tap_dance.h b/quantum/process_keycode/process_tap_dance.h
index f753cbba6..330809f83 100644
--- a/quantum/process_keycode/process_tap_dance.h
+++ b/quantum/process_keycode/process_tap_dance.h
@@ -1,3 +1,18 @@
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 */
1#ifndef PROCESS_TAP_DANCE_H 16#ifndef PROCESS_TAP_DANCE_H
2#define PROCESS_TAP_DANCE_H 17#define PROCESS_TAP_DANCE_H
3 18
@@ -9,6 +24,7 @@
9typedef struct 24typedef struct
10{ 25{
11 uint8_t count; 26 uint8_t count;
27 uint8_t oneshot_mods;
12 uint16_t keycode; 28 uint16_t keycode;
13 uint16_t timer; 29 uint16_t timer;
14 bool interrupted; 30 bool interrupted;
diff --git a/quantum/process_keycode/process_ucis.c b/quantum/process_keycode/process_ucis.c
new file mode 100644
index 000000000..86c0937f5
--- /dev/null
+++ b/quantum/process_keycode/process_ucis.c
@@ -0,0 +1,149 @@
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_ucis.h"
18
19qk_ucis_state_t qk_ucis_state;
20
21void qk_ucis_start(void) {
22 qk_ucis_state.count = 0;
23 qk_ucis_state.in_progress = true;
24
25 qk_ucis_start_user();
26}
27
28__attribute__((weak))
29void qk_ucis_start_user(void) {
30 unicode_input_start();
31 register_hex(0x2328);
32 unicode_input_finish();
33}
34
35static bool is_uni_seq(char *seq) {
36 uint8_t i;
37
38 for (i = 0; seq[i]; i++) {
39 uint16_t code;
40 if (('1' <= seq[i]) && (seq[i] <= '0'))
41 code = seq[i] - '1' + KC_1;
42 else
43 code = seq[i] - 'a' + KC_A;
44
45 if (i > qk_ucis_state.count || qk_ucis_state.codes[i] != code)
46 return false;
47 }
48
49 return (qk_ucis_state.codes[i] == KC_ENT ||
50 qk_ucis_state.codes[i] == KC_SPC);
51}
52
53__attribute__((weak))
54void qk_ucis_symbol_fallback (void) {
55 for (uint8_t i = 0; i < qk_ucis_state.count - 1; i++) {
56 uint8_t code = qk_ucis_state.codes[i];
57 register_code(code);
58 unregister_code(code);
59 wait_ms(UNICODE_TYPE_DELAY);
60 }
61}
62
63void register_ucis(const char *hex) {
64 for(int i = 0; hex[i]; i++) {
65 uint8_t kc = 0;
66 char c = hex[i];
67
68 switch (c) {
69 case '0':
70 kc = KC_0;
71 break;
72 case '1' ... '9':
73 kc = c - '1' + KC_1;
74 break;
75 case 'a' ... 'f':
76 kc = c - 'a' + KC_A;
77 break;
78 case 'A' ... 'F':
79 kc = c - 'A' + KC_A;
80 break;
81 }
82
83 if (kc) {
84 register_code (kc);
85 unregister_code (kc);
86 wait_ms (UNICODE_TYPE_DELAY);
87 }
88 }
89}
90
91bool process_ucis (uint16_t keycode, keyrecord_t *record) {
92 uint8_t i;
93
94 if (!qk_ucis_state.in_progress)
95 return true;
96
97 if (qk_ucis_state.count >= UCIS_MAX_SYMBOL_LENGTH &&
98 !(keycode == KC_BSPC || keycode == KC_ESC || keycode == KC_SPC || keycode == KC_ENT)) {
99 return false;
100 }
101
102 if (!record->event.pressed)
103 return true;
104
105 qk_ucis_state.codes[qk_ucis_state.count] = keycode;
106 qk_ucis_state.count++;
107
108 if (keycode == KC_BSPC) {
109 if (qk_ucis_state.count >= 2) {
110 qk_ucis_state.count -= 2;
111 return true;
112 } else {
113 qk_ucis_state.count--;
114 return false;
115 }
116 }
117
118 if (keycode == KC_ENT || keycode == KC_SPC || keycode == KC_ESC) {
119 bool symbol_found = false;
120
121 for (i = qk_ucis_state.count; i > 0; i--) {
122 register_code (KC_BSPC);
123 unregister_code (KC_BSPC);
124 wait_ms(UNICODE_TYPE_DELAY);
125 }
126
127 if (keycode == KC_ESC) {
128 qk_ucis_state.in_progress = false;
129 return false;
130 }
131
132 unicode_input_start();
133 for (i = 0; ucis_symbol_table[i].symbol; i++) {
134 if (is_uni_seq (ucis_symbol_table[i].symbol)) {
135 symbol_found = true;
136 register_ucis(ucis_symbol_table[i].code + 2);
137 break;
138 }
139 }
140 if (!symbol_found) {
141 qk_ucis_symbol_fallback();
142 }
143 unicode_input_finish();
144
145 qk_ucis_state.in_progress = false;
146 return false;
147 }
148 return true;
149}
diff --git a/quantum/process_keycode/process_ucis.h b/quantum/process_keycode/process_ucis.h
new file mode 100644
index 000000000..3f736a709
--- /dev/null
+++ b/quantum/process_keycode/process_ucis.h
@@ -0,0 +1,51 @@
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_UCIS_H
18#define PROCESS_UCIS_H
19
20#include "quantum.h"
21#include "process_unicode_common.h"
22
23#ifndef UCIS_MAX_SYMBOL_LENGTH
24#define UCIS_MAX_SYMBOL_LENGTH 32
25#endif
26
27typedef struct {
28 char *symbol;
29 char *code;
30} qk_ucis_symbol_t;
31
32typedef struct {
33 uint8_t count;
34 uint16_t codes[UCIS_MAX_SYMBOL_LENGTH];
35 bool in_progress:1;
36} qk_ucis_state_t;
37
38extern qk_ucis_state_t qk_ucis_state;
39
40#define UCIS_TABLE(...) {__VA_ARGS__, {NULL, NULL}}
41#define UCIS_SYM(name, code) {name, #code}
42
43extern const qk_ucis_symbol_t ucis_symbol_table[];
44
45void qk_ucis_start(void);
46void qk_ucis_start_user(void);
47void qk_ucis_symbol_fallback (void);
48void register_ucis(const char *hex);
49bool process_ucis (uint16_t keycode, keyrecord_t *record);
50
51#endif
diff --git a/quantum/process_keycode/process_unicode.c b/quantum/process_keycode/process_unicode.c
index f42f25538..cecfaeee9 100644
--- a/quantum/process_keycode/process_unicode.c
+++ b/quantum/process_keycode/process_unicode.c
@@ -1,4 +1,20 @@
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 */
1#include "process_unicode.h" 16#include "process_unicode.h"
17#include "action_util.h"
2 18
3static uint8_t input_mode; 19static uint8_t input_mode;
4static uint8_t first_flag = 0; 20static uint8_t first_flag = 0;
@@ -75,6 +91,7 @@ void register_hex(uint16_t hex) {
75 } 91 }
76} 92}
77 93
94
78bool process_unicode(uint16_t keycode, keyrecord_t *record) { 95bool process_unicode(uint16_t keycode, keyrecord_t *record) {
79 if (keycode > QK_UNICODE && record->event.pressed) { 96 if (keycode > QK_UNICODE && record->event.pressed) {
80 if (first_flag == 0) { 97 if (first_flag == 0) {
@@ -89,182 +106,3 @@ bool process_unicode(uint16_t keycode, keyrecord_t *record) {
89 return true; 106 return true;
90} 107}
91 108
92#ifdef UNICODEMAP_ENABLE
93__attribute__((weak))
94const uint32_t PROGMEM unicode_map[] = {
95};
96
97void register_hex32(uint32_t hex) {
98 uint8_t onzerostart = 1;
99 for(int i = 7; i >= 0; i--) {
100 if (i <= 3) {
101 onzerostart = 0;
102 }
103 uint8_t digit = ((hex >> (i*4)) & 0xF);
104 if (digit == 0) {
105 if (onzerostart == 0) {
106 register_code(hex_to_keycode(digit));
107 unregister_code(hex_to_keycode(digit));
108 }
109 } else {
110 register_code(hex_to_keycode(digit));
111 unregister_code(hex_to_keycode(digit));
112 onzerostart = 0;
113 }
114 }
115}
116
117__attribute__((weak))
118void unicode_map_input_error() {}
119
120bool process_unicode_map(uint16_t keycode, keyrecord_t *record) {
121 if ((keycode & QK_UNICODE_MAP) == QK_UNICODE_MAP && record->event.pressed) {
122 const uint32_t* map = unicode_map;
123 uint16_t index = keycode & 0x7FF;
124 uint32_t code = pgm_read_dword_far(&map[index]);
125 if ((code > 0xFFFF && input_mode == UC_OSX) || (code > 0xFFFFF && input_mode == UC_LNX)) {
126 // when character is out of range supported by the OS
127 unicode_map_input_error();
128 } else {
129 unicode_input_start();
130 register_hex32(code);
131 unicode_input_finish();
132 }
133 }
134 return true;
135}
136#endif
137
138#ifdef UCIS_ENABLE
139qk_ucis_state_t qk_ucis_state;
140
141void qk_ucis_start(void) {
142 qk_ucis_state.count = 0;
143 qk_ucis_state.in_progress = true;
144
145 qk_ucis_start_user();
146}
147
148__attribute__((weak))
149void qk_ucis_start_user(void) {
150 unicode_input_start();
151 register_hex(0x2328);
152 unicode_input_finish();
153}
154
155static bool is_uni_seq(char *seq) {
156 uint8_t i;
157
158 for (i = 0; seq[i]; i++) {
159 uint16_t code;
160 if (('1' <= seq[i]) && (seq[i] <= '0'))
161 code = seq[i] - '1' + KC_1;
162 else
163 code = seq[i] - 'a' + KC_A;
164
165 if (i > qk_ucis_state.count || qk_ucis_state.codes[i] != code)
166 return false;
167 }
168
169 return (qk_ucis_state.codes[i] == KC_ENT ||
170 qk_ucis_state.codes[i] == KC_SPC);
171}
172
173__attribute__((weak))
174void qk_ucis_symbol_fallback (void) {
175 for (uint8_t i = 0; i < qk_ucis_state.count - 1; i++) {
176 uint8_t code = qk_ucis_state.codes[i];
177 register_code(code);
178 unregister_code(code);
179 wait_ms(UNICODE_TYPE_DELAY);
180 }
181}
182
183void register_ucis(const char *hex) {
184 for(int i = 0; hex[i]; i++) {
185 uint8_t kc = 0;
186 char c = hex[i];
187
188 switch (c) {
189 case '0':
190 kc = KC_0;
191 break;
192 case '1' ... '9':
193 kc = c - '1' + KC_1;
194 break;
195 case 'a' ... 'f':
196 kc = c - 'a' + KC_A;
197 break;
198 case 'A' ... 'F':
199 kc = c - 'A' + KC_A;
200 break;
201 }
202
203 if (kc) {
204 register_code (kc);
205 unregister_code (kc);
206 wait_ms (UNICODE_TYPE_DELAY);
207 }
208 }
209}
210
211bool process_ucis (uint16_t keycode, keyrecord_t *record) {
212 uint8_t i;
213
214 if (!qk_ucis_state.in_progress)
215 return true;
216
217 if (qk_ucis_state.count >= UCIS_MAX_SYMBOL_LENGTH &&
218 !(keycode == KC_BSPC || keycode == KC_ESC || keycode == KC_SPC || keycode == KC_ENT)) {
219 return false;
220 }
221
222 if (!record->event.pressed)
223 return true;
224
225 qk_ucis_state.codes[qk_ucis_state.count] = keycode;
226 qk_ucis_state.count++;
227
228 if (keycode == KC_BSPC) {
229 if (qk_ucis_state.count >= 2) {
230 qk_ucis_state.count -= 2;
231 return true;
232 } else {
233 qk_ucis_state.count--;
234 return false;
235 }
236 }
237
238 if (keycode == KC_ENT || keycode == KC_SPC || keycode == KC_ESC) {
239 bool symbol_found = false;
240
241 for (i = qk_ucis_state.count; i > 0; i--) {
242 register_code (KC_BSPC);
243 unregister_code (KC_BSPC);
244 wait_ms(UNICODE_TYPE_DELAY);
245 }
246
247 if (keycode == KC_ESC) {
248 qk_ucis_state.in_progress = false;
249 return false;
250 }
251
252 unicode_input_start();
253 for (i = 0; ucis_symbol_table[i].symbol; i++) {
254 if (is_uni_seq (ucis_symbol_table[i].symbol)) {
255 symbol_found = true;
256 register_ucis(ucis_symbol_table[i].code + 2);
257 break;
258 }
259 }
260 if (!symbol_found) {
261 qk_ucis_symbol_fallback();
262 }
263 unicode_input_finish();
264
265 qk_ucis_state.in_progress = false;
266 return false;
267 }
268 return true;
269}
270#endif
diff --git a/quantum/process_keycode/process_unicode.h b/quantum/process_keycode/process_unicode.h
index 065eeb5f6..c525b74f0 100644
--- a/quantum/process_keycode/process_unicode.h
+++ b/quantum/process_keycode/process_unicode.h
@@ -1,166 +1,24 @@
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 */
1#ifndef PROCESS_UNICODE_H 16#ifndef PROCESS_UNICODE_H
2#define PROCESS_UNICODE_H 17#define PROCESS_UNICODE_H
3 18
4#include "quantum.h" 19#include "quantum.h"
5 20#include "process_unicode_common.h"
6#define UC_OSX 0 // Mac OS X
7#define UC_LNX 1 // Linux
8#define UC_WIN 2 // Windows 'HexNumpad'
9#define UC_BSD 3 // BSD (not implemented)
10#define UC_WINC 4 // WinCompose https://github.com/samhocevar/wincompose
11
12#ifndef UNICODE_TYPE_DELAY
13#define UNICODE_TYPE_DELAY 10
14#endif
15
16void set_unicode_input_mode(uint8_t os_target);
17uint8_t get_unicode_input_mode(void);
18void unicode_input_start(void);
19void unicode_input_finish(void);
20void register_hex(uint16_t hex);
21 21
22bool process_unicode(uint16_t keycode, keyrecord_t *record); 22bool process_unicode(uint16_t keycode, keyrecord_t *record);
23 23
24#ifdef UNICODEMAP_ENABLE
25bool process_unicode_map(uint16_t keycode, keyrecord_t *record);
26#endif
27
28#ifdef UCIS_ENABLE
29#ifndef UCIS_MAX_SYMBOL_LENGTH
30#define UCIS_MAX_SYMBOL_LENGTH 32
31#endif
32
33typedef struct {
34 char *symbol;
35 char *code;
36} qk_ucis_symbol_t;
37
38typedef struct {
39 uint8_t count;
40 uint16_t codes[UCIS_MAX_SYMBOL_LENGTH];
41 bool in_progress:1;
42} qk_ucis_state_t;
43
44extern qk_ucis_state_t qk_ucis_state;
45
46#define UCIS_TABLE(...) {__VA_ARGS__, {NULL, NULL}}
47#define UCIS_SYM(name, code) {name, #code}
48
49extern const qk_ucis_symbol_t ucis_symbol_table[];
50
51void qk_ucis_start(void);
52void qk_ucis_start_user(void);
53void qk_ucis_symbol_fallback (void);
54void register_ucis(const char *hex);
55bool process_ucis (uint16_t keycode, keyrecord_t *record);
56
57#endif
58
59#define UC_BSPC UC(0x0008)
60
61#define UC_SPC UC(0x0020)
62
63#define UC_EXLM UC(0x0021)
64#define UC_DQUT UC(0x0022)
65#define UC_HASH UC(0x0023)
66#define UC_DLR UC(0x0024)
67#define UC_PERC UC(0x0025)
68#define UC_AMPR UC(0x0026)
69#define UC_QUOT UC(0x0027)
70#define UC_LPRN UC(0x0028)
71#define UC_RPRN UC(0x0029)
72#define UC_ASTR UC(0x002A)
73#define UC_PLUS UC(0x002B)
74#define UC_COMM UC(0x002C)
75#define UC_DASH UC(0x002D)
76#define UC_DOT UC(0x002E)
77#define UC_SLSH UC(0x002F)
78
79#define UC_0 UC(0x0030)
80#define UC_1 UC(0x0031)
81#define UC_2 UC(0x0032)
82#define UC_3 UC(0x0033)
83#define UC_4 UC(0x0034)
84#define UC_5 UC(0x0035)
85#define UC_6 UC(0x0036)
86#define UC_7 UC(0x0037)
87#define UC_8 UC(0x0038)
88#define UC_9 UC(0x0039)
89
90#define UC_COLN UC(0x003A)
91#define UC_SCLN UC(0x003B)
92#define UC_LT UC(0x003C)
93#define UC_EQL UC(0x003D)
94#define UC_GT UC(0x003E)
95#define UC_QUES UC(0x003F)
96#define UC_AT UC(0x0040)
97
98#define UC_A UC(0x0041)
99#define UC_B UC(0x0042)
100#define UC_C UC(0x0043)
101#define UC_D UC(0x0044)
102#define UC_E UC(0x0045)
103#define UC_F UC(0x0046)
104#define UC_G UC(0x0047)
105#define UC_H UC(0x0048)
106#define UC_I UC(0x0049)
107#define UC_J UC(0x004A)
108#define UC_K UC(0x004B)
109#define UC_L UC(0x004C)
110#define UC_M UC(0x004D)
111#define UC_N UC(0x004E)
112#define UC_O UC(0x004F)
113#define UC_P UC(0x0050)
114#define UC_Q UC(0x0051)
115#define UC_R UC(0x0052)
116#define UC_S UC(0x0053)
117#define UC_T UC(0x0054)
118#define UC_U UC(0x0055)
119#define UC_V UC(0x0056)
120#define UC_W UC(0x0057)
121#define UC_X UC(0x0058)
122#define UC_Y UC(0x0059)
123#define UC_Z UC(0x005A)
124
125#define UC_LBRC UC(0x005B)
126#define UC_BSLS UC(0x005C)
127#define UC_RBRC UC(0x005D)
128#define UC_CIRM UC(0x005E)
129#define UC_UNDR UC(0x005F)
130
131#define UC_GRV UC(0x0060)
132
133#define UC_a UC(0x0061)
134#define UC_b UC(0x0062)
135#define UC_c UC(0x0063)
136#define UC_d UC(0x0064)
137#define UC_e UC(0x0065)
138#define UC_f UC(0x0066)
139#define UC_g UC(0x0067)
140#define UC_h UC(0x0068)
141#define UC_i UC(0x0069)
142#define UC_j UC(0x006A)
143#define UC_k UC(0x006B)
144#define UC_l UC(0x006C)
145#define UC_m UC(0x006D)
146#define UC_n UC(0x006E)
147#define UC_o UC(0x006F)
148#define UC_p UC(0x0070)
149#define UC_q UC(0x0071)
150#define UC_r UC(0x0072)
151#define UC_s UC(0x0073)
152#define UC_t UC(0x0074)
153#define UC_u UC(0x0075)
154#define UC_v UC(0x0076)
155#define UC_w UC(0x0077)
156#define UC_x UC(0x0078)
157#define UC_y UC(0x0079)
158#define UC_z UC(0x007A)
159
160#define UC_LCBR UC(0x007B)
161#define UC_PIPE UC(0x007C)
162#define UC_RCBR UC(0x007D)
163#define UC_TILD UC(0x007E)
164#define UC_DEL UC(0x007F)
165
166#endif 24#endif
diff --git a/quantum/process_keycode/process_unicode_common.c b/quantum/process_keycode/process_unicode_common.c
new file mode 100644
index 000000000..6012b4f07
--- /dev/null
+++ b/quantum/process_keycode/process_unicode_common.c
@@ -0,0 +1,101 @@
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_unicode_common.h"
18
19uint8_t mods;
20
21void set_unicode_input_mode(uint8_t os_target)
22{
23 input_mode = os_target;
24}
25
26uint8_t get_unicode_input_mode(void) {
27 return input_mode;
28}
29
30__attribute__((weak))
31void unicode_input_start (void) {
32 // save current mods
33 mods = keyboard_report->mods;
34
35 // unregister all mods to start from clean state
36 if (mods & MOD_BIT(KC_LSFT)) unregister_code(KC_LSFT);
37 if (mods & MOD_BIT(KC_RSFT)) unregister_code(KC_RSFT);
38 if (mods & MOD_BIT(KC_LCTL)) unregister_code(KC_LCTL);
39 if (mods & MOD_BIT(KC_RCTL)) unregister_code(KC_RCTL);
40 if (mods & MOD_BIT(KC_LALT)) unregister_code(KC_LALT);
41 if (mods & MOD_BIT(KC_RALT)) unregister_code(KC_RALT);
42 if (mods & MOD_BIT(KC_LGUI)) unregister_code(KC_LGUI);
43 if (mods & MOD_BIT(KC_RGUI)) unregister_code(KC_RGUI);
44
45 switch(input_mode) {
46 case UC_OSX:
47 register_code(KC_LALT);
48 break;
49 case UC_LNX:
50 register_code(KC_LCTL);
51 register_code(KC_LSFT);
52 register_code(KC_U);
53 unregister_code(KC_U);
54 unregister_code(KC_LSFT);
55 unregister_code(KC_LCTL);
56 break;
57 case UC_WIN:
58 register_code(KC_LALT);
59 register_code(KC_PPLS);
60 unregister_code(KC_PPLS);
61 break;
62 case UC_WINC:
63 register_code(KC_RALT);
64 unregister_code(KC_RALT);
65 register_code(KC_U);
66 unregister_code(KC_U);
67 }
68 wait_ms(UNICODE_TYPE_DELAY);
69}
70
71__attribute__((weak))
72void unicode_input_finish (void) {
73 switch(input_mode) {
74 case UC_OSX:
75 case UC_WIN:
76 unregister_code(KC_LALT);
77 break;
78 case UC_LNX:
79 register_code(KC_SPC);
80 unregister_code(KC_SPC);
81 break;
82 }
83
84 // reregister previously set mods
85 if (mods & MOD_BIT(KC_LSFT)) register_code(KC_LSFT);
86 if (mods & MOD_BIT(KC_RSFT)) register_code(KC_RSFT);
87 if (mods & MOD_BIT(KC_LCTL)) register_code(KC_LCTL);
88 if (mods & MOD_BIT(KC_RCTL)) register_code(KC_RCTL);
89 if (mods & MOD_BIT(KC_LALT)) register_code(KC_LALT);
90 if (mods & MOD_BIT(KC_RALT)) register_code(KC_RALT);
91 if (mods & MOD_BIT(KC_LGUI)) register_code(KC_LGUI);
92 if (mods & MOD_BIT(KC_RGUI)) register_code(KC_RGUI);
93}
94
95void register_hex(uint16_t hex) {
96 for(int i = 3; i >= 0; i--) {
97 uint8_t digit = ((hex >> (i*4)) & 0xF);
98 register_code(hex_to_keycode(digit));
99 unregister_code(hex_to_keycode(digit));
100 }
101}
diff --git a/quantum/process_keycode/process_unicode_common.h b/quantum/process_keycode/process_unicode_common.h
new file mode 100644
index 000000000..f5be1da5c
--- /dev/null
+++ b/quantum/process_keycode/process_unicode_common.h
@@ -0,0 +1,148 @@
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_UNICODE_COMMON_H
18#define PROCESS_UNICODE_COMMON_H
19
20#include "quantum.h"
21
22#ifndef UNICODE_TYPE_DELAY
23#define UNICODE_TYPE_DELAY 10
24#endif
25
26__attribute__ ((unused))
27static uint8_t input_mode;
28
29void set_unicode_input_mode(uint8_t os_target);
30uint8_t get_unicode_input_mode(void);
31void unicode_input_start(void);
32void unicode_input_finish(void);
33void register_hex(uint16_t hex);
34
35#define UC_OSX 0 // Mac OS X
36#define UC_LNX 1 // Linux
37#define UC_WIN 2 // Windows 'HexNumpad'
38#define UC_BSD 3 // BSD (not implemented)
39#define UC_WINC 4 // WinCompose https://github.com/samhocevar/wincompose
40
41#define UC_BSPC UC(0x0008)
42
43#define UC_SPC UC(0x0020)
44
45#define UC_EXLM UC(0x0021)
46#define UC_DQUT UC(0x0022)
47#define UC_HASH UC(0x0023)
48#define UC_DLR UC(0x0024)
49#define UC_PERC UC(0x0025)
50#define UC_AMPR UC(0x0026)
51#define UC_QUOT UC(0x0027)
52#define UC_LPRN UC(0x0028)
53#define UC_RPRN UC(0x0029)
54#define UC_ASTR UC(0x002A)
55#define UC_PLUS UC(0x002B)
56#define UC_COMM UC(0x002C)
57#define UC_DASH UC(0x002D)
58#define UC_DOT UC(0x002E)
59#define UC_SLSH UC(0x002F)
60
61#define UC_0 UC(0x0030)
62#define UC_1 UC(0x0031)
63#define UC_2 UC(0x0032)
64#define UC_3 UC(0x0033)
65#define UC_4 UC(0x0034)
66#define UC_5 UC(0x0035)
67#define UC_6 UC(0x0036)
68#define UC_7 UC(0x0037)
69#define UC_8 UC(0x0038)
70#define UC_9 UC(0x0039)
71
72#define UC_COLN UC(0x003A)
73#define UC_SCLN UC(0x003B)
74#define UC_LT UC(0x003C)
75#define UC_EQL UC(0x003D)
76#define UC_GT UC(0x003E)
77#define UC_QUES UC(0x003F)
78#define UC_AT UC(0x0040)
79
80#define UC_A UC(0x0041)
81#define UC_B UC(0x0042)
82#define UC_C UC(0x0043)
83#define UC_D UC(0x0044)
84#define UC_E UC(0x0045)
85#define UC_F UC(0x0046)
86#define UC_G UC(0x0047)
87#define UC_H UC(0x0048)
88#define UC_I UC(0x0049)
89#define UC_J UC(0x004A)
90#define UC_K UC(0x004B)
91#define UC_L UC(0x004C)
92#define UC_M UC(0x004D)
93#define UC_N UC(0x004E)
94#define UC_O UC(0x004F)
95#define UC_P UC(0x0050)
96#define UC_Q UC(0x0051)
97#define UC_R UC(0x0052)
98#define UC_S UC(0x0053)
99#define UC_T UC(0x0054)
100#define UC_U UC(0x0055)
101#define UC_V UC(0x0056)
102#define UC_W UC(0x0057)
103#define UC_X UC(0x0058)
104#define UC_Y UC(0x0059)
105#define UC_Z UC(0x005A)
106
107#define UC_LBRC UC(0x005B)
108#define UC_BSLS UC(0x005C)
109#define UC_RBRC UC(0x005D)
110#define UC_CIRM UC(0x005E)
111#define UC_UNDR UC(0x005F)
112
113#define UC_GRV UC(0x0060)
114
115#define UC_a UC(0x0061)
116#define UC_b UC(0x0062)
117#define UC_c UC(0x0063)
118#define UC_d UC(0x0064)
119#define UC_e UC(0x0065)
120#define UC_f UC(0x0066)
121#define UC_g UC(0x0067)
122#define UC_h UC(0x0068)
123#define UC_i UC(0x0069)
124#define UC_j UC(0x006A)
125#define UC_k UC(0x006B)
126#define UC_l UC(0x006C)
127#define UC_m UC(0x006D)
128#define UC_n UC(0x006E)
129#define UC_o UC(0x006F)
130#define UC_p UC(0x0070)
131#define UC_q UC(0x0071)
132#define UC_r UC(0x0072)
133#define UC_s UC(0x0073)
134#define UC_t UC(0x0074)
135#define UC_u UC(0x0075)
136#define UC_v UC(0x0076)
137#define UC_w UC(0x0077)
138#define UC_x UC(0x0078)
139#define UC_y UC(0x0079)
140#define UC_z UC(0x007A)
141
142#define UC_LCBR UC(0x007B)
143#define UC_PIPE UC(0x007C)
144#define UC_RCBR UC(0x007D)
145#define UC_TILD UC(0x007E)
146#define UC_DEL UC(0x007F)
147
148#endif
diff --git a/quantum/process_keycode/process_unicodemap.c b/quantum/process_keycode/process_unicodemap.c
new file mode 100644
index 000000000..0227fbdd7
--- /dev/null
+++ b/quantum/process_keycode/process_unicodemap.c
@@ -0,0 +1,72 @@
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_unicodemap.h"
18#include "process_unicode_common.h"
19
20__attribute__((weak))
21const uint32_t PROGMEM unicode_map[] = {
22};
23
24void register_hex32(uint32_t hex) {
25 bool onzerostart = true;
26 for(int i = 7; i >= 0; i--) {
27 if (i <= 3) {
28 onzerostart = false;
29 }
30 uint8_t digit = ((hex >> (i*4)) & 0xF);
31 if (digit == 0) {
32 if (!onzerostart) {
33 register_code(hex_to_keycode(digit));
34 unregister_code(hex_to_keycode(digit));
35 }
36 } else {
37 register_code(hex_to_keycode(digit));
38 unregister_code(hex_to_keycode(digit));
39 onzerostart = false;
40 }
41 }
42}
43
44__attribute__((weak))
45void unicode_map_input_error() {}
46
47bool process_unicode_map(uint16_t keycode, keyrecord_t *record) {
48 uint8_t input_mode = get_unicode_input_mode();
49 if ((keycode & QK_UNICODE_MAP) == QK_UNICODE_MAP && record->event.pressed) {
50 const uint32_t* map = unicode_map;
51 uint16_t index = keycode - QK_UNICODE_MAP;
52 uint32_t code = pgm_read_dword_far(&map[index]);
53 if (code > 0xFFFF && code <= 0x10ffff && input_mode == UC_OSX) {
54 // Convert to UTF-16 surrogate pair
55 code -= 0x10000;
56 uint32_t lo = code & 0x3ff;
57 uint32_t hi = (code & 0xffc00) >> 10;
58 unicode_input_start();
59 register_hex32(hi + 0xd800);
60 register_hex32(lo + 0xdc00);
61 unicode_input_finish();
62 } else if ((code > 0x10ffff && input_mode == UC_OSX) || (code > 0xFFFFF && input_mode == UC_LNX)) {
63 // when character is out of range supported by the OS
64 unicode_map_input_error();
65 } else {
66 unicode_input_start();
67 register_hex32(code);
68 unicode_input_finish();
69 }
70 }
71 return true;
72}
diff --git a/quantum/process_keycode/process_unicodemap.h b/quantum/process_keycode/process_unicodemap.h
new file mode 100644
index 000000000..929c88c0b
--- /dev/null
+++ b/quantum/process_keycode/process_unicodemap.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_UNICODEMAP_H
18#define PROCESS_UNICODEMAP_H
19
20#include "quantum.h"
21#include "process_unicode_common.h"
22
23void unicode_map_input_error(void);
24bool process_unicode_map(uint16_t keycode, keyrecord_t *record);
25#endif
diff --git a/quantum/quantum.c b/quantum/quantum.c
index 098312e6e..62d9ef923 100644
--- a/quantum/quantum.c
+++ b/quantum/quantum.c
@@ -1,4 +1,34 @@
1/* Copyright 2016-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
1#include "quantum.h" 17#include "quantum.h"
18#ifdef PROTOCOL_LUFA
19#include "outputselect.h"
20#endif
21
22#ifndef TAPPING_TERM
23#define TAPPING_TERM 200
24#endif
25
26#include "backlight.h"
27extern backlight_config_t backlight_config;
28
29#ifdef FAUXCLICKY_ENABLE
30#include "fauxclicky.h"
31#endif
2 32
3static void do_code16 (uint16_t code, void (*f) (uint8_t)) { 33static void do_code16 (uint16_t code, void (*f) (uint8_t)) {
4 switch (code) { 34 switch (code) {
@@ -17,6 +47,8 @@ static void do_code16 (uint16_t code, void (*f) (uint8_t)) {
17 if (code & QK_LGUI) 47 if (code & QK_LGUI)
18 f(KC_LGUI); 48 f(KC_LGUI);
19 49
50 if (code < QK_RMODS_MIN) return;
51
20 if (code & QK_RCTL) 52 if (code & QK_RCTL)
21 f(KC_RCTL); 53 f(KC_RCTL);
22 if (code & QK_RSFT) 54 if (code & QK_RSFT)
@@ -27,14 +59,42 @@ static void do_code16 (uint16_t code, void (*f) (uint8_t)) {
27 f(KC_RGUI); 59 f(KC_RGUI);
28} 60}
29 61
62static inline void qk_register_weak_mods(uint8_t kc) {
63 add_weak_mods(MOD_BIT(kc));
64 send_keyboard_report();
65}
66
67static inline void qk_unregister_weak_mods(uint8_t kc) {
68 del_weak_mods(MOD_BIT(kc));
69 send_keyboard_report();
70}
71
72static inline void qk_register_mods(uint8_t kc) {
73 add_weak_mods(MOD_BIT(kc));
74 send_keyboard_report();
75}
76
77static inline void qk_unregister_mods(uint8_t kc) {
78 del_weak_mods(MOD_BIT(kc));
79 send_keyboard_report();
80}
81
30void register_code16 (uint16_t code) { 82void register_code16 (uint16_t code) {
31 do_code16 (code, register_code); 83 if (IS_MOD(code) || code == KC_NO) {
84 do_code16 (code, qk_register_mods);
85 } else {
86 do_code16 (code, qk_register_weak_mods);
87 }
32 register_code (code); 88 register_code (code);
33} 89}
34 90
35void unregister_code16 (uint16_t code) { 91void unregister_code16 (uint16_t code) {
36 unregister_code (code); 92 unregister_code (code);
37 do_code16 (code, unregister_code); 93 if (IS_MOD(code) || code == KC_NO) {
94 do_code16 (code, qk_unregister_mods);
95 } else {
96 do_code16 (code, qk_unregister_weak_mods);
97 }
38} 98}
39 99
40__attribute__ ((weak)) 100__attribute__ ((weak))
@@ -54,8 +114,8 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
54 114
55void reset_keyboard(void) { 115void reset_keyboard(void) {
56 clear_keyboard(); 116 clear_keyboard();
57#ifdef AUDIO_ENABLE 117#if defined(AUDIO_ENABLE) || (defined(MIDI_ENABLE) && defined(MIDI_ENABLE_BASIC))
58 stop_all_notes(); 118 music_all_notes_off();
59 shutdown_user(); 119 shutdown_user();
60#endif 120#endif
61 wait_ms(250); 121 wait_ms(250);
@@ -75,6 +135,7 @@ void reset_keyboard(void) {
75#endif 135#endif
76 136
77static bool shift_interrupted[2] = {0, 0}; 137static bool shift_interrupted[2] = {0, 0};
138static uint16_t scs_timer = 0;
78 139
79bool process_record_quantum(keyrecord_t *record) { 140bool process_record_quantum(keyrecord_t *record) {
80 141
@@ -108,10 +169,13 @@ bool process_record_quantum(keyrecord_t *record) {
108 169
109 if (!( 170 if (!(
110 process_record_kb(keycode, record) && 171 process_record_kb(keycode, record) &&
111 #ifdef MIDI_ENABLE 172 #if defined(MIDI_ENABLE) && defined(MIDI_ADVANCED)
112 process_midi(keycode, record) && 173 process_midi(keycode, record) &&
113 #endif 174 #endif
114 #ifdef AUDIO_ENABLE 175 #ifdef AUDIO_ENABLE
176 process_audio(keycode, record) &&
177 #endif
178 #if defined(AUDIO_ENABLE) || (defined(MIDI_ENABLE) && defined(MIDI_BASIC))
115 process_music(keycode, record) && 179 process_music(keycode, record) &&
116 #endif 180 #endif
117 #ifdef TAP_DANCE_ENABLE 181 #ifdef TAP_DANCE_ENABLE
@@ -123,12 +187,18 @@ bool process_record_quantum(keyrecord_t *record) {
123 #ifndef DISABLE_CHORDING 187 #ifndef DISABLE_CHORDING
124 process_chording(keycode, record) && 188 process_chording(keycode, record) &&
125 #endif 189 #endif
190 #ifdef COMBO_ENABLE
191 process_combo(keycode, record) &&
192 #endif
126 #ifdef UNICODE_ENABLE 193 #ifdef UNICODE_ENABLE
127 process_unicode(keycode, record) && 194 process_unicode(keycode, record) &&
128 #endif 195 #endif
129 #ifdef UCIS_ENABLE 196 #ifdef UCIS_ENABLE
130 process_ucis(keycode, record) && 197 process_ucis(keycode, record) &&
131 #endif 198 #endif
199 #ifdef PRINTING_ENABLE
200 process_printer(keycode, record) &&
201 #endif
132 #ifdef UNICODEMAP_ENABLE 202 #ifdef UNICODEMAP_ENABLE
133 process_unicode_map(keycode, record) && 203 process_unicode_map(keycode, record) &&
134 #endif 204 #endif
@@ -152,6 +222,26 @@ bool process_record_quantum(keyrecord_t *record) {
152 } 222 }
153 return false; 223 return false;
154 break; 224 break;
225 #ifdef FAUXCLICKY_ENABLE
226 case FC_TOG:
227 if (record->event.pressed) {
228 FAUXCLICKY_TOGGLE;
229 }
230 return false;
231 break;
232 case FC_ON:
233 if (record->event.pressed) {
234 FAUXCLICKY_ON;
235 }
236 return false;
237 break;
238 case FC_OFF:
239 if (record->event.pressed) {
240 FAUXCLICKY_OFF;
241 }
242 return false;
243 break;
244 #endif
155 #ifdef RGBLIGHT_ENABLE 245 #ifdef RGBLIGHT_ENABLE
156 case RGB_TOG: 246 case RGB_TOG:
157 if (record->event.pressed) { 247 if (record->event.pressed) {
@@ -202,6 +292,28 @@ bool process_record_quantum(keyrecord_t *record) {
202 return false; 292 return false;
203 break; 293 break;
204 #endif 294 #endif
295 #ifdef PROTOCOL_LUFA
296 case OUT_AUTO:
297 if (record->event.pressed) {
298 set_output(OUTPUT_AUTO);
299 }
300 return false;
301 break;
302 case OUT_USB:
303 if (record->event.pressed) {
304 set_output(OUTPUT_USB);
305 }
306 return false;
307 break;
308 #ifdef BLUETOOTH_ENABLE
309 case OUT_BT:
310 if (record->event.pressed) {
311 set_output(OUTPUT_BLUETOOTH);
312 }
313 return false;
314 break;
315 #endif
316 #endif
205 case MAGIC_SWAP_CONTROL_CAPSLOCK ... MAGIC_TOGGLE_NKRO: 317 case MAGIC_SWAP_CONTROL_CAPSLOCK ... MAGIC_TOGGLE_NKRO:
206 if (record->event.pressed) { 318 if (record->event.pressed) {
207 // MAGIC actions (BOOTMAGIC without the boot) 319 // MAGIC actions (BOOTMAGIC without the boot)
@@ -283,6 +395,7 @@ bool process_record_quantum(keyrecord_t *record) {
283 case KC_LSPO: { 395 case KC_LSPO: {
284 if (record->event.pressed) { 396 if (record->event.pressed) {
285 shift_interrupted[0] = false; 397 shift_interrupted[0] = false;
398 scs_timer = timer_read ();
286 register_mods(MOD_BIT(KC_LSFT)); 399 register_mods(MOD_BIT(KC_LSFT));
287 } 400 }
288 else { 401 else {
@@ -292,7 +405,7 @@ bool process_record_quantum(keyrecord_t *record) {
292 shift_interrupted[1] = true; 405 shift_interrupted[1] = true;
293 } 406 }
294 #endif 407 #endif
295 if (!shift_interrupted[0]) { 408 if (!shift_interrupted[0] && timer_elapsed(scs_timer) < TAPPING_TERM) {
296 register_code(LSPO_KEY); 409 register_code(LSPO_KEY);
297 unregister_code(LSPO_KEY); 410 unregister_code(LSPO_KEY);
298 } 411 }
@@ -305,6 +418,7 @@ bool process_record_quantum(keyrecord_t *record) {
305 case KC_RSPC: { 418 case KC_RSPC: {
306 if (record->event.pressed) { 419 if (record->event.pressed) {
307 shift_interrupted[1] = false; 420 shift_interrupted[1] = false;
421 scs_timer = timer_read ();
308 register_mods(MOD_BIT(KC_RSFT)); 422 register_mods(MOD_BIT(KC_RSFT));
309 } 423 }
310 else { 424 else {
@@ -314,7 +428,7 @@ bool process_record_quantum(keyrecord_t *record) {
314 shift_interrupted[1] = true; 428 shift_interrupted[1] = true;
315 } 429 }
316 #endif 430 #endif
317 if (!shift_interrupted[1]) { 431 if (!shift_interrupted[1] && timer_elapsed(scs_timer) < TAPPING_TERM) {
318 register_code(RSPC_KEY); 432 register_code(RSPC_KEY);
319 unregister_code(RSPC_KEY); 433 unregister_code(RSPC_KEY);
320 } 434 }
@@ -496,6 +610,15 @@ void matrix_scan_quantum() {
496 #ifdef TAP_DANCE_ENABLE 610 #ifdef TAP_DANCE_ENABLE
497 matrix_scan_tap_dance(); 611 matrix_scan_tap_dance();
498 #endif 612 #endif
613
614 #ifdef COMBO_ENABLE
615 matrix_scan_combo();
616 #endif
617
618 #if defined(BACKLIGHT_ENABLE) && defined(BACKLIGHT_PIN)
619 backlight_task();
620 #endif
621
499 matrix_scan_kb(); 622 matrix_scan_kb();
500} 623}
501 624
@@ -513,34 +636,45 @@ static const uint8_t backlight_pin = BACKLIGHT_PIN;
513# define COM1x1 COM1A1 636# define COM1x1 COM1A1
514# define OCR1x OCR1A 637# define OCR1x OCR1A
515#else 638#else
516# error "Backlight pin not supported - use B5, B6, or B7" 639# define NO_BACKLIGHT_CLOCK
640#endif
641
642#ifndef BACKLIGHT_ON_STATE
643#define BACKLIGHT_ON_STATE 0
517#endif 644#endif
518 645
519__attribute__ ((weak)) 646__attribute__ ((weak))
520void backlight_init_ports(void) 647void backlight_init_ports(void)
521{ 648{
522 649
523 // Setup backlight pin as output and output low. 650 // Setup backlight pin as output and output to on state.
524 // DDRx |= n 651 // DDRx |= n
525 _SFR_IO8((backlight_pin >> 4) + 1) |= _BV(backlight_pin & 0xF); 652 _SFR_IO8((backlight_pin >> 4) + 1) |= _BV(backlight_pin & 0xF);
526 // PORTx &= ~n 653 #if BACKLIGHT_ON_STATE == 0
527 _SFR_IO8((backlight_pin >> 4) + 2) &= ~_BV(backlight_pin & 0xF); 654 // PORTx &= ~n
655 _SFR_IO8((backlight_pin >> 4) + 2) &= ~_BV(backlight_pin & 0xF);
656 #else
657 // PORTx |= n
658 _SFR_IO8((backlight_pin >> 4) + 2) |= _BV(backlight_pin & 0xF);
659 #endif
528 660
529 // Use full 16-bit resolution. 661 #ifndef NO_BACKLIGHT_CLOCK
530 ICR1 = 0xFFFF; 662 // Use full 16-bit resolution.
663 ICR1 = 0xFFFF;
531 664
532 // I could write a wall of text here to explain... but TL;DW 665 // I could write a wall of text here to explain... but TL;DW
533 // Go read the ATmega32u4 datasheet. 666 // Go read the ATmega32u4 datasheet.
534 // And this: http://blog.saikoled.com/post/43165849837/secret-konami-cheat-code-to-high-resolution-pwm-on 667 // And this: http://blog.saikoled.com/post/43165849837/secret-konami-cheat-code-to-high-resolution-pwm-on
535 668
536 // Pin PB7 = OCR1C (Timer 1, Channel C) 669 // Pin PB7 = OCR1C (Timer 1, Channel C)
537 // Compare Output Mode = Clear on compare match, Channel C = COM1C1=1 COM1C0=0 670 // Compare Output Mode = Clear on compare match, Channel C = COM1C1=1 COM1C0=0
538 // (i.e. start high, go low when counter matches.) 671 // (i.e. start high, go low when counter matches.)
539 // WGM Mode 14 (Fast PWM) = WGM13=1 WGM12=1 WGM11=1 WGM10=0 672 // WGM Mode 14 (Fast PWM) = WGM13=1 WGM12=1 WGM11=1 WGM10=0
540 // Clock Select = clk/1 (no prescaling) = CS12=0 CS11=0 CS10=1 673 // Clock Select = clk/1 (no prescaling) = CS12=0 CS11=0 CS10=1
541 674
542 TCCR1A = _BV(COM1x1) | _BV(WGM11); // = 0b00001010; 675 TCCR1A = _BV(COM1x1) | _BV(WGM11); // = 0b00001010;
543 TCCR1B = _BV(WGM13) | _BV(WGM12) | _BV(CS10); // = 0b00011001; 676 TCCR1B = _BV(WGM13) | _BV(WGM12) | _BV(CS10); // = 0b00011001;
677 #endif
544 678
545 backlight_init(); 679 backlight_init();
546 #ifdef BACKLIGHT_BREATHING 680 #ifdef BACKLIGHT_BREATHING
@@ -552,30 +686,73 @@ __attribute__ ((weak))
552void backlight_set(uint8_t level) 686void backlight_set(uint8_t level)
553{ 687{
554 // Prevent backlight blink on lowest level 688 // Prevent backlight blink on lowest level
555 // PORTx &= ~n 689 // #if BACKLIGHT_ON_STATE == 0
556 _SFR_IO8((backlight_pin >> 4) + 2) &= ~_BV(backlight_pin & 0xF); 690 // // PORTx &= ~n
691 // _SFR_IO8((backlight_pin >> 4) + 2) &= ~_BV(backlight_pin & 0xF);
692 // #else
693 // // PORTx |= n
694 // _SFR_IO8((backlight_pin >> 4) + 2) |= _BV(backlight_pin & 0xF);
695 // #endif
557 696
558 if ( level == 0 ) { 697 if ( level == 0 ) {
559 // Turn off PWM control on backlight pin, revert to output low. 698 #ifndef NO_BACKLIGHT_CLOCK
560 TCCR1A &= ~(_BV(COM1x1)); 699 // Turn off PWM control on backlight pin, revert to output low.
561 OCR1x = 0x0; 700 TCCR1A &= ~(_BV(COM1x1));
562 } else if ( level == BACKLIGHT_LEVELS ) { 701 OCR1x = 0x0;
563 // Turn on PWM control of backlight pin 702 #else
564 TCCR1A |= _BV(COM1x1); 703 // #if BACKLIGHT_ON_STATE == 0
565 // Set the brightness 704 // // PORTx |= n
566 OCR1x = 0xFFFF; 705 // _SFR_IO8((backlight_pin >> 4) + 2) |= _BV(backlight_pin & 0xF);
567 } else { 706 // #else
568 // Turn on PWM control of backlight pin 707 // // PORTx &= ~n
569 TCCR1A |= _BV(COM1x1); 708 // _SFR_IO8((backlight_pin >> 4) + 2) &= ~_BV(backlight_pin & 0xF);
570 // Set the brightness 709 // #endif
571 OCR1x = 0xFFFF >> ((BACKLIGHT_LEVELS - level) * ((BACKLIGHT_LEVELS + 1) / 2)); 710 #endif
572 } 711 }
712 #ifndef NO_BACKLIGHT_CLOCK
713 else if ( level == BACKLIGHT_LEVELS ) {
714 // Turn on PWM control of backlight pin
715 TCCR1A |= _BV(COM1x1);
716 // Set the brightness
717 OCR1x = 0xFFFF;
718 }
719 else {
720 // Turn on PWM control of backlight pin
721 TCCR1A |= _BV(COM1x1);
722 // Set the brightness
723 OCR1x = 0xFFFF >> ((BACKLIGHT_LEVELS - level) * ((BACKLIGHT_LEVELS + 1) / 2));
724 }
725 #endif
573 726
574 #ifdef BACKLIGHT_BREATHING 727 #ifdef BACKLIGHT_BREATHING
575 breathing_intensity_default(); 728 breathing_intensity_default();
576 #endif 729 #endif
577} 730}
578 731
732uint8_t backlight_tick = 0;
733
734void backlight_task(void) {
735 #ifdef NO_BACKLIGHT_CLOCK
736 if ((0xFFFF >> ((BACKLIGHT_LEVELS - backlight_config.level) * ((BACKLIGHT_LEVELS + 1) / 2))) & (1 << backlight_tick)) {
737 #if BACKLIGHT_ON_STATE == 0
738 // PORTx &= ~n
739 _SFR_IO8((backlight_pin >> 4) + 2) &= ~_BV(backlight_pin & 0xF);
740 #else
741 // PORTx |= n
742 _SFR_IO8((backlight_pin >> 4) + 2) |= _BV(backlight_pin & 0xF);
743 #endif
744 } else {
745 #if BACKLIGHT_ON_STATE == 0
746 // PORTx |= n
747 _SFR_IO8((backlight_pin >> 4) + 2) |= _BV(backlight_pin & 0xF);
748 #else
749 // PORTx &= ~n
750 _SFR_IO8((backlight_pin >> 4) + 2) &= ~_BV(backlight_pin & 0xF);
751 #endif
752 }
753 backlight_tick = (backlight_tick + 1) % 16;
754 #endif
755}
579 756
580#ifdef BACKLIGHT_BREATHING 757#ifdef BACKLIGHT_BREATHING
581 758
@@ -799,6 +976,64 @@ void backlight_set(uint8_t level)
799#endif // backlight 976#endif // backlight
800 977
801 978
979// Functions for spitting out values
980//
981
982void send_dword(uint32_t number) { // this might not actually work
983 uint16_t word = (number >> 16);
984 send_word(word);
985 send_word(number & 0xFFFFUL);
986}
987
988void send_word(uint16_t number) {
989 uint8_t byte = number >> 8;
990 send_byte(byte);
991 send_byte(number & 0xFF);
992}
993
994void send_byte(uint8_t number) {
995 uint8_t nibble = number >> 4;
996 send_nibble(nibble);
997 send_nibble(number & 0xF);
998}
999
1000void send_nibble(uint8_t number) {
1001 switch (number) {
1002 case 0:
1003 register_code(KC_0);
1004 unregister_code(KC_0);
1005 break;
1006 case 1 ... 9:
1007 register_code(KC_1 + (number - 1));
1008 unregister_code(KC_1 + (number - 1));
1009 break;
1010 case 0xA ... 0xF:
1011 register_code(KC_A + (number - 0xA));
1012 unregister_code(KC_A + (number - 0xA));
1013 break;
1014 }
1015}
1016
1017
1018__attribute__((weak))
1019uint16_t hex_to_keycode(uint8_t hex)
1020{
1021 if (hex == 0x0) {
1022 return KC_0;
1023 } else if (hex < 0xA) {
1024 return KC_1 + (hex - 0x1);
1025 } else {
1026 return KC_A + (hex - 0xA);
1027 }
1028}
1029
1030void api_send_unicode(uint32_t unicode) {
1031#ifdef API_ENABLE
1032 uint8_t chunk[4];
1033 dword_to_bytes(unicode, chunk);
1034 MT_SEND_DATA(DT_UNICODE, chunk, 5);
1035#endif
1036}
802 1037
803__attribute__ ((weak)) 1038__attribute__ ((weak))
804void led_set_user(uint8_t usb_led) { 1039void led_set_user(uint8_t usb_led) {
diff --git a/quantum/quantum.h b/quantum/quantum.h
index 0c6046649..2bf18d095 100644
--- a/quantum/quantum.h
+++ b/quantum/quantum.h
@@ -1,3 +1,18 @@
1/* Copyright 2016-2017 Erez Zukerman, 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 */
1#ifndef QUANTUM_H 16#ifndef QUANTUM_H
2#define QUANTUM_H 17#define QUANTUM_H
3 18
@@ -15,7 +30,6 @@
15#ifdef RGBLIGHT_ENABLE 30#ifdef RGBLIGHT_ENABLE
16 #include "rgblight.h" 31 #include "rgblight.h"
17#endif 32#endif
18
19#include "action_layer.h" 33#include "action_layer.h"
20#include "eeconfig.h" 34#include "eeconfig.h"
21#include <stddef.h> 35#include <stddef.h>
@@ -36,11 +50,16 @@ extern uint32_t default_layer_state;
36 50
37#ifdef MIDI_ENABLE 51#ifdef MIDI_ENABLE
38 #include <lufa.h> 52 #include <lufa.h>
53#ifdef MIDI_ADVANCED
39 #include "process_midi.h" 54 #include "process_midi.h"
40#endif 55#endif
56#endif // MIDI_ENABLE
41 57
42#ifdef AUDIO_ENABLE 58#ifdef AUDIO_ENABLE
43 #include "audio.h" 59 #include "process_audio.h"
60#endif
61
62#if defined(AUDIO_ENABLE) || (defined(MIDI_ENABLE) && defined(MIDI_BASIC))
44 #include "process_music.h" 63 #include "process_music.h"
45#endif 64#endif
46 65
@@ -57,8 +76,24 @@ extern uint32_t default_layer_state;
57 #include "process_unicode.h" 76 #include "process_unicode.h"
58#endif 77#endif
59 78
79#ifdef UCIS_ENABLE
80 #include "process_ucis.h"
81#endif
82
83#ifdef UNICODEMAP_ENABLE
84 #include "process_unicodemap.h"
85#endif
86
60#include "process_tap_dance.h" 87#include "process_tap_dance.h"
61 88
89#ifdef PRINTING_ENABLE
90 #include "process_printer.h"
91#endif
92
93#ifdef COMBO_ENABLE
94 #include "process_combo.h"
95#endif
96
62#define SEND_STRING(str) send_string(PSTR(str)) 97#define SEND_STRING(str) send_string(PSTR(str))
63void send_string(const char *str); 98void send_string(const char *str);
64 99
@@ -88,6 +123,7 @@ void unregister_code16 (uint16_t code);
88 123
89#ifdef BACKLIGHT_ENABLE 124#ifdef BACKLIGHT_ENABLE
90void backlight_init_ports(void); 125void backlight_init_ports(void);
126void backlight_task(void);
91 127
92#ifdef BACKLIGHT_BREATHING 128#ifdef BACKLIGHT_BREATHING
93void breathing_enable(void); 129void breathing_enable(void);
@@ -106,8 +142,15 @@ void breathing_speed_dec(uint8_t value);
106#endif 142#endif
107 143
108#endif 144#endif
145void send_dword(uint32_t number);
146void send_word(uint16_t number);
147void send_byte(uint8_t number);
148void send_nibble(uint8_t number);
149uint16_t hex_to_keycode(uint8_t hex);
109 150
110void led_set_user(uint8_t usb_led); 151void led_set_user(uint8_t usb_led);
111void led_set_kb(uint8_t usb_led); 152void led_set_kb(uint8_t usb_led);
112 153
154void api_send_unicode(uint32_t unicode);
155
113#endif 156#endif
diff --git a/quantum/quantum_keycodes.h b/quantum/quantum_keycodes.h
new file mode 100644
index 000000000..7354ae0da
--- /dev/null
+++ b/quantum/quantum_keycodes.h
@@ -0,0 +1,600 @@
1/* Copyright 2016-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#ifndef QUANTUM_KEYCODES_H
17#define QUANTUM_KEYCODES_H
18
19#ifndef MIDI_ENABLE_STRICT
20#define MIDI_ENABLE_STRICT 0
21#endif
22
23#if !MIDI_ENABLE_STRICT || (defined(MIDI_ENABLE) && defined(MIDI_ADVANCED))
24#ifndef MIDI_TONE_KEYCODE_OCTAVES
25#define MIDI_TONE_KEYCODE_OCTAVES 3
26#endif
27#endif
28
29enum quantum_keycodes {
30 // Ranges used in shortucuts - not to be used directly
31 QK_TMK = 0x0000,
32 QK_TMK_MAX = 0x00FF,
33 QK_MODS = 0x0100,
34 QK_LCTL = 0x0100,
35 QK_LSFT = 0x0200,
36 QK_LALT = 0x0400,
37 QK_LGUI = 0x0800,
38 QK_RMODS_MIN = 0x1000,
39 QK_RCTL = 0x1100,
40 QK_RSFT = 0x1200,
41 QK_RALT = 0x1400,
42 QK_RGUI = 0x1800,
43 QK_MODS_MAX = 0x1FFF,
44 QK_FUNCTION = 0x2000,
45 QK_FUNCTION_MAX = 0x2FFF,
46 QK_MACRO = 0x3000,
47 QK_MACRO_MAX = 0x3FFF,
48 QK_LAYER_TAP = 0x4000,
49 QK_LAYER_TAP_MAX = 0x4FFF,
50 QK_TO = 0x5000,
51 QK_TO_MAX = 0x50FF,
52 QK_MOMENTARY = 0x5100,
53 QK_MOMENTARY_MAX = 0x51FF,
54 QK_DEF_LAYER = 0x5200,
55 QK_DEF_LAYER_MAX = 0x52FF,
56 QK_TOGGLE_LAYER = 0x5300,
57 QK_TOGGLE_LAYER_MAX = 0x53FF,
58 QK_ONE_SHOT_LAYER = 0x5400,
59 QK_ONE_SHOT_LAYER_MAX = 0x54FF,
60 QK_ONE_SHOT_MOD = 0x5500,
61 QK_ONE_SHOT_MOD_MAX = 0x55FF,
62#ifndef DISABLE_CHORDING
63 QK_CHORDING = 0x5600,
64 QK_CHORDING_MAX = 0x56FF,
65#endif
66 QK_TAP_DANCE = 0x5700,
67 QK_TAP_DANCE_MAX = 0x57FF,
68 QK_LAYER_TAP_TOGGLE = 0x5800,
69 QK_LAYER_TAP_TOGGLE_MAX = 0x58FF,
70 QK_MOD_TAP = 0x6000,
71 QK_MOD_TAP_MAX = 0x7FFF,
72#if defined(UNICODEMAP_ENABLE) && defined(UNICODE_ENABLE)
73 #error "Cannot enable both UNICODEMAP && UNICODE"
74#endif
75#ifdef UNICODE_ENABLE
76 QK_UNICODE = 0x8000,
77 QK_UNICODE_MAX = 0xFFFF,
78#endif
79#ifdef UNICODEMAP_ENABLE
80 QK_UNICODE_MAP = 0x8000,
81 QK_UNICODE_MAP_MAX = 0x83FF,
82#endif
83
84 // Loose keycodes - to be used directly
85
86 RESET = 0x5C00,
87 DEBUG,
88 MAGIC_SWAP_CONTROL_CAPSLOCK,
89 MAGIC_CAPSLOCK_TO_CONTROL,
90 MAGIC_SWAP_LALT_LGUI,
91 MAGIC_SWAP_RALT_RGUI,
92 MAGIC_NO_GUI,
93 MAGIC_SWAP_GRAVE_ESC,
94 MAGIC_SWAP_BACKSLASH_BACKSPACE,
95 MAGIC_HOST_NKRO,
96 MAGIC_SWAP_ALT_GUI,
97 MAGIC_UNSWAP_CONTROL_CAPSLOCK,
98 MAGIC_UNCAPSLOCK_TO_CONTROL,
99 MAGIC_UNSWAP_LALT_LGUI,
100 MAGIC_UNSWAP_RALT_RGUI,
101 MAGIC_UNNO_GUI,
102 MAGIC_UNSWAP_GRAVE_ESC,
103 MAGIC_UNSWAP_BACKSLASH_BACKSPACE,
104 MAGIC_UNHOST_NKRO,
105 MAGIC_UNSWAP_ALT_GUI,
106 MAGIC_TOGGLE_NKRO,
107
108 // Leader key
109#ifndef DISABLE_LEADER
110 KC_LEAD,
111#endif
112
113 // Audio on/off/toggle
114 AU_ON,
115 AU_OFF,
116 AU_TOG,
117
118#ifdef FAUXCLICKY_ENABLE
119 // Faux clicky
120 FC_ON,
121 FC_OFF,
122 FC_TOG,
123#endif
124
125 // Music mode on/off/toggle
126 MU_ON,
127 MU_OFF,
128 MU_TOG,
129
130 // Music voice iterate
131 MUV_IN,
132 MUV_DE,
133
134 // Midi
135#if !MIDI_ENABLE_STRICT || (defined(MIDI_ENABLE) && defined(MIDI_BASIC))
136 MI_ON, // send midi notes when music mode is enabled
137 MI_OFF, // don't send midi notes when music mode is enabled
138#endif
139
140#if !MIDI_ENABLE_STRICT || (defined(MIDI_ENABLE) && defined(MIDI_ADVANCED))
141 MIDI_TONE_MIN,
142
143#if !MIDI_ENABLE_STRICT || MIDI_TONE_KEYCODE_OCTAVES > 0
144 MI_C = MIDI_TONE_MIN,
145 MI_Cs,
146 MI_Db = MI_Cs,
147 MI_D,
148 MI_Ds,
149 MI_Eb = MI_Ds,
150 MI_E,
151 MI_F,
152 MI_Fs,
153 MI_Gb = MI_Fs,
154 MI_G,
155 MI_Gs,
156 MI_Ab = MI_Gs,
157 MI_A,
158 MI_As,
159 MI_Bb = MI_As,
160 MI_B,
161#endif
162
163#if !MIDI_ENABLE_STRICT || MIDI_TONE_KEYCODE_OCTAVES > 1
164 MI_C_1,
165 MI_Cs_1,
166 MI_Db_1 = MI_Cs_1,
167 MI_D_1,
168 MI_Ds_1,
169 MI_Eb_1 = MI_Ds_1,
170 MI_E_1,
171 MI_F_1,
172 MI_Fs_1,
173 MI_Gb_1 = MI_Fs_1,
174 MI_G_1,
175 MI_Gs_1,
176 MI_Ab_1 = MI_Gs_1,
177 MI_A_1,
178 MI_As_1,
179 MI_Bb_1 = MI_As_1,
180 MI_B_1,
181#endif
182
183#if !MIDI_ENABLE_STRICT || MIDI_TONE_KEYCODE_OCTAVES > 2
184 MI_C_2,
185 MI_Cs_2,
186 MI_Db_2 = MI_Cs_2,
187 MI_D_2,
188 MI_Ds_2,
189 MI_Eb_2 = MI_Ds_2,
190 MI_E_2,
191 MI_F_2,
192 MI_Fs_2,
193 MI_Gb_2 = MI_Fs_2,
194 MI_G_2,
195 MI_Gs_2,
196 MI_Ab_2 = MI_Gs_2,
197 MI_A_2,
198 MI_As_2,
199 MI_Bb_2 = MI_As_2,
200 MI_B_2,
201#endif
202
203#if !MIDI_ENABLE_STRICT || MIDI_TONE_KEYCODE_OCTAVES > 3
204 MI_C_3,
205 MI_Cs_3,
206 MI_Db_3 = MI_Cs_3,
207 MI_D_3,
208 MI_Ds_3,
209 MI_Eb_3 = MI_Ds_3,
210 MI_E_3,
211 MI_F_3,
212 MI_Fs_3,
213 MI_Gb_3 = MI_Fs_3,
214 MI_G_3,
215 MI_Gs_3,
216 MI_Ab_3 = MI_Gs_3,
217 MI_A_3,
218 MI_As_3,
219 MI_Bb_3 = MI_As_3,
220 MI_B_3,
221#endif
222
223#if !MIDI_ENABLE_STRICT || MIDI_TONE_KEYCODE_OCTAVES > 4
224 MI_C_4,
225 MI_Cs_4,
226 MI_Db_4 = MI_Cs_4,
227 MI_D_4,
228 MI_Ds_4,
229 MI_Eb_4 = MI_Ds_4,
230 MI_E_4,
231 MI_F_4,
232 MI_Fs_4,
233 MI_Gb_4 = MI_Fs_4,
234 MI_G_4,
235 MI_Gs_4,
236 MI_Ab_4 = MI_Gs_4,
237 MI_A_4,
238 MI_As_4,
239 MI_Bb_4 = MI_As_4,
240 MI_B_4,
241#endif
242
243#if !MIDI_ENABLE_STRICT || MIDI_TONE_KEYCODE_OCTAVES > 5
244 MI_C_5,
245 MI_Cs_5,
246 MI_Db_5 = MI_Cs_5,
247 MI_D_5,
248 MI_Ds_5,
249 MI_Eb_5 = MI_Ds_5,
250 MI_E_5,
251 MI_F_5,
252 MI_Fs_5,
253 MI_Gb_5 = MI_Fs_5,
254 MI_G_5,
255 MI_Gs_5,
256 MI_Ab_5 = MI_Gs_5,
257 MI_A_5,
258 MI_As_5,
259 MI_Bb_5 = MI_As_5,
260 MI_B_5,
261#endif
262
263#if !MIDI_ENABLE_STRICT || MIDI_TONE_KEYCODE_OCTAVES > 5
264 MIDI_TONE_MAX = MI_B_5,
265#elif MIDI_TONE_KEYCODE_OCTAVES > 4
266 MIDI_TONE_MAX = MI_B_4,
267#elif MIDI_TONE_KEYCODE_OCTAVES > 3
268 MIDI_TONE_MAX = MI_B_3,
269#elif MIDI_TONE_KEYCODE_OCTAVES > 2
270 MIDI_TONE_MAX = MI_B_2,
271#elif MIDI_TONE_KEYCODE_OCTAVES > 1
272 MIDI_TONE_MAX = MI_B_1,
273#elif MIDI_TONE_KEYCODE_OCTAVES > 0
274 MIDI_TONE_MAX = MI_B,
275#endif
276
277 MIDI_OCTAVE_MIN,
278 MI_OCT_N2 = MIDI_OCTAVE_MIN,
279 MI_OCT_N1,
280 MI_OCT_0,
281 MI_OCT_1,
282 MI_OCT_2,
283 MI_OCT_3,
284 MI_OCT_4,
285 MI_OCT_5,
286 MI_OCT_6,
287 MI_OCT_7,
288 MIDI_OCTAVE_MAX = MI_OCT_7,
289 MI_OCTD, // octave down
290 MI_OCTU, // octave up
291
292 MIDI_TRANSPOSE_MIN,
293 MI_TRNS_N6 = MIDI_TRANSPOSE_MIN,
294 MI_TRNS_N5,
295 MI_TRNS_N4,
296 MI_TRNS_N3,
297 MI_TRNS_N2,
298 MI_TRNS_N1,
299 MI_TRNS_0,
300 MI_TRNS_1,
301 MI_TRNS_2,
302 MI_TRNS_3,
303 MI_TRNS_4,
304 MI_TRNS_5,
305 MI_TRNS_6,
306 MIDI_TRANSPOSE_MAX = MI_TRNS_6,
307 MI_TRNSD, // transpose down
308 MI_TRNSU, // transpose up
309
310 MIDI_VELOCITY_MIN,
311 MI_VEL_1 = MIDI_VELOCITY_MIN,
312 MI_VEL_2,
313 MI_VEL_3,
314 MI_VEL_4,
315 MI_VEL_5,
316 MI_VEL_6,
317 MI_VEL_7,
318 MI_VEL_8,
319 MI_VEL_9,
320 MI_VEL_10,
321 MIDI_VELOCITY_MAX = MI_VEL_10,
322 MI_VELD, // velocity down
323 MI_VELU, // velocity up
324
325 MIDI_CHANNEL_MIN,
326 MI_CH1 = MIDI_CHANNEL_MIN,
327 MI_CH2,
328 MI_CH3,
329 MI_CH4,
330 MI_CH5,
331 MI_CH6,
332 MI_CH7,
333 MI_CH8,
334 MI_CH9,
335 MI_CH10,
336 MI_CH11,
337 MI_CH12,
338 MI_CH13,
339 MI_CH14,
340 MI_CH15,
341 MI_CH16,
342 MIDI_CHANNEL_MAX = MI_CH16,
343 MI_CHD, // previous channel
344 MI_CHU, // next channel
345
346 MI_ALLOFF, // all notes off
347
348 MI_SUS, // sustain
349 MI_PORT, // portamento
350 MI_SOST, // sostenuto
351 MI_SOFT, // soft pedal
352 MI_LEG, // legato
353
354 MI_MOD, // modulation
355 MI_MODSD, // decrease modulation speed
356 MI_MODSU, // increase modulation speed
357#endif // MIDI_ADVANCED
358
359 // Backlight functionality
360 BL_0,
361 BL_1,
362 BL_2,
363 BL_3,
364 BL_4,
365 BL_5,
366 BL_6,
367 BL_7,
368 BL_8,
369 BL_9,
370 BL_10,
371 BL_11,
372 BL_12,
373 BL_13,
374 BL_14,
375 BL_15,
376 BL_DEC,
377 BL_INC,
378 BL_TOGG,
379 BL_STEP,
380
381 // RGB functionality
382 RGB_TOG,
383 RGB_MOD,
384 RGB_HUI,
385 RGB_HUD,
386 RGB_SAI,
387 RGB_SAD,
388 RGB_VAI,
389 RGB_VAD,
390
391 // Left shift, open paren
392 KC_LSPO,
393
394 // Right shift, close paren
395 KC_RSPC,
396
397 // Printing
398 PRINT_ON,
399 PRINT_OFF,
400
401 // output selection
402 OUT_AUTO,
403 OUT_USB,
404#ifdef BLUETOOTH_ENABLE
405 OUT_BT,
406#endif
407
408 // always leave at the end
409 SAFE_RANGE
410};
411
412// Ability to use mods in layouts
413#define LCTL(kc) (kc | QK_LCTL)
414#define LSFT(kc) (kc | QK_LSFT)
415#define LALT(kc) (kc | QK_LALT)
416#define LGUI(kc) (kc | QK_LGUI)
417#define RCTL(kc) (kc | QK_RCTL)
418#define RSFT(kc) (kc | QK_RSFT)
419#define RALT(kc) (kc | QK_RALT)
420#define RGUI(kc) (kc | QK_RGUI)
421
422#define HYPR(kc) (kc | QK_LCTL | QK_LSFT | QK_LALT | QK_LGUI)
423#define MEH(kc) (kc | QK_LCTL | QK_LSFT | QK_LALT)
424#define LCAG(kc) (kc | QK_LCTL | QK_LALT | QK_LGUI)
425#define ALTG(kc) (kc | QK_RCTL | QK_RALT)
426#define SCMD(kc) (kc | QK_LGUI | QK_LSFT)
427#define SWIN(kc) SCMD(kc)
428#define LCA(kc) (kc | QK_LCTL | QK_LALT)
429
430#define MOD_HYPR 0xf
431#define MOD_MEH 0x7
432
433
434// Aliases for shifted symbols
435// Each key has a 4-letter code, and some have longer aliases too.
436// While the long aliases are descriptive, the 4-letter codes
437// make for nicer grid layouts (everything lines up), and are
438// the preferred style for Quantum.
439#define KC_TILD LSFT(KC_GRV) // ~
440#define KC_TILDE KC_TILD
441
442#define KC_EXLM LSFT(KC_1) // !
443#define KC_EXCLAIM KC_EXLM
444
445#define KC_AT LSFT(KC_2) // @
446
447#define KC_HASH LSFT(KC_3) // #
448
449#define KC_DLR LSFT(KC_4) // $
450#define KC_DOLLAR KC_DLR
451
452#define KC_PERC LSFT(KC_5) // %
453#define KC_PERCENT KC_PERC
454
455#define KC_CIRC LSFT(KC_6) // ^
456#define KC_CIRCUMFLEX KC_CIRC
457
458#define KC_AMPR LSFT(KC_7) // &
459#define KC_AMPERSAND KC_AMPR
460
461#define KC_ASTR LSFT(KC_8) // *
462#define KC_ASTERISK KC_ASTR
463
464#define KC_LPRN LSFT(KC_9) // (
465#define KC_LEFT_PAREN KC_LPRN
466
467#define KC_RPRN LSFT(KC_0) // )
468#define KC_RIGHT_PAREN KC_RPRN
469
470#define KC_UNDS LSFT(KC_MINS) // _
471#define KC_UNDERSCORE KC_UNDS
472
473#define KC_PLUS LSFT(KC_EQL) // +
474
475#define KC_LCBR LSFT(KC_LBRC) // {
476#define KC_LEFT_CURLY_BRACE KC_LCBR
477
478#define KC_RCBR LSFT(KC_RBRC) // }
479#define KC_RIGHT_CURLY_BRACE KC_RCBR
480
481#define KC_LABK LSFT(KC_COMM) // <
482#define KC_LEFT_ANGLE_BRACKET KC_LABK
483
484#define KC_RABK LSFT(KC_DOT) // >
485#define KC_RIGHT_ANGLE_BRACKET KC_RABK
486
487#define KC_COLN LSFT(KC_SCLN) // :
488#define KC_COLON KC_COLN
489
490#define KC_PIPE LSFT(KC_BSLS) // |
491
492#define KC_LT LSFT(KC_COMM) // <
493
494#define KC_GT LSFT(KC_DOT) // >
495
496#define KC_QUES LSFT(KC_SLSH) // ?
497#define KC_QUESTION KC_QUES
498
499#define KC_DQT LSFT(KC_QUOT) // "
500#define KC_DOUBLE_QUOTE KC_DQT
501#define KC_DQUO KC_DQT
502
503#define KC_DELT KC_DELETE // Del key (four letter code)
504
505// Alias for function layers than expand past FN31
506#define FUNC(kc) (kc | QK_FUNCTION)
507
508// Aliases
509#define S(kc) LSFT(kc)
510#define F(kc) FUNC(kc)
511
512#define M(kc) (kc | QK_MACRO)
513
514#define MACROTAP(kc) (kc | QK_MACRO | FUNC_TAP<<8)
515#define MACRODOWN(...) (record->event.pressed ? MACRO(__VA_ARGS__) : MACRO_NONE)
516
517
518// L-ayer, T-ap - 256 keycode max, 16 layer max
519#define LT(layer, kc) (kc | QK_LAYER_TAP | ((layer & 0xF) << 8))
520
521#define AG_SWAP MAGIC_SWAP_ALT_GUI
522#define AG_NORM MAGIC_UNSWAP_ALT_GUI
523
524#define BL_ON BL_9
525#define BL_OFF BL_0
526
527// GOTO layer - 16 layers max
528// when:
529// ON_PRESS = 1
530// ON_RELEASE = 2
531// Unless you have a good reason not to do so, prefer ON_PRESS (1) as your default.
532// In fact, we changed it to assume ON_PRESS for sanity/simplicity. If needed, you can add your own
533// keycode modeled after the old version, kept below for this.
534/* #define TO(layer, when) (layer | QK_TO | (when << 0x4)) */
535#define TO(layer) (layer | QK_TO | (ON_PRESS << 0x4))
536
537// Momentary switch layer - 256 layer max
538#define MO(layer) (layer | QK_MOMENTARY)
539
540// Set default layer - 256 layer max
541#define DF(layer) (layer | QK_DEF_LAYER)
542
543// Toggle to layer - 256 layer max
544#define TG(layer) (layer | QK_TOGGLE_LAYER)
545
546// One-shot layer - 256 layer max
547#define OSL(layer) (layer | QK_ONE_SHOT_LAYER)
548
549// One-shot mod
550#define OSM(mod) (mod | QK_ONE_SHOT_MOD)
551
552// Layer tap-toggle
553#define TT(layer) (layer | QK_LAYER_TAP_TOGGLE)
554
555// M-od, T-ap - 256 keycode max
556#define MT(mod, kc) (kc | QK_MOD_TAP | ((mod & 0x1F) << 8))
557
558#define CTL_T(kc) MT(MOD_LCTL, kc)
559#define LCTL_T(kc) MT(MOD_LCTL, kc)
560#define RCTL_T(kc) MT(MOD_RCTL, kc)
561
562#define SFT_T(kc) MT(MOD_LSFT, kc)
563#define LSFT_T(kc) MT(MOD_LSFT, kc)
564#define RSFT_T(kc) MT(MOD_RSFT, kc)
565
566#define ALT_T(kc) MT(MOD_LALT, kc)
567#define LALT_T(kc) MT(MOD_LALT, kc)
568#define RALT_T(kc) MT(MOD_RALT, kc)
569#define ALGR_T(kc) MT(MOD_RALT, kc) // dual-function AltGR
570
571#define GUI_T(kc) MT(MOD_LGUI, kc)
572#define LGUI_T(kc) MT(MOD_LGUI, kc)
573#define RGUI_T(kc) MT(MOD_RGUI, kc)
574
575#define C_S_T(kc) MT((MOD_LCTL | MOD_LSFT), kc) // Control + Shift e.g. for gnome-terminal
576#define MEH_T(kc) MT((MOD_LCTL | MOD_LSFT | MOD_LALT), kc) // Meh is a less hyper version of the Hyper key -- doesn't include Win or Cmd, so just alt+shift+ctrl
577#define LCAG_T(kc) MT((MOD_LCTL | MOD_LALT | MOD_LGUI), kc) // Left control alt and gui
578#define RCAG_T(kc) MT((MOD_RCTL | MOD_RALT | MOD_RGUI), kc) // Right control alt and gui
579#define ALL_T(kc) MT((MOD_LCTL | MOD_LSFT | MOD_LALT | MOD_LGUI), kc) // see http://brettterpstra.com/2012/12/08/a-useful-caps-lock-key/
580#define SCMD_T(kc) MT((MOD_LGUI | MOD_LSFT), kc)
581#define SWIN_T(kc) SCMD_T(kc)
582#define LCA_T(kc) MT((MOD_LCTL | MOD_LALT), kc) // Left control and left alt
583
584// Dedicated keycode versions for Hyper and Meh, if you want to use them as standalone keys rather than mod-tap
585#define KC_HYPR HYPR(KC_NO)
586#define KC_MEH MEH(KC_NO)
587
588#ifdef UNICODE_ENABLE
589 // For sending unicode codes.
590 // You may not send codes over 7FFF -- this supports most of UTF8.
591 // To have a key that sends out Œ, go UC(0x0152)
592 #define UNICODE(n) (n | QK_UNICODE)
593 #define UC(n) UNICODE(n)
594#endif
595
596#ifdef UNICODEMAP_ENABLE
597 #define X(n) (n | QK_UNICODE_MAP)
598#endif
599
600#endif // QUANTUM_KEYCODES_H
diff --git a/quantum/rgblight.c b/quantum/rgblight.c
index d550c5866..eff70aae1 100644
--- a/quantum/rgblight.c
+++ b/quantum/rgblight.c
@@ -1,3 +1,18 @@
1/* Copyright 2016-2017 Yang Liu
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 */
1#include <avr/eeprom.h> 16#include <avr/eeprom.h>
2#include <avr/interrupt.h> 17#include <avr/interrupt.h>
3#include <util/delay.h> 18#include <util/delay.h>
@@ -66,14 +81,17 @@ __attribute__ ((weak))
66const uint8_t RGBLED_SNAKE_INTERVALS[] PROGMEM = {100, 50, 20}; 81const uint8_t RGBLED_SNAKE_INTERVALS[] PROGMEM = {100, 50, 20};
67__attribute__ ((weak)) 82__attribute__ ((weak))
68const uint8_t RGBLED_KNIGHT_INTERVALS[] PROGMEM = {100, 50, 20}; 83const uint8_t RGBLED_KNIGHT_INTERVALS[] PROGMEM = {100, 50, 20};
84__attribute__ ((weak))
85const uint16_t RGBLED_GRADIENT_RANGES[] PROGMEM = {360, 240, 180, 120, 90};
69 86
70rgblight_config_t rgblight_config; 87rgblight_config_t rgblight_config;
71rgblight_config_t inmem_config; 88rgblight_config_t inmem_config;
72struct cRGB led[RGBLED_NUM];
73uint8_t rgblight_inited = 0;
74 89
90LED_TYPE led[RGBLED_NUM];
91uint8_t rgblight_inited = 0;
92bool rgblight_timer_enabled = false;
75 93
76void sethsv(uint16_t hue, uint8_t sat, uint8_t val, struct cRGB *led1) { 94void sethsv(uint16_t hue, uint8_t sat, uint8_t val, LED_TYPE *led1) {
77 uint8_t r = 0, g = 0, b = 0, base, color; 95 uint8_t r = 0, g = 0, b = 0, base, color;
78 96
79 if (sat == 0) { // Acromatic color (gray). Hue doesn't mind. 97 if (sat == 0) { // Acromatic color (gray). Hue doesn't mind.
@@ -124,7 +142,7 @@ void sethsv(uint16_t hue, uint8_t sat, uint8_t val, struct cRGB *led1) {
124 setrgb(r, g, b, led1); 142 setrgb(r, g, b, led1);
125} 143}
126 144
127void setrgb(uint8_t r, uint8_t g, uint8_t b, struct cRGB *led1) { 145void setrgb(uint8_t r, uint8_t g, uint8_t b, LED_TYPE *led1) {
128 (*led1).r = r; 146 (*led1).r = r;
129 (*led1).g = g; 147 (*led1).g = g;
130 (*led1).b = b; 148 (*led1).b = b;
@@ -141,9 +159,9 @@ void eeconfig_update_rgblight_default(void) {
141 dprintf("eeconfig_update_rgblight_default\n"); 159 dprintf("eeconfig_update_rgblight_default\n");
142 rgblight_config.enable = 1; 160 rgblight_config.enable = 1;
143 rgblight_config.mode = 1; 161 rgblight_config.mode = 1;
144 rgblight_config.hue = 200; 162 rgblight_config.hue = 0;
145 rgblight_config.sat = 204; 163 rgblight_config.sat = 255;
146 rgblight_config.val = 204; 164 rgblight_config.val = 255;
147 eeconfig_update_rgblight(rgblight_config.raw); 165 eeconfig_update_rgblight(rgblight_config.raw);
148} 166}
149void eeconfig_debug_rgblight(void) { 167void eeconfig_debug_rgblight(void) {
@@ -173,7 +191,7 @@ void rgblight_init(void) {
173 } 191 }
174 eeconfig_debug_rgblight(); // display current eeprom values 192 eeconfig_debug_rgblight(); // display current eeprom values
175 193
176 #if !defined(AUDIO_ENABLE) && defined(RGBLIGHT_TIMER) 194 #ifdef RGBLIGHT_ANIMATIONS
177 rgblight_timer_init(); // setup the timer 195 rgblight_timer_init(); // setup the timer
178 #endif 196 #endif
179 197
@@ -182,6 +200,19 @@ void rgblight_init(void) {
182 } 200 }
183} 201}
184 202
203void rgblight_update_dword(uint32_t dword) {
204 rgblight_config.raw = dword;
205 eeconfig_update_rgblight(rgblight_config.raw);
206 if (rgblight_config.enable)
207 rgblight_mode(rgblight_config.mode);
208 else {
209 #ifdef RGBLIGHT_ANIMATIONS
210 rgblight_timer_disable();
211 #endif
212 rgblight_set();
213 }
214}
215
185void rgblight_increase(void) { 216void rgblight_increase(void) {
186 uint8_t mode = 0; 217 uint8_t mode = 0;
187 if (rgblight_config.mode < RGBLIGHT_MODES) { 218 if (rgblight_config.mode < RGBLIGHT_MODES) {
@@ -205,6 +236,14 @@ void rgblight_step(void) {
205 } 236 }
206 rgblight_mode(mode); 237 rgblight_mode(mode);
207} 238}
239void rgblight_step_reverse(void) {
240 uint8_t mode = 0;
241 mode = rgblight_config.mode - 1;
242 if (mode < 1) {
243 mode = RGBLIGHT_MODES;
244 }
245 rgblight_mode(mode);
246}
208 247
209void rgblight_mode(uint8_t mode) { 248void rgblight_mode(uint8_t mode) {
210 if (!rgblight_config.enable) { 249 if (!rgblight_config.enable) {
@@ -220,19 +259,25 @@ void rgblight_mode(uint8_t mode) {
220 eeconfig_update_rgblight(rgblight_config.raw); 259 eeconfig_update_rgblight(rgblight_config.raw);
221 xprintf("rgblight mode: %u\n", rgblight_config.mode); 260 xprintf("rgblight mode: %u\n", rgblight_config.mode);
222 if (rgblight_config.mode == 1) { 261 if (rgblight_config.mode == 1) {
223 #if !defined(AUDIO_ENABLE) && defined(RGBLIGHT_TIMER) 262 #ifdef RGBLIGHT_ANIMATIONS
224 rgblight_timer_disable(); 263 rgblight_timer_disable();
225 #endif 264 #endif
226 } else if (rgblight_config.mode >= 2 && rgblight_config.mode <= 23) { 265 } else if (rgblight_config.mode >= 2 && rgblight_config.mode <= 24) {
227 // MODE 2-5, breathing 266 // MODE 2-5, breathing
228 // MODE 6-8, rainbow mood 267 // MODE 6-8, rainbow mood
229 // MODE 9-14, rainbow swirl 268 // MODE 9-14, rainbow swirl
230 // MODE 15-20, snake 269 // MODE 15-20, snake
231 // MODE 21-23, knight 270 // MODE 21-23, knight
232 271
233 #if !defined(AUDIO_ENABLE) && defined(RGBLIGHT_TIMER) 272 #ifdef RGBLIGHT_ANIMATIONS
234 rgblight_timer_enable(); 273 rgblight_timer_enable();
235 #endif 274 #endif
275 } else if (rgblight_config.mode >= 25 && rgblight_config.mode <= 34) {
276 // MODE 25-34, static gradient
277
278 #ifdef RGBLIGHT_ANIMATIONS
279 rgblight_timer_disable();
280 #endif
236 } 281 }
237 rgblight_sethsv(rgblight_config.hue, rgblight_config.sat, rgblight_config.val); 282 rgblight_sethsv(rgblight_config.hue, rgblight_config.sat, rgblight_config.val);
238} 283}
@@ -244,7 +289,7 @@ void rgblight_toggle(void) {
244 if (rgblight_config.enable) { 289 if (rgblight_config.enable) {
245 rgblight_mode(rgblight_config.mode); 290 rgblight_mode(rgblight_config.mode);
246 } else { 291 } else {
247 #if !defined(AUDIO_ENABLE) && defined(RGBLIGHT_TIMER) 292 #ifdef RGBLIGHT_ANIMATIONS
248 rgblight_timer_disable(); 293 rgblight_timer_disable();
249 #endif 294 #endif
250 _delay_ms(50); 295 _delay_ms(50);
@@ -252,6 +297,13 @@ void rgblight_toggle(void) {
252 } 297 }
253} 298}
254 299
300void rgblight_enable(void) {
301 rgblight_config.enable = 1;
302 eeconfig_update_rgblight(rgblight_config.raw);
303 xprintf("rgblight enable: rgblight_config.enable = %u\n", rgblight_config.enable);
304 rgblight_mode(rgblight_config.mode);
305}
306
255 307
256void rgblight_increase_hue(void) { 308void rgblight_increase_hue(void) {
257 uint16_t hue; 309 uint16_t hue;
@@ -307,7 +359,7 @@ void rgblight_decrease_val(void) {
307void rgblight_sethsv_noeeprom(uint16_t hue, uint8_t sat, uint8_t val) { 359void rgblight_sethsv_noeeprom(uint16_t hue, uint8_t sat, uint8_t val) {
308 inmem_config.raw = rgblight_config.raw; 360 inmem_config.raw = rgblight_config.raw;
309 if (rgblight_config.enable) { 361 if (rgblight_config.enable) {
310 struct cRGB tmp_led; 362 LED_TYPE tmp_led;
311 sethsv(hue, sat, val, &tmp_led); 363 sethsv(hue, sat, val, &tmp_led);
312 inmem_config.hue = hue; 364 inmem_config.hue = hue;
313 inmem_config.sat = sat; 365 inmem_config.sat = sat;
@@ -329,6 +381,17 @@ void rgblight_sethsv(uint16_t hue, uint8_t sat, uint8_t val) {
329 } else if (rgblight_config.mode >= 6 && rgblight_config.mode <= 14) { 381 } else if (rgblight_config.mode >= 6 && rgblight_config.mode <= 14) {
330 // rainbow mood and rainbow swirl, ignore the change of hue 382 // rainbow mood and rainbow swirl, ignore the change of hue
331 hue = rgblight_config.hue; 383 hue = rgblight_config.hue;
384 } else if (rgblight_config.mode >= 25 && rgblight_config.mode <= 34) {
385 // static gradient
386 uint16_t _hue;
387 int8_t direction = ((rgblight_config.mode - 25) % 2) ? -1 : 1;
388 uint16_t range = pgm_read_word(&RGBLED_GRADIENT_RANGES[(rgblight_config.mode - 25) / 2]);
389 for (uint8_t i = 0; i < RGBLED_NUM; i++) {
390 _hue = (range / RGBLED_NUM * i * direction + hue + 360) % 360;
391 dprintf("rgblight rainbow set hsv: %u,%u,%d,%u\n", i, _hue, direction, range);
392 sethsv(_hue, sat, val, (LED_TYPE *)&led[i]);
393 }
394 rgblight_set();
332 } 395 }
333 } 396 }
334 rgblight_config.hue = hue; 397 rgblight_config.hue = hue;
@@ -349,68 +412,90 @@ void rgblight_setrgb(uint8_t r, uint8_t g, uint8_t b) {
349 rgblight_set(); 412 rgblight_set();
350} 413}
351 414
415__attribute__ ((weak))
352void rgblight_set(void) { 416void rgblight_set(void) {
353 if (rgblight_config.enable) { 417 if (rgblight_config.enable) {
354 ws2812_setleds(led, RGBLED_NUM); 418 #ifdef RGBW
419 ws2812_setleds_rgbw(led, RGBLED_NUM);
420 #else
421 ws2812_setleds(led, RGBLED_NUM);
422 #endif
355 } else { 423 } else {
356 for (uint8_t i = 0; i < RGBLED_NUM; i++) { 424 for (uint8_t i = 0; i < RGBLED_NUM; i++) {
357 led[i].r = 0; 425 led[i].r = 0;
358 led[i].g = 0; 426 led[i].g = 0;
359 led[i].b = 0; 427 led[i].b = 0;
360 } 428 }
361 ws2812_setleds(led, RGBLED_NUM); 429 #ifdef RGBW
430 ws2812_setleds_rgbw(led, RGBLED_NUM);
431 #else
432 ws2812_setleds(led, RGBLED_NUM);
433 #endif
362 } 434 }
363} 435}
364 436
365#if !defined(AUDIO_ENABLE) && defined(RGBLIGHT_TIMER) 437#ifdef RGBLIGHT_ANIMATIONS
366 438
367// Animation timer -- AVR Timer3 439// Animation timer -- AVR Timer3
368void rgblight_timer_init(void) { 440void rgblight_timer_init(void) {
369 static uint8_t rgblight_timer_is_init = 0; 441 // static uint8_t rgblight_timer_is_init = 0;
370 if (rgblight_timer_is_init) { 442 // if (rgblight_timer_is_init) {
371 return; 443 // return;
372 } 444 // }
373 rgblight_timer_is_init = 1; 445 // rgblight_timer_is_init = 1;
374 /* Timer 3 setup */ 446 // /* Timer 3 setup */
375 TCCR3B = _BV(WGM32) //CTC mode OCR3A as TOP 447 // TCCR3B = _BV(WGM32) // CTC mode OCR3A as TOP
376 | _BV(CS30); //Clock selelct: clk/1 448 // | _BV(CS30); // Clock selelct: clk/1
377 /* Set TOP value */ 449 // /* Set TOP value */
378 uint8_t sreg = SREG; 450 // uint8_t sreg = SREG;
379 cli(); 451 // cli();
380 OCR3AH = (RGBLED_TIMER_TOP >> 8) & 0xff; 452 // OCR3AH = (RGBLED_TIMER_TOP >> 8) & 0xff;
381 OCR3AL = RGBLED_TIMER_TOP & 0xff; 453 // OCR3AL = RGBLED_TIMER_TOP & 0xff;
382 SREG = sreg; 454 // SREG = sreg;
455
456 rgblight_timer_enabled = true;
383} 457}
384void rgblight_timer_enable(void) { 458void rgblight_timer_enable(void) {
385 TIMSK3 |= _BV(OCIE3A); 459 rgblight_timer_enabled = true;
386 dprintf("TIMER3 enabled.\n"); 460 dprintf("TIMER3 enabled.\n");
387} 461}
388void rgblight_timer_disable(void) { 462void rgblight_timer_disable(void) {
389 TIMSK3 &= ~_BV(OCIE3A); 463 rgblight_timer_enabled = false;
390 dprintf("TIMER3 disabled.\n"); 464 dprintf("TIMER3 disabled.\n");
391} 465}
392void rgblight_timer_toggle(void) { 466void rgblight_timer_toggle(void) {
393 TIMSK3 ^= _BV(OCIE3A); 467 rgblight_timer_enabled ^= rgblight_timer_enabled;
394 dprintf("TIMER3 toggled.\n"); 468 dprintf("TIMER3 toggled.\n");
395} 469}
396 470
397ISR(TIMER3_COMPA_vect) { 471void rgblight_show_solid_color(uint8_t r, uint8_t g, uint8_t b) {
398 // mode = 1, static light, do nothing here 472 rgblight_enable();
399 if (rgblight_config.mode >= 2 && rgblight_config.mode <= 5) { 473 rgblight_mode(1);
400 // mode = 2 to 5, breathing mode 474 rgblight_setrgb(r, g, b);
401 rgblight_effect_breathing(rgblight_config.mode - 2); 475}
402 } else if (rgblight_config.mode >= 6 && rgblight_config.mode <= 8) { 476
403 // mode = 6 to 8, rainbow mood mod 477void rgblight_task(void) {
404 rgblight_effect_rainbow_mood(rgblight_config.mode - 6); 478 if (rgblight_timer_enabled) {
405 } else if (rgblight_config.mode >= 9 && rgblight_config.mode <= 14) { 479 // mode = 1, static light, do nothing here
406 // mode = 9 to 14, rainbow swirl mode 480 if (rgblight_config.mode >= 2 && rgblight_config.mode <= 5) {
407 rgblight_effect_rainbow_swirl(rgblight_config.mode - 9); 481 // mode = 2 to 5, breathing mode
408 } else if (rgblight_config.mode >= 15 && rgblight_config.mode <= 20) { 482 rgblight_effect_breathing(rgblight_config.mode - 2);
409 // mode = 15 to 20, snake mode 483 } else if (rgblight_config.mode >= 6 && rgblight_config.mode <= 8) {
410 rgblight_effect_snake(rgblight_config.mode - 15); 484 // mode = 6 to 8, rainbow mood mod
411 } else if (rgblight_config.mode >= 21 && rgblight_config.mode <= 23) { 485 rgblight_effect_rainbow_mood(rgblight_config.mode - 6);
412 // mode = 21 to 23, knight mode 486 } else if (rgblight_config.mode >= 9 && rgblight_config.mode <= 14) {
413 rgblight_effect_knight(rgblight_config.mode - 21); 487 // mode = 9 to 14, rainbow swirl mode
488 rgblight_effect_rainbow_swirl(rgblight_config.mode - 9);
489 } else if (rgblight_config.mode >= 15 && rgblight_config.mode <= 20) {
490 // mode = 15 to 20, snake mode
491 rgblight_effect_snake(rgblight_config.mode - 15);
492 } else if (rgblight_config.mode >= 21 && rgblight_config.mode <= 23) {
493 // mode = 21 to 23, knight mode
494 rgblight_effect_knight(rgblight_config.mode - 21);
495 } else if (rgblight_config.mode == 24) {
496 // mode = 24, christmas mode
497 rgblight_effect_christmas();
498 }
414 } 499 }
415} 500}
416 501
@@ -449,7 +534,7 @@ void rgblight_effect_rainbow_swirl(uint8_t interval) {
449 last_timer = timer_read(); 534 last_timer = timer_read();
450 for (i = 0; i < RGBLED_NUM; i++) { 535 for (i = 0; i < RGBLED_NUM; i++) {
451 hue = (360 / RGBLED_NUM * i + current_hue) % 360; 536 hue = (360 / RGBLED_NUM * i + current_hue) % 360;
452 sethsv(hue, rgblight_config.sat, rgblight_config.val, &led[i]); 537 sethsv(hue, rgblight_config.sat, rgblight_config.val, (LED_TYPE *)&led[i]);
453 } 538 }
454 rgblight_set(); 539 rgblight_set();
455 540
@@ -486,7 +571,7 @@ void rgblight_effect_snake(uint8_t interval) {
486 k = k + RGBLED_NUM; 571 k = k + RGBLED_NUM;
487 } 572 }
488 if (i == k) { 573 if (i == k) {
489 sethsv(rgblight_config.hue, rgblight_config.sat, (uint8_t)(rgblight_config.val*(RGBLIGHT_EFFECT_SNAKE_LENGTH-j)/RGBLIGHT_EFFECT_SNAKE_LENGTH), &led[i]); 574 sethsv(rgblight_config.hue, rgblight_config.sat, (uint8_t)(rgblight_config.val*(RGBLIGHT_EFFECT_SNAKE_LENGTH-j)/RGBLIGHT_EFFECT_SNAKE_LENGTH), (LED_TYPE *)&led[i]);
490 } 575 }
491 } 576 }
492 } 577 }
@@ -506,7 +591,7 @@ void rgblight_effect_knight(uint8_t interval) {
506 static uint16_t last_timer = 0; 591 static uint16_t last_timer = 0;
507 uint8_t i, j, cur; 592 uint8_t i, j, cur;
508 int8_t k; 593 int8_t k;
509 struct cRGB preled[RGBLED_NUM]; 594 LED_TYPE preled[RGBLED_NUM];
510 static int8_t increment = -1; 595 static int8_t increment = -1;
511 if (timer_elapsed(last_timer) < pgm_read_byte(&RGBLED_KNIGHT_INTERVALS[interval])) { 596 if (timer_elapsed(last_timer) < pgm_read_byte(&RGBLED_KNIGHT_INTERVALS[interval])) {
512 return; 597 return;
@@ -525,7 +610,7 @@ void rgblight_effect_knight(uint8_t interval) {
525 k = RGBLED_NUM - 1; 610 k = RGBLED_NUM - 1;
526 } 611 }
527 if (i == k) { 612 if (i == k) {
528 sethsv(rgblight_config.hue, rgblight_config.sat, rgblight_config.val, &preled[i]); 613 sethsv(rgblight_config.hue, rgblight_config.sat, rgblight_config.val, (LED_TYPE *)&preled[i]);
529 } 614 }
530 } 615 }
531 } 616 }
@@ -555,4 +640,22 @@ void rgblight_effect_knight(uint8_t interval) {
555 } 640 }
556} 641}
557 642
643
644void rgblight_effect_christmas(void) {
645 static uint16_t current_offset = 0;
646 static uint16_t last_timer = 0;
647 uint16_t hue;
648 uint8_t i;
649 if (timer_elapsed(last_timer) < RGBLIGHT_EFFECT_CHRISTMAS_INTERVAL) {
650 return;
651 }
652 last_timer = timer_read();
653 current_offset = (current_offset + 1) % 2;
654 for (i = 0; i < RGBLED_NUM; i++) {
655 hue = 0 + ((i/RGBLIGHT_EFFECT_CHRISTMAS_STEP + current_offset) % 2) * 120;
656 sethsv(hue, rgblight_config.sat, rgblight_config.val, (LED_TYPE *)&led[i]);
657 }
658 rgblight_set();
659}
660
558#endif 661#endif
diff --git a/quantum/rgblight.h b/quantum/rgblight.h
index 17f04ffcf..92130192c 100644
--- a/quantum/rgblight.h
+++ b/quantum/rgblight.h
@@ -1,9 +1,23 @@
1/* Copyright 2017 Yang Liu
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 */
1#ifndef RGBLIGHT_H 16#ifndef RGBLIGHT_H
2#define RGBLIGHT_H 17#define RGBLIGHT_H
3 18
4 19#ifdef RGBLIGHT_ANIMATIONS
5#if !defined(AUDIO_ENABLE) && defined(RGBLIGHT_TIMER) 20 #define RGBLIGHT_MODES 34
6 #define RGBLIGHT_MODES 23
7#else 21#else
8 #define RGBLIGHT_MODES 1 22 #define RGBLIGHT_MODES 1
9#endif 23#endif
@@ -23,6 +37,14 @@
23#define RGBLIGHT_EFFECT_DUALKNIGHT_LENGTH 4 37#define RGBLIGHT_EFFECT_DUALKNIGHT_LENGTH 4
24#endif 38#endif
25 39
40#ifndef RGBLIGHT_EFFECT_CHRISTMAS_INTERVAL
41#define RGBLIGHT_EFFECT_CHRISTMAS_INTERVAL 1000
42#endif
43
44#ifndef RGBLIGHT_EFFECT_CHRISTMAS_STEP
45#define RGBLIGHT_EFFECT_CHRISTMAS_STEP 2
46#endif
47
26#ifndef RGBLIGHT_HUE_STEP 48#ifndef RGBLIGHT_HUE_STEP
27#define RGBLIGHT_HUE_STEP 10 49#define RGBLIGHT_HUE_STEP 10
28#endif 50#endif
@@ -34,12 +56,15 @@
34#endif 56#endif
35 57
36#define RGBLED_TIMER_TOP F_CPU/(256*64) 58#define RGBLED_TIMER_TOP F_CPU/(256*64)
59// #define RGBLED_TIMER_TOP 0xFF10
37 60
38#include <stdint.h> 61#include <stdint.h>
39#include <stdbool.h> 62#include <stdbool.h>
40#include "eeconfig.h" 63#include "eeconfig.h"
41#include "light_ws2812.h" 64#include "light_ws2812.h"
42 65
66extern LED_TYPE led[RGBLED_NUM];
67
43extern const uint8_t RGBLED_BREATHING_INTERVALS[4] PROGMEM; 68extern const uint8_t RGBLED_BREATHING_INTERVALS[4] PROGMEM;
44extern const uint8_t RGBLED_RAINBOW_MOOD_INTERVALS[3] PROGMEM; 69extern const uint8_t RGBLED_RAINBOW_MOOD_INTERVALS[3] PROGMEM;
45extern const uint8_t RGBLED_RAINBOW_SWIRL_INTERVALS[3] PROGMEM; 70extern const uint8_t RGBLED_RAINBOW_SWIRL_INTERVALS[3] PROGMEM;
@@ -61,9 +86,12 @@ void rgblight_init(void);
61void rgblight_increase(void); 86void rgblight_increase(void);
62void rgblight_decrease(void); 87void rgblight_decrease(void);
63void rgblight_toggle(void); 88void rgblight_toggle(void);
89void rgblight_enable(void);
64void rgblight_step(void); 90void rgblight_step(void);
91void rgblight_step_reverse(void);
65void rgblight_mode(uint8_t mode); 92void rgblight_mode(uint8_t mode);
66void rgblight_set(void); 93void rgblight_set(void);
94void rgblight_update_dword(uint32_t dword);
67void rgblight_increase_hue(void); 95void rgblight_increase_hue(void);
68void rgblight_decrease_hue(void); 96void rgblight_decrease_hue(void);
69void rgblight_increase_sat(void); 97void rgblight_increase_sat(void);
@@ -78,10 +106,15 @@ void eeconfig_update_rgblight(uint32_t val);
78void eeconfig_update_rgblight_default(void); 106void eeconfig_update_rgblight_default(void);
79void eeconfig_debug_rgblight(void); 107void eeconfig_debug_rgblight(void);
80 108
81void sethsv(uint16_t hue, uint8_t sat, uint8_t val, struct cRGB *led1); 109void sethsv(uint16_t hue, uint8_t sat, uint8_t val, LED_TYPE *led1);
82void setrgb(uint8_t r, uint8_t g, uint8_t b, struct cRGB *led1); 110void setrgb(uint8_t r, uint8_t g, uint8_t b, LED_TYPE *led1);
83void rgblight_sethsv_noeeprom(uint16_t hue, uint8_t sat, uint8_t val); 111void rgblight_sethsv_noeeprom(uint16_t hue, uint8_t sat, uint8_t val);
84 112
113#define EZ_RGB(val) rgblight_show_solid_color((val >> 16) & 0xFF, (val >> 8) & 0xFF, val & 0xFF)
114void rgblight_show_solid_color(uint8_t r, uint8_t g, uint8_t b);
115
116void rgblight_task(void);
117
85void rgblight_timer_init(void); 118void rgblight_timer_init(void);
86void rgblight_timer_enable(void); 119void rgblight_timer_enable(void);
87void rgblight_timer_disable(void); 120void rgblight_timer_disable(void);
@@ -91,5 +124,6 @@ void rgblight_effect_rainbow_mood(uint8_t interval);
91void rgblight_effect_rainbow_swirl(uint8_t interval); 124void rgblight_effect_rainbow_swirl(uint8_t interval);
92void rgblight_effect_snake(uint8_t interval); 125void rgblight_effect_snake(uint8_t interval);
93void rgblight_effect_knight(uint8_t interval); 126void rgblight_effect_knight(uint8_t interval);
127void rgblight_effect_christmas(void);
94 128
95#endif 129#endif
diff --git a/quantum/serial_link/LICENSE b/quantum/serial_link/LICENSE
index d7cc3198c..d13cc4b26 100644
--- a/quantum/serial_link/LICENSE
+++ b/quantum/serial_link/LICENSE
@@ -1,7 +1,5 @@
1The MIT License (MIT) 1The MIT License (MIT)
2 2
3Copyright (c) 2016 Fred Sundvik
4
5Permission is hereby granted, free of charge, to any person obtaining a copy 3Permission is hereby granted, free of charge, to any person obtaining a copy
6of this software and associated documentation files (the "Software"), to deal 4of this software and associated documentation files (the "Software"), to deal
7in the Software without restriction, including without limitation the rights 5in the Software without restriction, including without limitation the rights
diff --git a/quantum/template/Makefile b/quantum/template/Makefile
index 4e2a6f00f..840dc9a28 100644
--- a/quantum/template/Makefile
+++ b/quantum/template/Makefile
@@ -1,3 +1,18 @@
1# Copyright 2013 Jun Wako <wakojun@gmail.com>
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
1ifndef MAKEFILE_INCLUDED 16ifndef MAKEFILE_INCLUDED
2 include ../../Makefile 17 include ../../Makefile
3endif \ No newline at end of file 18endif
diff --git a/quantum/template/config.h b/quantum/template/config.h
index b02f0c7eb..dbca45765 100644
--- a/quantum/template/config.h
+++ b/quantum/template/config.h
@@ -1,5 +1,5 @@
1/* 1/*
2Copyright 2012 Jun Wako <wakojun@gmail.com> 2Copyright 2017 REPLACE_WITH_YOUR_NAME
3 3
4This program is free software: you can redistribute it and/or modify 4This program is free software: you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by 5it under the terms of the GNU General Public License as published by
@@ -46,7 +46,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
46#define MATRIX_COL_PINS { F1, F0, B0 } 46#define MATRIX_COL_PINS { F1, F0, B0 }
47#define UNUSED_PINS 47#define UNUSED_PINS
48 48
49/* COL2ROW or ROW2COL */ 49/* COL2ROW, ROW2COL, or CUSTOM_MATRIX */
50#define DIODE_DIRECTION COL2ROW 50#define DIODE_DIRECTION COL2ROW
51 51
52// #define BACKLIGHT_PIN B7 52// #define BACKLIGHT_PIN B7
@@ -159,4 +159,27 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
159//#define NO_ACTION_MACRO 159//#define NO_ACTION_MACRO
160//#define NO_ACTION_FUNCTION 160//#define NO_ACTION_FUNCTION
161 161
162/*
163 * MIDI options
164 */
165
166/* Prevent use of disabled MIDI features in the keymap */
167//#define MIDI_ENABLE_STRICT 1
168
169/* enable basic MIDI features:
170 - MIDI notes can be sent when in Music mode is on
171*/
172//#define MIDI_BASIC
173
174/* enable advanced MIDI features:
175 - MIDI notes can be added to the keymap
176 - Octave shift and transpose
177 - Virtual sustain, portamento, and modulation wheel
178 - etc.
179*/
180//#define MIDI_ADVANCED
181
182/* override number of MIDI tone keycodes (each octave adds 12 keycodes and allocates 12 bytes) */
183//#define MIDI_TONE_KEYCODE_OCTAVES 1
184
162#endif 185#endif
diff --git a/quantum/template/keymaps/default/Makefile b/quantum/template/keymaps/default/Makefile
index f4671a9d1..b8879076b 100644
--- a/quantum/template/keymaps/default/Makefile
+++ b/quantum/template/keymaps/default/Makefile
@@ -1,4 +1,20 @@
1# Build Options 1# Copyright 2013 Jun Wako <wakojun@gmail.com>
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# QMK Build Options
2# change to "no" to disable the options, or define them in the Makefile in 18# change to "no" to disable the options, or define them in the Makefile in
3# the appropriate keymap folder that will get included automatically 19# the appropriate keymap folder that will get included automatically
4# 20#
@@ -9,7 +25,7 @@ CONSOLE_ENABLE = no # Console for debug(+400)
9COMMAND_ENABLE = yes # Commands for debug and configuration 25COMMAND_ENABLE = yes # Commands for debug and configuration
10NKRO_ENABLE = yes # Nkey Rollover - if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work 26NKRO_ENABLE = yes # Nkey Rollover - if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work
11BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality 27BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality
12MIDI_ENABLE = no # MIDI controls 28MIDI_ENABLE = no # MIDI support (+2400 to 4200, depending on config)
13AUDIO_ENABLE = no # Audio output on port C6 29AUDIO_ENABLE = no # Audio output on port C6
14UNICODE_ENABLE = no # Unicode 30UNICODE_ENABLE = no # Unicode
15BLUETOOTH_ENABLE = no # Enable Bluetooth with the Adafruit EZ-Key HID 31BLUETOOTH_ENABLE = no # Enable Bluetooth with the Adafruit EZ-Key HID
@@ -18,4 +34,4 @@ SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend
18 34
19ifndef QUANTUM_DIR 35ifndef QUANTUM_DIR
20 include ../../../../Makefile 36 include ../../../../Makefile
21endif \ No newline at end of file 37endif
diff --git a/quantum/template/keymaps/default/config.h b/quantum/template/keymaps/default/config.h
index df06a2620..f52a97bbc 100644
--- a/quantum/template/keymaps/default/config.h
+++ b/quantum/template/keymaps/default/config.h
@@ -1,3 +1,19 @@
1/* Copyright 2017 REPLACE_WITH_YOUR_NAME
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
1#ifndef CONFIG_USER_H 17#ifndef CONFIG_USER_H
2#define CONFIG_USER_H 18#define CONFIG_USER_H
3 19
@@ -5,4 +21,4 @@
5 21
6// place overrides here 22// place overrides here
7 23
8#endif \ No newline at end of file 24#endif
diff --git a/quantum/template/keymaps/default/keymap.c b/quantum/template/keymaps/default/keymap.c
index e28a4723e..a123cd7ba 100644
--- a/quantum/template/keymaps/default/keymap.c
+++ b/quantum/template/keymaps/default/keymap.c
@@ -1,3 +1,18 @@
1/* Copyright 2017 REPLACE_WITH_YOUR_NAME
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 */
1#include "%KEYBOARD%.h" 16#include "%KEYBOARD%.h"
2 17
3const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { 18const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
@@ -41,4 +56,4 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
41 56
42void led_set_user(uint8_t usb_led) { 57void led_set_user(uint8_t usb_led) {
43 58
44} \ No newline at end of file 59}
diff --git a/quantum/template/rules.mk b/quantum/template/rules.mk
index 55898147d..a1f9377d8 100644
--- a/quantum/template/rules.mk
+++ b/quantum/template/rules.mk
@@ -61,7 +61,8 @@ SLEEP_LED_ENABLE ?= no # Breathing sleep LED during USB suspend
61# if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work 61# if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work
62NKRO_ENABLE ?= no # USB Nkey Rollover 62NKRO_ENABLE ?= no # USB Nkey Rollover
63BACKLIGHT_ENABLE ?= no # Enable keyboard backlight functionality on B7 by default 63BACKLIGHT_ENABLE ?= no # Enable keyboard backlight functionality on B7 by default
64MIDI_ENABLE ?= no # MIDI controls 64MIDI_ENABLE ?= no # MIDI support (+2400 to 4200, depending on config)
65UNICODE_ENABLE ?= no # Unicode 65UNICODE_ENABLE ?= no # Unicode
66BLUETOOTH_ENABLE ?= no # Enable Bluetooth with the Adafruit EZ-Key HID 66BLUETOOTH_ENABLE ?= no # Enable Bluetooth with the Adafruit EZ-Key HID
67AUDIO_ENABLE ?= no # Audio output on port C6 67AUDIO_ENABLE ?= no # Audio output on port C6
68FAUXCLICKY_ENABLE ?= no # Use buzzer to emulate clicky switches
diff --git a/quantum/template/template.c b/quantum/template/template.c
index 5ef349583..97f788654 100644
--- a/quantum/template/template.c
+++ b/quantum/template/template.c
@@ -1,3 +1,18 @@
1/* Copyright 2017 REPLACE_WITH_YOUR_NAME
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 */
1#include "%KEYBOARD%.h" 16#include "%KEYBOARD%.h"
2 17
3void matrix_init_kb(void) { 18void matrix_init_kb(void) {
diff --git a/quantum/template/template.h b/quantum/template/template.h
index cd78a54e3..e912188ba 100644
--- a/quantum/template/template.h
+++ b/quantum/template/template.h
@@ -1,3 +1,18 @@
1/* Copyright 2017 REPLACE_WITH_YOUR_NAME
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 */
1#ifndef %KEYBOARD_UPPERCASE%_H 16#ifndef %KEYBOARD_UPPERCASE%_H
2#define %KEYBOARD_UPPERCASE%_H 17#define %KEYBOARD_UPPERCASE%_H
3 18
diff --git a/quantum/variable_trace.c b/quantum/variable_trace.c
index de580244c..713747cfc 100644
--- a/quantum/variable_trace.c
+++ b/quantum/variable_trace.c
@@ -1,3 +1,19 @@
1/* Copyright 2016 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
1#include "variable_trace.h" 17#include "variable_trace.h"
2#include <stddef.h> 18#include <stddef.h>
3#include <string.h> 19#include <string.h>
diff --git a/quantum/variable_trace.h b/quantum/variable_trace.h
index 46bd82786..dacc13858 100644
--- a/quantum/variable_trace.h
+++ b/quantum/variable_trace.h
@@ -1,3 +1,19 @@
1/* Copyright 2016 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
1#ifndef VARIABLE_TRACE_H 17#ifndef VARIABLE_TRACE_H
2#define VARIABLE_TRACE_H 18#define VARIABLE_TRACE_H
3 19
diff --git a/quantum/visualizer/visualizer.c b/quantum/visualizer/visualizer.c
index 54f6faaa4..5826d909e 100644
--- a/quantum/visualizer/visualizer.c
+++ b/quantum/visualizer/visualizer.c
@@ -53,10 +53,13 @@ SOFTWARE.
53#define "Visualizer thread priority not defined" 53#define "Visualizer thread priority not defined"
54#endif 54#endif
55 55
56// mods status
57#include "action_util.h"
56 58
57static visualizer_keyboard_status_t current_status = { 59static visualizer_keyboard_status_t current_status = {
58 .layer = 0xFFFFFFFF, 60 .layer = 0xFFFFFFFF,
59 .default_layer = 0xFFFFFFFF, 61 .default_layer = 0xFFFFFFFF,
62 .mods = 0xFF,
60 .leds = 0xFFFFFFFF, 63 .leds = 0xFFFFFFFF,
61 .suspended = false, 64 .suspended = false,
62}; 65};
@@ -64,6 +67,7 @@ static visualizer_keyboard_status_t current_status = {
64static bool same_status(visualizer_keyboard_status_t* status1, visualizer_keyboard_status_t* status2) { 67static bool same_status(visualizer_keyboard_status_t* status1, visualizer_keyboard_status_t* status2) {
65 return status1->layer == status2->layer && 68 return status1->layer == status2->layer &&
66 status1->default_layer == status2->default_layer && 69 status1->default_layer == status2->default_layer &&
70 status1->mods == status2->mods &&
67 status1->leds == status2->leds && 71 status1->leds == status2->leds &&
68 status1->suspended == status2->suspended; 72 status1->suspended == status2->suspended;
69} 73}
@@ -307,6 +311,45 @@ bool keyframe_display_layer_bitmap(keyframe_animation_t* animation, visualizer_s
307 gdispFlush(); 311 gdispFlush();
308 return false; 312 return false;
309} 313}
314
315static void format_mods_bitmap_string(uint8_t mods, char* buffer) {
316 *buffer = ' ';
317 ++buffer;
318
319 for (int i = 0; i<8; i++)
320 {
321 uint32_t mask = (1u << i);
322 if (mods & mask) {
323 *buffer = '1';
324 } else {
325 *buffer = '0';
326 }
327 ++buffer;
328
329 if (i==3) {
330 *buffer = ' ';
331 ++buffer;
332 }
333 }
334 *buffer = 0;
335}
336
337bool keyframe_display_mods_bitmap(keyframe_animation_t* animation, visualizer_state_t* state) {
338 (void)animation;
339
340 const char* title = "Modifier states";
341 const char* mods_header = " CSAG CSAG ";
342 char status_buffer[12];
343
344 gdispClear(White);
345 gdispDrawString(0, 0, title, state->font_fixed5x8, Black);
346 gdispDrawString(0, 10, mods_header, state->font_fixed5x8, Black);
347 format_mods_bitmap_string(state->status.mods, status_buffer);
348 gdispDrawString(0, 20, status_buffer, state->font_fixed5x8, Black);
349
350 gdispFlush();
351 return false;
352}
310#endif // LCD_ENABLE 353#endif // LCD_ENABLE
311 354
312bool keyframe_disable_lcd_and_backlight(keyframe_animation_t* animation, visualizer_state_t* state) { 355bool keyframe_disable_lcd_and_backlight(keyframe_animation_t* animation, visualizer_state_t* state) {
@@ -350,6 +393,7 @@ static DECLARE_THREAD_FUNCTION(visualizerThread, arg) {
350 visualizer_keyboard_status_t initial_status = { 393 visualizer_keyboard_status_t initial_status = {
351 .default_layer = 0xFFFFFFFF, 394 .default_layer = 0xFFFFFFFF,
352 .layer = 0xFFFFFFFF, 395 .layer = 0xFFFFFFFF,
396 .mods = 0xFF,
353 .leds = 0xFFFFFFFF, 397 .leds = 0xFFFFFFFF,
354 .suspended = false, 398 .suspended = false,
355 }; 399 };
@@ -499,7 +543,18 @@ void update_status(bool changed) {
499#endif 543#endif
500} 544}
501 545
502void visualizer_update(uint32_t default_state, uint32_t state, uint32_t leds) { 546uint8_t visualizer_get_mods() {
547 uint8_t mods = get_mods();
548
549#ifndef NO_ACTION_ONESHOT
550 if (!has_oneshot_mods_timed_out()) {
551 mods |= get_oneshot_mods();
552 }
553#endif
554 return mods;
555}
556
557void visualizer_update(uint32_t default_state, uint32_t state, uint8_t mods, uint32_t leds) {
503 // Note that there's a small race condition here, the thread could read 558 // Note that there's a small race condition here, the thread could read
504 // a state where one of these are set but not the other. But this should 559 // a state where one of these are set but not the other. But this should
505 // not really matter as it will be fixed during the next loop step. 560 // not really matter as it will be fixed during the next loop step.
@@ -523,6 +578,7 @@ void visualizer_update(uint32_t default_state, uint32_t state, uint32_t leds) {
523 visualizer_keyboard_status_t new_status = { 578 visualizer_keyboard_status_t new_status = {
524 .layer = state, 579 .layer = state,
525 .default_layer = default_state, 580 .default_layer = default_state,
581 .mods = mods,
526 .leds = leds, 582 .leds = leds,
527 .suspended = current_status.suspended, 583 .suspended = current_status.suspended,
528 }; 584 };
diff --git a/quantum/visualizer/visualizer.h b/quantum/visualizer/visualizer.h
index 53e250725..315af5022 100644
--- a/quantum/visualizer/visualizer.h
+++ b/quantum/visualizer/visualizer.h
@@ -34,10 +34,14 @@ SOFTWARE.
34#include "lcd_backlight.h" 34#include "lcd_backlight.h"
35#endif 35#endif
36 36
37// use this function to merget both real_mods and oneshot_mods in a uint16_t
38uint8_t visualizer_get_mods(void);
39
37// This need to be called once at the start 40// This need to be called once at the start
38void visualizer_init(void); 41void visualizer_init(void);
39// This should be called at every matrix scan 42// This should be called at every matrix scan
40void visualizer_update(uint32_t default_state, uint32_t state, uint32_t leds); 43void visualizer_update(uint32_t default_state, uint32_t state, uint8_t mods, uint32_t leds);
44
41// This should be called when the keyboard goes to suspend state 45// This should be called when the keyboard goes to suspend state
42void visualizer_suspend(void); 46void visualizer_suspend(void);
43// This should be called when the keyboard wakes up from suspend state 47// This should be called when the keyboard wakes up from suspend state
@@ -61,6 +65,7 @@ struct keyframe_animation_t;
61typedef struct { 65typedef struct {
62 uint32_t layer; 66 uint32_t layer;
63 uint32_t default_layer; 67 uint32_t default_layer;
68 uint8_t mods;
64 uint32_t leds; // See led.h for available statuses 69 uint32_t leds; // See led.h for available statuses
65 bool suspended; 70 bool suspended;
66} visualizer_keyboard_status_t; 71} visualizer_keyboard_status_t;
@@ -129,6 +134,8 @@ bool keyframe_set_backlight_color(keyframe_animation_t* animation, visualizer_st
129bool keyframe_display_layer_text(keyframe_animation_t* animation, visualizer_state_t* state); 134bool keyframe_display_layer_text(keyframe_animation_t* animation, visualizer_state_t* state);
130// Displays a bitmap (0/1) of all the currently active layers 135// Displays a bitmap (0/1) of all the currently active layers
131bool keyframe_display_layer_bitmap(keyframe_animation_t* animation, visualizer_state_t* state); 136bool keyframe_display_layer_bitmap(keyframe_animation_t* animation, visualizer_state_t* state);
137// Displays a bitmap (0/1) of all the currently active mods
138bool keyframe_display_mods_bitmap(keyframe_animation_t* animation, visualizer_state_t* state);
132 139
133bool keyframe_disable_lcd_and_backlight(keyframe_animation_t* animation, visualizer_state_t* state); 140bool keyframe_disable_lcd_and_backlight(keyframe_animation_t* animation, visualizer_state_t* state);
134bool keyframe_enable_lcd_and_backlight(keyframe_animation_t* animation, visualizer_state_t* state); 141bool keyframe_enable_lcd_and_backlight(keyframe_animation_t* animation, visualizer_state_t* state);