aboutsummaryrefslogtreecommitdiff
path: root/quantum
diff options
context:
space:
mode:
authorAlex Ong <the.onga@gmail.com>2019-01-04 19:43:45 +1100
committerAlex Ong <the.onga@gmail.com>2019-01-04 19:43:45 +1100
commit2bb2977c133646c4e056960e72029270d77cc1eb (patch)
tree235d491f992121ac1716c5bf2fafb80983748576 /quantum
parenta55c838961c89097ab849ed6cb1f261791e6b9b4 (diff)
parent47c91fc7f75ae0a477e55b687aa0fc30da0a283c (diff)
downloadqmk_firmware-2bb2977c133646c4e056960e72029270d77cc1eb.tar.gz
qmk_firmware-2bb2977c133646c4e056960e72029270d77cc1eb.zip
Merge branch 'master' into debounce_refactor
# Conflicts: # tmk_core/common/keyboard.c
Diffstat (limited to 'quantum')
-rw-r--r--quantum/api.h4
-rw-r--r--quantum/audio/audio.c8
-rw-r--r--quantum/audio/audio.h3
-rw-r--r--quantum/audio/audio_arm.c135
-rw-r--r--quantum/audio/song_list.h30
-rw-r--r--quantum/config_common.h257
-rw-r--r--quantum/dynamic_keymap.c230
-rw-r--r--quantum/dynamic_keymap.h63
-rw-r--r--quantum/encoder.c70
-rw-r--r--quantum/encoder.h (renamed from quantum/process_keycode/process_chording.h)21
-rw-r--r--quantum/keymap_common.c2
-rw-r--r--quantum/keymap_extras/keymap_belgian.h9
-rw-r--r--quantum/keymap_extras/keymap_bepo.h153
-rw-r--r--quantum/keymap_extras/keymap_canadian_multilingual.h49
-rw-r--r--quantum/keymap_extras/keymap_fr_ch.h4
-rw-r--r--quantum/keymap_extras/keymap_french.h6
-rw-r--r--quantum/keymap_extras/keymap_german.h4
-rw-r--r--quantum/keymap_extras/keymap_german_ch.h4
-rw-r--r--quantum/keymap_extras/keymap_hungarian.h4
-rw-r--r--quantum/keymap_extras/keymap_italian.h7
-rw-r--r--quantum/keymap_extras/keymap_jp.h3
-rw-r--r--quantum/keymap_extras/keymap_neo2.h2
-rw-r--r--quantum/keymap_extras/keymap_nordic.h4
-rw-r--r--quantum/keymap_extras/keymap_plover_dvorak.h47
-rw-r--r--quantum/keymap_extras/keymap_slovenian.h107
-rw-r--r--quantum/keymap_extras/keymap_spanish.h4
-rw-r--r--quantum/keymap_extras/keymap_swedish.h4
-rw-r--r--quantum/keymap_extras/keymap_uk.h4
-rw-r--r--quantum/keymap_extras/sendstring_german.h81
-rw-r--r--quantum/matrix.c49
-rw-r--r--quantum/process_keycode/process_auto_shift.c2
-rw-r--r--quantum/process_keycode/process_chording.c76
-rw-r--r--quantum/process_keycode/process_clicky.c72
-rw-r--r--quantum/process_keycode/process_clicky.h10
-rw-r--r--quantum/process_keycode/process_leader.c49
-rw-r--r--quantum/process_keycode/process_leader.h2
-rw-r--r--quantum/process_keycode/process_tap_dance.c6
-rw-r--r--quantum/process_keycode/process_tap_dance.h1
-rw-r--r--quantum/process_keycode/process_ucis.c8
-rw-r--r--quantum/process_keycode/process_ucis.h6
-rw-r--r--quantum/process_keycode/process_unicode.c7
-rw-r--r--quantum/process_keycode/process_unicode.h5
-rw-r--r--quantum/process_keycode/process_unicode_common.c223
-rw-r--r--quantum/process_keycode/process_unicode_common.h68
-rw-r--r--quantum/process_keycode/process_unicodemap.c4
-rw-r--r--quantum/process_keycode/process_unicodemap.h4
-rw-r--r--quantum/quantum.c149
-rw-r--r--quantum/quantum.h95
-rw-r--r--quantum/quantum_keycodes.h129
-rw-r--r--quantum/rgb_matrix.c446
-rw-r--r--quantum/rgb_matrix.h120
-rw-r--r--quantum/rgb_matrix_drivers.c82
-rw-r--r--quantum/rgblight.c343
-rw-r--r--quantum/rgblight.h147
-rw-r--r--quantum/rgblight_reconfig.h36
-rw-r--r--quantum/split_common/i2c.c3
-rw-r--r--quantum/split_common/matrix.c160
-rw-r--r--quantum/split_common/matrix.h31
-rw-r--r--quantum/split_common/serial.c548
-rw-r--r--quantum/split_common/serial.h78
-rw-r--r--quantum/split_common/split_util.c51
-rw-r--r--quantum/template/avr/config.h31
-rw-r--r--quantum/template/avr/readme.md2
-rw-r--r--quantum/template/avr/rules.mk25
-rw-r--r--quantum/template/avr/template.h14
-rw-r--r--quantum/template/base/keymaps/default/keymap.c54
-rw-r--r--quantum/template/ps2avrgb/config.h4
-rw-r--r--quantum/template/ps2avrgb/readme.md2
-rw-r--r--quantum/template/ps2avrgb/rules.mk4
-rw-r--r--quantum/template/ps2avrgb/template.h12
70 files changed, 3146 insertions, 1331 deletions
diff --git a/quantum/api.h b/quantum/api.h
index efc0ddca1..fc016391b 100644
--- a/quantum/api.h
+++ b/quantum/api.h
@@ -17,7 +17,9 @@
17#ifndef _API_H_ 17#ifndef _API_H_
18#define _API_H_ 18#define _API_H_
19 19
20#ifdef __AVR__
20#include "lufa.h" 21#include "lufa.h"
22#endif
21 23
22enum MESSAGE_TYPE { 24enum MESSAGE_TYPE {
23 MT_GET_DATA = 0x10, // Get data from keyboard 25 MT_GET_DATA = 0x10, // Get data from keyboard
@@ -28,7 +30,7 @@ enum MESSAGE_TYPE {
28 MT_SEND_DATA_ACK = 0x31, // returned data/action confirmation (ACK) 30 MT_SEND_DATA_ACK = 0x31, // returned data/action confirmation (ACK)
29 MT_EXE_ACTION = 0x40, // executing actions on keyboard 31 MT_EXE_ACTION = 0x40, // executing actions on keyboard
30 MT_EXE_ACTION_ACK =0x41, // return confirmation/value (ACK) 32 MT_EXE_ACTION_ACK =0x41, // return confirmation/value (ACK)
31 MT_TYPE_ERROR = 0x80 // type not recofgnised (ACK) 33 MT_TYPE_ERROR = 0x80 // type not recognised (ACK)
32}; 34};
33 35
34enum DATA_TYPE { 36enum DATA_TYPE {
diff --git a/quantum/audio/audio.c b/quantum/audio/audio.c
index c948a60d6..6d6833ec1 100644
--- a/quantum/audio/audio.c
+++ b/quantum/audio/audio.c
@@ -223,7 +223,7 @@ void audio_init()
223 TCCR1B = (1 << WGM13) | (1 << WGM12) | (0 << CS12) | (1 << CS11) | (0 << CS10); 223 TCCR1B = (1 << WGM13) | (1 << WGM12) | (0 << CS12) | (1 << CS11) | (0 << CS10);
224 TIMER_1_PERIOD = (uint16_t)(((float)F_CPU) / (440 * CPU_PRESCALER)); 224 TIMER_1_PERIOD = (uint16_t)(((float)F_CPU) / (440 * CPU_PRESCALER));
225 TIMER_1_DUTY_CYCLE = (uint16_t)((((float)F_CPU) / (440 * CPU_PRESCALER)) * note_timbre); 225 TIMER_1_DUTY_CYCLE = (uint16_t)((((float)F_CPU) / (440 * CPU_PRESCALER)) * note_timbre);
226 #endif 226 #endif
227 227
228 audio_initialized = true; 228 audio_initialized = true;
229 } 229 }
@@ -231,7 +231,7 @@ void audio_init()
231 if (audio_config.enable) { 231 if (audio_config.enable) {
232 PLAY_SONG(startup_song); 232 PLAY_SONG(startup_song);
233 } 233 }
234 234
235} 235}
236 236
237void stop_all_notes() 237void stop_all_notes()
@@ -464,7 +464,7 @@ ISR(TIMER3_AUDIO_vect)
464 note_position++; 464 note_position++;
465 bool end_of_note = false; 465 bool end_of_note = false;
466 if (TIMER_3_PERIOD > 0) { 466 if (TIMER_3_PERIOD > 0) {
467 if (!note_resting) 467 if (!note_resting)
468 end_of_note = (note_position >= (note_length / TIMER_3_PERIOD * 0xFFFF - 1)); 468 end_of_note = (note_position >= (note_length / TIMER_3_PERIOD * 0xFFFF - 1));
469 else 469 else
470 end_of_note = (note_position >= (note_length)); 470 end_of_note = (note_position >= (note_length));
@@ -604,7 +604,7 @@ ISR(TIMER1_AUDIO_vect)
604 note_position++; 604 note_position++;
605 bool end_of_note = false; 605 bool end_of_note = false;
606 if (TIMER_1_PERIOD > 0) { 606 if (TIMER_1_PERIOD > 0) {
607 if (!note_resting) 607 if (!note_resting)
608 end_of_note = (note_position >= (note_length / TIMER_1_PERIOD * 0xFFFF - 1)); 608 end_of_note = (note_position >= (note_length / TIMER_1_PERIOD * 0xFFFF - 1));
609 else 609 else
610 end_of_note = (note_position >= (note_length)); 610 end_of_note = (note_position >= (note_length));
diff --git a/quantum/audio/audio.h b/quantum/audio/audio.h
index da09b2bcd..8136c5b25 100644
--- a/quantum/audio/audio.h
+++ b/quantum/audio/audio.h
@@ -40,7 +40,8 @@ typedef union {
40 uint8_t raw; 40 uint8_t raw;
41 struct { 41 struct {
42 bool enable :1; 42 bool enable :1;
43 uint8_t level :7; 43 bool clicky_enable :1;
44 uint8_t level :6;
44 }; 45 };
45} audio_config_t; 46} audio_config_t;
46 47
diff --git a/quantum/audio/audio_arm.c b/quantum/audio/audio_arm.c
index d38184f32..989f7a64b 100644
--- a/quantum/audio/audio_arm.c
+++ b/quantum/audio/audio_arm.c
@@ -80,6 +80,9 @@ float startup_song[][2] = STARTUP_SONG;
80static void gpt_cb8(GPTDriver *gptp); 80static void gpt_cb8(GPTDriver *gptp);
81 81
82#define DAC_BUFFER_SIZE 720 82#define DAC_BUFFER_SIZE 720
83#ifndef DAC_SAMPLE_MAX
84#define DAC_SAMPLE_MAX 65535U
85#endif
83 86
84#define START_CHANNEL_1() gptStart(&GPTD6, &gpt6cfg1); \ 87#define START_CHANNEL_1() gptStart(&GPTD6, &gpt6cfg1); \
85 gptStartContinuous(&GPTD6, 2U) 88 gptStartContinuous(&GPTD6, 2U)
@@ -202,132 +205,16 @@ GPTConfig gpt8cfg1 = {
202 205
203// squarewave 206// squarewave
204static const dacsample_t dac_buffer[DAC_BUFFER_SIZE] = { 207static const dacsample_t dac_buffer[DAC_BUFFER_SIZE] = {
205 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 208 // First half is max, second half is 0
206 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 209 [0 ... DAC_BUFFER_SIZE/2-1] = DAC_SAMPLE_MAX,
207 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 210 [DAC_BUFFER_SIZE/2 ... DAC_BUFFER_SIZE -1] = 0,
208 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047,
209 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047,
210 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047,
211 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047,
212 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047,
213 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047,
214 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047,
215 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047,
216 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047,
217 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047,
218 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047,
219 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047,
220 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047,
221 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047,
222 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047,
223 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047,
224 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047,
225 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047,
226 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047,
227 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047,
228 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047,
229 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047,
230 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047,
231 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047,
232 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047,
233 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047,
234 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047,
235
236 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
237 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
238 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
239 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
240 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
241 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
242 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
243 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
244 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
245 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
246 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
247 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
248 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
249 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
250 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
251 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
252 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
253 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
254 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
255 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
256 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
257 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
258 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
259 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
260 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
261 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
262 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
263 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
264 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
265 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
266}; 211};
267 212
268// squarewave 213// squarewave
269static const dacsample_t dac_buffer_2[DAC_BUFFER_SIZE] = { 214static const dacsample_t dac_buffer_2[DAC_BUFFER_SIZE] = {
270 215 // opposite of dac_buffer above
271 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 216 [0 ... DAC_BUFFER_SIZE/2-1] = 0,
272 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 217 [DAC_BUFFER_SIZE/2 ... DAC_BUFFER_SIZE -1] = DAC_SAMPLE_MAX,
273 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
274 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
275 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
276 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
277 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
278 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
279 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
280 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
281 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
282 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
283 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
284 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
285 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
286 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
287 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
288 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
289 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
290 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
291 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
292 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
293 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
294 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
295 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
296 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
297 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
298 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
299 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
300 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
301 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047,
302 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047,
303 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047,
304 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047,
305 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047,
306 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047,
307 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047,
308 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047,
309 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047,
310 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047,
311 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047,
312 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047,
313 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047,
314 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047,
315 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047,
316 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047,
317 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047,
318 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047,
319 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047,
320 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047,
321 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047,
322 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047,
323 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047,
324 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047,
325 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047,
326 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047,
327 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047,
328 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047,
329 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047,
330 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047
331}; 218};
332 219
333/* 220/*
@@ -363,7 +250,7 @@ static void error_cb1(DACDriver *dacp, dacerror_t err) {
363} 250}
364 251
365static const DACConfig dac1cfg1 = { 252static const DACConfig dac1cfg1 = {
366 .init = 2047U, 253 .init = DAC_SAMPLE_MAX,
367 .datamode = DAC_DHRM_12BIT_RIGHT 254 .datamode = DAC_DHRM_12BIT_RIGHT
368}; 255};
369 256
@@ -375,7 +262,7 @@ static const DACConversionGroup dacgrpcfg1 = {
375}; 262};
376 263
377static const DACConfig dac1cfg2 = { 264static const DACConfig dac1cfg2 = {
378 .init = 2047U, 265 .init = DAC_SAMPLE_MAX,
379 .datamode = DAC_DHRM_12BIT_RIGHT 266 .datamode = DAC_DHRM_12BIT_RIGHT
380}; 267};
381 268
diff --git a/quantum/audio/song_list.h b/quantum/audio/song_list.h
index e63616a99..994608497 100644
--- a/quantum/audio/song_list.h
+++ b/quantum/audio/song_list.h
@@ -472,4 +472,34 @@
472 H__NOTE(_AS4), W__NOTE(_GS4), W__NOTE(_GS4), W__NOTE(_FS4), W__NOTE(_GS4), \ 472 H__NOTE(_AS4), W__NOTE(_GS4), W__NOTE(_GS4), W__NOTE(_FS4), W__NOTE(_GS4), \
473 H__NOTE(_AS4), WD_NOTE(_DS4) 473 H__NOTE(_AS4), WD_NOTE(_DS4)
474 474
475#define RICK_ROLL \
476 Q__NOTE(_F4), \
477 Q__NOTE(_G4), \
478 Q__NOTE(_BF4), \
479 Q__NOTE(_G4), \
480 HD_NOTE(_D5), \
481 HD_NOTE(_D5), \
482 W__NOTE(_C5), \
483 S__NOTE(_REST), \
484 Q__NOTE(_F4), \
485 Q__NOTE(_G4), \
486 Q__NOTE(_BF4), \
487 Q__NOTE(_G4), \
488 HD_NOTE(_C5), \
489 HD_NOTE(_C5), \
490 W__NOTE(_BF4), \
491 S__NOTE(_REST), \
492 Q__NOTE(_F4), \
493 Q__NOTE(_G4), \
494 Q__NOTE(_BF4), \
495 Q__NOTE(_G4), \
496 W__NOTE(_BF4), \
497 H__NOTE(_C5), \
498 H__NOTE(_A4), \
499 H__NOTE(_A4), \
500 H__NOTE(_G4), \
501 H__NOTE(_F4), \
502 H__NOTE(_F4), \
503 W__NOTE(_C5), \
504 W__NOTE(_BF4),
475#endif 505#endif
diff --git a/quantum/config_common.h b/quantum/config_common.h
index f6f51b367..cbff372ea 100644
--- a/quantum/config_common.h
+++ b/quantum/config_common.h
@@ -1,4 +1,4 @@
1/* Copyright 2015-2017 Jack Humbert 1/* Copyright 2015-2018 Jack Humbert
2 * 2 *
3 * This program is free software: you can redistribute it and/or modify 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 4 * it under the terms of the GNU General Public License as published by
@@ -14,8 +14,7 @@
14 * along with this program. If not, see <http://www.gnu.org/licenses/>. 14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */ 15 */
16 16
17#ifndef CONFIG_DEFINITIONS_H 17#pragma once
18#define CONFIG_DEFINITIONS_H
19 18
20/* diode directions */ 19/* diode directions */
21#define COL2ROW 0 20#define COL2ROW 0
@@ -23,57 +22,205 @@
23#define CUSTOM_MATRIX 2 /* Disables built-in matrix scanning code */ 22#define CUSTOM_MATRIX 2 /* Disables built-in matrix scanning code */
24 23
25#ifdef __AVR__ 24#ifdef __AVR__
26 /* I/O pins */ 25 #ifndef __ASSEMBLER__
27 #ifndef F0 26 #include <avr/io.h>
28 #define B0 0x30 27 #endif
29 #define B1 0x31 28 #define PORT_SHIFTER 4 // this may be 4 for all AVR chips
30 #define B2 0x32 29
31 #define B3 0x33 30 // If you want to add more to this list, reference the PINx definitions in these header
32 #define B4 0x34 31 // files: https://github.com/vancegroup-mirrors/avr-libc/tree/master/avr-libc/include/avr
33 #define B5 0x35 32
34 #define B6 0x36 33 #if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega16U4__)
35 #define B7 0x37 34 #define ADDRESS_BASE 0x00
36 #define C0 0x60 35 #define PINB_ADDRESS 0x3
37 #define C1 0x61 36 #define PINC_ADDRESS 0x6
38 #define C2 0x62 37 #define PIND_ADDRESS 0x9
39 #define C3 0x63 38 #define PINE_ADDRESS 0xC
40 #define C4 0x64 39 #define PINF_ADDRESS 0xF
41 #define C5 0x65 40 #elif defined(__AVR_ATmega32U2__) || defined(__AVR_ATmega16U2__)
42 #define C6 0x66 41 #define ADDRESS_BASE 0x00
43 #define C7 0x67 42 #define PINB_ADDRESS 0x3
44 #define D0 0x90 43 #define PINC_ADDRESS 0x6
45 #define D1 0x91 44 #define PIND_ADDRESS 0x9
46 #define D2 0x92 45 #elif defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB646__)
47 #define D3 0x93 46 #define ADDRESS_BASE 0x00
48 #define D4 0x94 47 #define PINA_ADDRESS 0x0
49 #define D5 0x95 48 #define PINB_ADDRESS 0x3
50 #define D6 0x96 49 #define PINC_ADDRESS 0x6
51 #define D7 0x97 50 #define PIND_ADDRESS 0x9
52 #define E0 0xC0 51 #define PINE_ADDRESS 0xC
53 #define E1 0xC1 52 #define PINF_ADDRESS 0xF
54 #define E2 0xC2 53 #elif defined(__AVR_ATmega32A__)
55 #define E3 0xC3 54 #define ADDRESS_BASE 0x10
56 #define E4 0xC4 55 #define PIND_ADDRESS 0x0
57 #define E5 0xC5 56 #define PINC_ADDRESS 0x3
58 #define E6 0xC6 57 #define PINB_ADDRESS 0x6
59 #define E7 0xC7 58 #define PINA_ADDRESS 0x9
60 #define F0 0xF0 59 #else
61 #define F1 0xF1 60 #error "Pins are not defined"
62 #define F2 0xF2 61 #endif
63 #define F3 0xF3 62
64 #define F4 0xF4 63 /* I/O pins */
65 #define F5 0xF5 64 #define PINDEF(port, pin) ((PIN##port##_ADDRESS << PORT_SHIFTER) | pin)
66 #define F6 0xF6 65
67 #define F7 0xF7 66 #ifdef PORTA
68 #define A0 0x00 67 #define A0 PINDEF(A, 0)
69 #define A1 0x01 68 #define A1 PINDEF(A, 1)
70 #define A2 0x02 69 #define A2 PINDEF(A, 2)
71 #define A3 0x03 70 #define A3 PINDEF(A, 3)
72 #define A4 0x04 71 #define A4 PINDEF(A, 4)
73 #define A5 0x05 72 #define A5 PINDEF(A, 5)
74 #define A6 0x06 73 #define A6 PINDEF(A, 6)
75 #define A7 0x07 74 #define A7 PINDEF(A, 7)
76 #endif 75 #endif
76 #ifdef PORTB
77 #define B0 PINDEF(B, 0)
78 #define B1 PINDEF(B, 1)
79 #define B2 PINDEF(B, 2)
80 #define B3 PINDEF(B, 3)
81 #define B4 PINDEF(B, 4)
82 #define B5 PINDEF(B, 5)
83 #define B6 PINDEF(B, 6)
84 #define B7 PINDEF(B, 7)
85 #endif
86 #ifdef PORTC
87 #define C0 PINDEF(C, 0)
88 #define C1 PINDEF(C, 1)
89 #define C2 PINDEF(C, 2)
90 #define C3 PINDEF(C, 3)
91 #define C4 PINDEF(C, 4)
92 #define C5 PINDEF(C, 5)
93 #define C6 PINDEF(C, 6)
94 #define C7 PINDEF(C, 7)
95 #endif
96 #ifdef PORTD
97 #define D0 PINDEF(D, 0)
98 #define D1 PINDEF(D, 1)
99 #define D2 PINDEF(D, 2)
100 #define D3 PINDEF(D, 3)
101 #define D4 PINDEF(D, 4)
102 #define D5 PINDEF(D, 5)
103 #define D6 PINDEF(D, 6)
104 #define D7 PINDEF(D, 7)
105 #endif
106 #ifdef PORTE
107 #define E0 PINDEF(E, 0)
108 #define E1 PINDEF(E, 1)
109 #define E2 PINDEF(E, 2)
110 #define E3 PINDEF(E, 3)
111 #define E4 PINDEF(E, 4)
112 #define E5 PINDEF(E, 5)
113 #define E6 PINDEF(E, 6)
114 #define E7 PINDEF(E, 7)
115 #endif
116 #ifdef PORTF
117 #define F0 PINDEF(F, 0)
118 #define F1 PINDEF(F, 1)
119 #define F2 PINDEF(F, 2)
120 #define F3 PINDEF(F, 3)
121 #define F4 PINDEF(F, 4)
122 #define F5 PINDEF(F, 5)
123 #define F6 PINDEF(F, 6)
124 #define F7 PINDEF(F, 7)
125 #endif
126
127#elif defined(PROTOCOL_CHIBIOS)
128 #define A0 PAL_LINE(GPIOA, 0)
129 #define A1 PAL_LINE(GPIOA, 1)
130 #define A2 PAL_LINE(GPIOA, 2)
131 #define A3 PAL_LINE(GPIOA, 3)
132 #define A4 PAL_LINE(GPIOA, 4)
133 #define A5 PAL_LINE(GPIOA, 5)
134 #define A6 PAL_LINE(GPIOA, 6)
135 #define A7 PAL_LINE(GPIOA, 7)
136 #define A8 PAL_LINE(GPIOA, 8)
137 #define A9 PAL_LINE(GPIOA, 9)
138 #define A10 PAL_LINE(GPIOA, 10)
139 #define A11 PAL_LINE(GPIOA, 11)
140 #define A12 PAL_LINE(GPIOA, 12)
141 #define A13 PAL_LINE(GPIOA, 13)
142 #define A14 PAL_LINE(GPIOA, 14)
143 #define A15 PAL_LINE(GPIOA, 15)
144 #define B0 PAL_LINE(GPIOB, 0)
145 #define B1 PAL_LINE(GPIOB, 1)
146 #define B2 PAL_LINE(GPIOB, 2)
147 #define B3 PAL_LINE(GPIOB, 3)
148 #define B4 PAL_LINE(GPIOB, 4)
149 #define B5 PAL_LINE(GPIOB, 5)
150 #define B6 PAL_LINE(GPIOB, 6)
151 #define B7 PAL_LINE(GPIOB, 7)
152 #define B8 PAL_LINE(GPIOB, 8)
153 #define B9 PAL_LINE(GPIOB, 9)
154 #define B10 PAL_LINE(GPIOB, 10)
155 #define B11 PAL_LINE(GPIOB, 11)
156 #define B12 PAL_LINE(GPIOB, 12)
157 #define B13 PAL_LINE(GPIOB, 13)
158 #define B14 PAL_LINE(GPIOB, 14)
159 #define B15 PAL_LINE(GPIOB, 15)
160 #define C0 PAL_LINE(GPIOC, 0)
161 #define C1 PAL_LINE(GPIOC, 1)
162 #define C2 PAL_LINE(GPIOC, 2)
163 #define C3 PAL_LINE(GPIOC, 3)
164 #define C4 PAL_LINE(GPIOC, 4)
165 #define C5 PAL_LINE(GPIOC, 5)
166 #define C6 PAL_LINE(GPIOC, 6)
167 #define C7 PAL_LINE(GPIOC, 7)
168 #define C8 PAL_LINE(GPIOC, 8)
169 #define C9 PAL_LINE(GPIOC, 9)
170 #define C10 PAL_LINE(GPIOC, 10)
171 #define C11 PAL_LINE(GPIOC, 11)
172 #define C12 PAL_LINE(GPIOC, 12)
173 #define C13 PAL_LINE(GPIOC, 13)
174 #define C14 PAL_LINE(GPIOC, 14)
175 #define C15 PAL_LINE(GPIOC, 15)
176 #define D0 PAL_LINE(GPIOD, 0)
177 #define D1 PAL_LINE(GPIOD, 1)
178 #define D2 PAL_LINE(GPIOD, 2)
179 #define D3 PAL_LINE(GPIOD, 3)
180 #define D4 PAL_LINE(GPIOD, 4)
181 #define D5 PAL_LINE(GPIOD, 5)
182 #define D6 PAL_LINE(GPIOD, 6)
183 #define D7 PAL_LINE(GPIOD, 7)
184 #define D8 PAL_LINE(GPIOD, 8)
185 #define D9 PAL_LINE(GPIOD, 9)
186 #define D10 PAL_LINE(GPIOD, 10)
187 #define D11 PAL_LINE(GPIOD, 11)
188 #define D12 PAL_LINE(GPIOD, 12)
189 #define D13 PAL_LINE(GPIOD, 13)
190 #define D14 PAL_LINE(GPIOD, 14)
191 #define D15 PAL_LINE(GPIOD, 15)
192 #define E0 PAL_LINE(GPIOE, 0)
193 #define E1 PAL_LINE(GPIOE, 1)
194 #define E2 PAL_LINE(GPIOE, 2)
195 #define E3 PAL_LINE(GPIOE, 3)
196 #define E4 PAL_LINE(GPIOE, 4)
197 #define E5 PAL_LINE(GPIOE, 5)
198 #define E6 PAL_LINE(GPIOE, 6)
199 #define E7 PAL_LINE(GPIOE, 7)
200 #define E8 PAL_LINE(GPIOE, 8)
201 #define E9 PAL_LINE(GPIOE, 9)
202 #define E10 PAL_LINE(GPIOE, 10)
203 #define E11 PAL_LINE(GPIOE, 11)
204 #define E12 PAL_LINE(GPIOE, 12)
205 #define E13 PAL_LINE(GPIOE, 13)
206 #define E14 PAL_LINE(GPIOE, 14)
207 #define E15 PAL_LINE(GPIOE, 15)
208 #define F0 PAL_LINE(GPIOF, 0)
209 #define F1 PAL_LINE(GPIOF, 1)
210 #define F2 PAL_LINE(GPIOF, 2)
211 #define F3 PAL_LINE(GPIOF, 3)
212 #define F4 PAL_LINE(GPIOF, 4)
213 #define F5 PAL_LINE(GPIOF, 5)
214 #define F6 PAL_LINE(GPIOF, 6)
215 #define F7 PAL_LINE(GPIOF, 7)
216 #define F8 PAL_LINE(GPIOF, 8)
217 #define F9 PAL_LINE(GPIOF, 9)
218 #define F10 PAL_LINE(GPIOF, 10)
219 #define F11 PAL_LINE(GPIOF, 11)
220 #define F12 PAL_LINE(GPIOF, 12)
221 #define F13 PAL_LINE(GPIOF, 13)
222 #define F14 PAL_LINE(GPIOF, 14)
223 #define F15 PAL_LINE(GPIOF, 15)
77#endif 224#endif
78 225
79/* USART configuration */ 226/* USART configuration */
@@ -103,5 +250,3 @@
103#define API_SYSEX_MAX_SIZE 32 250#define API_SYSEX_MAX_SIZE 32
104 251
105#include "song_list.h" 252#include "song_list.h"
106
107#endif
diff --git a/quantum/dynamic_keymap.c b/quantum/dynamic_keymap.c
new file mode 100644
index 000000000..14627a93d
--- /dev/null
+++ b/quantum/dynamic_keymap.c
@@ -0,0 +1,230 @@
1/* Copyright 2017 Jason Williams (Wilba)
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 "config.h"
18#include "keymap.h" // to get keymaps[][][]
19#include "tmk_core/common/eeprom.h"
20#include "progmem.h" // to read default from flash
21#include "quantum.h" // for send_string()
22#include "dynamic_keymap.h"
23
24#ifdef DYNAMIC_KEYMAP_ENABLE
25
26#ifndef DYNAMIC_KEYMAP_EEPROM_ADDR
27#error DYNAMIC_KEYMAP_EEPROM_ADDR not defined
28#endif
29
30#ifndef DYNAMIC_KEYMAP_LAYER_COUNT
31#error DYNAMIC_KEYMAP_LAYER_COUNT not defined
32#endif
33
34#ifndef DYNAMIC_KEYMAP_MACRO_COUNT
35#error DYNAMIC_KEYMAP_MACRO_COUNT not defined
36#endif
37
38#ifndef DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR
39#error DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR not defined
40#endif
41
42#ifndef DYNAMIC_KEYMAP_MACRO_EEPROM_SIZE
43#error DYNAMIC_KEYMAP_MACRO_EEPROM_SIZE not defined
44#endif
45
46uint8_t dynamic_keymap_get_layer_count(void)
47{
48 return DYNAMIC_KEYMAP_LAYER_COUNT;
49}
50
51void *dynamic_keymap_key_to_eeprom_address(uint8_t layer, uint8_t row, uint8_t column)
52{
53 // TODO: optimize this with some left shifts
54 return ((void*)DYNAMIC_KEYMAP_EEPROM_ADDR) + ( layer * MATRIX_ROWS * MATRIX_COLS * 2 ) +
55 ( row * MATRIX_COLS * 2 ) + ( column * 2 );
56}
57
58uint16_t dynamic_keymap_get_keycode(uint8_t layer, uint8_t row, uint8_t column)
59{
60 void *address = dynamic_keymap_key_to_eeprom_address(layer, row, column);
61 // Big endian, so we can read/write EEPROM directly from host if we want
62 uint16_t keycode = eeprom_read_byte(address) << 8;
63 keycode |= eeprom_read_byte(address + 1);
64 return keycode;
65}
66
67void dynamic_keymap_set_keycode(uint8_t layer, uint8_t row, uint8_t column, uint16_t keycode)
68{
69 void *address = dynamic_keymap_key_to_eeprom_address(layer, row, column);
70 // Big endian, so we can read/write EEPROM directly from host if we want
71 eeprom_update_byte(address, (uint8_t)(keycode >> 8));
72 eeprom_update_byte(address+1, (uint8_t)(keycode & 0xFF));
73}
74
75void dynamic_keymap_reset(void)
76{
77 // Reset the keymaps in EEPROM to what is in flash.
78 // All keyboards using dynamic keymaps should define a layout
79 // for the same number of layers as DYNAMIC_KEYMAP_LAYER_COUNT.
80 for ( int layer = 0; layer < DYNAMIC_KEYMAP_LAYER_COUNT; layer++ ) {
81 for ( int row = 0; row < MATRIX_ROWS; row++ ) {
82 for ( int column = 0; column < MATRIX_COLS; column++ ) {
83 dynamic_keymap_set_keycode(layer, row, column, pgm_read_word(&keymaps[layer][row][column]));
84 }
85 }
86 }
87}
88
89void dynamic_keymap_get_buffer( uint16_t offset, uint16_t size, uint8_t *data )
90{
91 uint16_t dynamic_keymap_eeprom_size = DYNAMIC_KEYMAP_LAYER_COUNT * MATRIX_ROWS * MATRIX_COLS * 2;
92 void *source = (void*)(DYNAMIC_KEYMAP_EEPROM_ADDR+offset);
93 uint8_t *target = data;
94 for ( uint16_t i = 0; i < size; i++ ) {
95 if ( offset + i < dynamic_keymap_eeprom_size ) {
96 *target = eeprom_read_byte(source);
97 } else {
98 *target = 0x00;
99 }
100 source++;
101 target++;
102 }
103}
104
105void dynamic_keymap_set_buffer( uint16_t offset, uint16_t size, uint8_t *data )
106{
107 uint16_t dynamic_keymap_eeprom_size = DYNAMIC_KEYMAP_LAYER_COUNT * MATRIX_ROWS * MATRIX_COLS * 2;
108 void *target = (void*)(DYNAMIC_KEYMAP_EEPROM_ADDR+offset);
109 uint8_t *source = data;
110 for ( uint16_t i = 0; i < size; i++ ) {
111 if ( offset + i < dynamic_keymap_eeprom_size ) {
112 eeprom_update_byte(target, *source);
113 }
114 source++;
115 target++;
116 }
117}
118
119// This overrides the one in quantum/keymap_common.c
120uint16_t keymap_key_to_keycode(uint8_t layer, keypos_t key)
121{
122 if ( layer < DYNAMIC_KEYMAP_LAYER_COUNT &&
123 key.row < MATRIX_ROWS &&
124 key.col < MATRIX_COLS ) {
125 return dynamic_keymap_get_keycode(layer, key.row, key.col);
126 } else {
127 return KC_NO;
128 }
129}
130
131
132
133uint8_t dynamic_keymap_macro_get_count(void)
134{
135 return DYNAMIC_KEYMAP_MACRO_COUNT;
136}
137
138uint16_t dynamic_keymap_macro_get_buffer_size(void)
139{
140 return DYNAMIC_KEYMAP_MACRO_EEPROM_SIZE;
141}
142
143void dynamic_keymap_macro_get_buffer( uint16_t offset, uint16_t size, uint8_t *data )
144{
145 void *source = (void*)(DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR+offset);
146 uint8_t *target = data;
147 for ( uint16_t i = 0; i < size; i++ ) {
148 if ( offset + i < DYNAMIC_KEYMAP_MACRO_EEPROM_SIZE ) {
149 *target = eeprom_read_byte(source);
150 } else {
151 *target = 0x00;
152 }
153 source++;
154 target++;
155 }
156}
157
158void dynamic_keymap_macro_set_buffer( uint16_t offset, uint16_t size, uint8_t *data )
159{
160 void *target = (void*)(DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR+offset);
161 uint8_t *source = data;
162 for ( uint16_t i = 0; i < size; i++ ) {
163 if ( offset + i < DYNAMIC_KEYMAP_MACRO_EEPROM_SIZE ) {
164 eeprom_update_byte(target, *source);
165 }
166 source++;
167 target++;
168 }
169}
170
171void dynamic_keymap_macro_reset(void)
172{
173 void *p = (void*)(DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR);
174 void *end = (void*)(DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR+DYNAMIC_KEYMAP_MACRO_EEPROM_SIZE);
175 while ( p != end ) {
176 eeprom_update_byte(p, 0);
177 ++p;
178 }
179}
180
181void dynamic_keymap_macro_send( uint8_t id )
182{
183 if ( id >= DYNAMIC_KEYMAP_MACRO_COUNT ) {
184 return;
185 }
186
187 // Check the last byte of the buffer.
188 // If it's not zero, then we are in the middle
189 // of buffer writing, possibly an aborted buffer
190 // write. So do nothing.
191 void *p = (void*)(DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR+DYNAMIC_KEYMAP_MACRO_EEPROM_SIZE-1);
192 if ( eeprom_read_byte(p) != 0 ) {
193 return;
194 }
195
196 // Skip N null characters
197 // p will then point to the Nth macro
198 p = (void*)(DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR);
199 void *end = (void*)(DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR+DYNAMIC_KEYMAP_MACRO_EEPROM_SIZE);
200 while ( id > 0 ) {
201 // If we are past the end of the buffer, then the buffer
202 // contents are garbage, i.e. there were not DYNAMIC_KEYMAP_MACRO_COUNT
203 // nulls in the buffer.
204 if ( p == end ) {
205 return;
206 }
207 if ( eeprom_read_byte(p) == 0 ) {
208 --id;
209 }
210 ++p;
211 }
212
213 // Send the macro string one char at a time
214 // by making temporary 1 char strings
215 char data[2] = { 0, 0 };
216 // We already checked there was a null at the end of
217 // the buffer, so this cannot go past the end
218 while ( 1 ) {
219 data[0] = eeprom_read_byte(p);
220 // Stop at the null terminator of this macro string
221 if ( data[0] == 0 ) {
222 break;
223 }
224 send_string(data);
225 ++p;
226 }
227}
228
229#endif // DYNAMIC_KEYMAP_ENABLE
230
diff --git a/quantum/dynamic_keymap.h b/quantum/dynamic_keymap.h
new file mode 100644
index 000000000..63653f6cb
--- /dev/null
+++ b/quantum/dynamic_keymap.h
@@ -0,0 +1,63 @@
1/* Copyright 2017 Jason Williams (Wilba)
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
18#include <stdint.h>
19#include <stdbool.h>
20
21uint8_t dynamic_keymap_get_layer_count(void);
22void *dynamic_keymap_key_to_eeprom_address(uint8_t layer, uint8_t row, uint8_t column);
23uint16_t dynamic_keymap_get_keycode(uint8_t layer, uint8_t row, uint8_t column);
24void dynamic_keymap_set_keycode(uint8_t layer, uint8_t row, uint8_t column, uint16_t keycode);
25void dynamic_keymap_reset(void);
26// These get/set the keycodes as stored in the EEPROM buffer
27// Data is big-endian 16-bit values (the keycodes)
28// Order is by layer/row/column
29// Thus offset 0 = 0,0,0, offset MATRIX_COLS*2 = 0,1,0, offset MATRIX_ROWS*MATRIX_COLS*2 = 1,0,0
30// Note the *2, because offset is in bytes and keycodes are two bytes
31// This is only really useful for host applications that want to get a whole keymap fast,
32// by reading 14 keycodes (28 bytes) at a time, reducing the number of raw HID transfers by
33// a factor of 14.
34void dynamic_keymap_get_buffer( uint16_t offset, uint16_t size, uint8_t *data );
35void dynamic_keymap_set_buffer( uint16_t offset, uint16_t size, uint8_t *data );
36
37// This overrides the one in quantum/keymap_common.c
38// uint16_t keymap_key_to_keycode(uint8_t layer, keypos_t key);
39
40
41
42// Note regarding dynamic_keymap_macro_set_buffer():
43// The last byte of the buffer is used as a valid flag,
44// so macro sending is disabled during writing a new buffer,
45// should it happen during, or after an interrupted transfer.
46//
47// Users writing to the buffer must first set the last byte of the buffer
48// to non-zero (i.e. 0xFF). After (or during) the final write, set the
49// last byte of the buffer to zero.
50//
51// Since the contents of the buffer must be a list of null terminated
52// strings, the last byte must be a null when at maximum capacity,
53// and it not being null means the buffer can be considered in an
54// invalid state.
55
56uint8_t dynamic_keymap_macro_get_count(void);
57uint16_t dynamic_keymap_macro_get_buffer_size(void);
58void dynamic_keymap_macro_get_buffer( uint16_t offset, uint16_t size, uint8_t *data );
59void dynamic_keymap_macro_set_buffer( uint16_t offset, uint16_t size, uint8_t *data );
60void dynamic_keymap_macro_reset(void);
61
62void dynamic_keymap_macro_send( uint8_t id );
63
diff --git a/quantum/encoder.c b/quantum/encoder.c
new file mode 100644
index 000000000..6629a098b
--- /dev/null
+++ b/quantum/encoder.c
@@ -0,0 +1,70 @@
1/*
2 * Copyright 2018 Jack Humbert <jack.humb@gmail.com>
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#include "encoder.h"
19
20#ifndef ENCODER_RESOLUTION
21 #define ENCODER_RESOLUTION 4
22#endif
23
24#ifndef NUMBER_OF_ENCODERS
25 #error "Number of encoders not defined by NUMBER_OF_ENCODERS"
26#endif
27
28#if !defined(ENCODERS_PAD_A) || !defined(ENCODERS_PAD_B)
29 #error "No encoder pads defined by ENCODERS_PAD_A and ENCODERS_PAD_B"
30#endif
31
32static pin_t encoders_pad_a[NUMBER_OF_ENCODERS] = ENCODERS_PAD_A;
33static pin_t encoders_pad_b[NUMBER_OF_ENCODERS] = ENCODERS_PAD_B;
34
35static int8_t encoder_LUT[] = { 0, -1, 1, 0, 1, 0, 0, -1, -1, 0, 0, 1, 0, 1, -1, 0 };
36
37static uint8_t encoder_state[NUMBER_OF_ENCODERS] = {0};
38static int8_t encoder_value[NUMBER_OF_ENCODERS] = {0};
39
40__attribute__ ((weak))
41void encoder_update_user(int8_t index, bool clockwise) { }
42
43__attribute__ ((weak))
44void encoder_update_kb(int8_t index, bool clockwise) {
45 encoder_update_user(index, clockwise);
46}
47
48void encoder_init(void) {
49 for (int i = 0; i < NUMBER_OF_ENCODERS; i++) {
50 setPinInputHigh(encoders_pad_a[i]);
51 setPinInputHigh(encoders_pad_b[i]);
52
53 encoder_state[i] = (readPin(encoders_pad_a[i]) << 0) | (readPin(encoders_pad_b[i]) << 1);
54 }
55}
56
57void encoder_read(void) {
58 for (int i = 0; i < NUMBER_OF_ENCODERS; i++) {
59 encoder_state[i] <<= 2;
60 encoder_state[i] |= (readPin(encoders_pad_a[i]) << 0) | (readPin(encoders_pad_b[i]) << 1);
61 encoder_value[i] += encoder_LUT[encoder_state[i] & 0xF];
62 if (encoder_value[i] >= ENCODER_RESOLUTION) {
63 encoder_update_kb(i, COUNTRECLOCKWISE);
64 }
65 if (encoder_value[i] <= -ENCODER_RESOLUTION) { // direction is arbitrary here, but this clockwise
66 encoder_update_kb(i, CLOCKWISE);
67 }
68 encoder_value[i] %= ENCODER_RESOLUTION;
69 }
70}
diff --git a/quantum/process_keycode/process_chording.h b/quantum/encoder.h
index 8c0f4862a..2024fa303 100644
--- a/quantum/process_keycode/process_chording.h
+++ b/quantum/encoder.h
@@ -1,4 +1,5 @@
1/* Copyright 2016 Jack Humbert 1/*
2 * Copyright 2018 Jack Humbert <jack.humb@gmail.com>
2 * 3 *
3 * This program is free software: you can redistribute it and/or modify 4 * 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 * it under the terms of the GNU General Public License as published by
@@ -14,19 +15,15 @@
14 * along with this program. If not, see <http://www.gnu.org/licenses/>. 15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */ 16 */
16 17
17#ifndef PROCESS_CHORDING_H 18#pragma once
18#define PROCESS_CHORDING_H
19 19
20#include "quantum.h" 20#include "quantum.h"
21 21
22// Chording stuff 22#define COUNTRECLOCKWISE 0
23#define CHORDING_MAX 4 23#define CLOCKWISE 1
24bool chording = false;
25 24
26uint8_t chord_keys[CHORDING_MAX] = {0}; 25void encoder_init(void);
27uint8_t chord_key_count = 0; 26void encoder_read(void);
28uint8_t chord_key_down = 0;
29 27
30bool process_chording(uint16_t keycode, keyrecord_t *record); 28void encoder_update_kb(int8_t index, bool clockwise);
31 29void encoder_update_user(int8_t index, bool clockwise);
32#endif
diff --git a/quantum/keymap_common.c b/quantum/keymap_common.c
index 50af15d62..f6c8b70d2 100644
--- a/quantum/keymap_common.c
+++ b/quantum/keymap_common.c
@@ -64,7 +64,7 @@ action_t action_for_key(uint8_t layer, keypos_t key)
64 case KC_SYSTEM_POWER ... KC_SYSTEM_WAKE: 64 case KC_SYSTEM_POWER ... KC_SYSTEM_WAKE:
65 action.code = ACTION_USAGE_SYSTEM(KEYCODE2SYSTEM(keycode)); 65 action.code = ACTION_USAGE_SYSTEM(KEYCODE2SYSTEM(keycode));
66 break; 66 break;
67 case KC_AUDIO_MUTE ... KC_MEDIA_REWIND: 67 case KC_AUDIO_MUTE ... KC_BRIGHTNESS_DOWN:
68 action.code = ACTION_USAGE_CONSUMER(KEYCODE2CONSUMER(keycode)); 68 action.code = ACTION_USAGE_CONSUMER(KEYCODE2CONSUMER(keycode));
69 break; 69 break;
70 case KC_MS_UP ... KC_MS_ACCEL2: 70 case KC_MS_UP ... KC_MS_ACCEL2:
diff --git a/quantum/keymap_extras/keymap_belgian.h b/quantum/keymap_extras/keymap_belgian.h
index 764c56141..ab89fbabf 100644
--- a/quantum/keymap_extras/keymap_belgian.h
+++ b/quantum/keymap_extras/keymap_belgian.h
@@ -18,15 +18,6 @@
18 18
19#include "keymap.h" 19#include "keymap.h"
20 20
21#define BE_LGUI KC_LALT
22#define BE_LALT KC_LGUI
23
24// Alt gr
25#ifndef ALGR
26#define ALGR(kc) RALT(kc)
27#endif
28#define NO_ALGR KC_RALT
29
30// Normal characters 21// Normal characters
31// Line 1 22// Line 1
32#define BE_SUP2 KC_GRV 23#define BE_SUP2 KC_GRV
diff --git a/quantum/keymap_extras/keymap_bepo.h b/quantum/keymap_extras/keymap_bepo.h
index 05fd2b002..8d7b36ca3 100644
--- a/quantum/keymap_extras/keymap_bepo.h
+++ b/quantum/keymap_extras/keymap_bepo.h
@@ -19,15 +19,6 @@
19 19
20#include "keymap.h" 20#include "keymap.h"
21 21
22// Alt gr
23#ifndef ALTGR
24#define ALTGR(kc) RALT(kc)
25#endif
26#ifndef ALGR
27#define ALGR(kc) ALTGR(kc)
28#endif
29#define BP_ALGR KC_RALT
30
31// Normal characters 22// Normal characters
32// First row (on usual keyboards) 23// First row (on usual keyboards)
33#define BP_DOLLAR KC_GRAVE // $ 24#define BP_DOLLAR KC_GRAVE // $
@@ -142,138 +133,138 @@
142 133
143// AltGr-ed characters 134// AltGr-ed characters
144// First row 135// First row
145#define BP_EN_DASH ALTGR(BP_DOLLAR) // – 136#define BP_EN_DASH ALGR(BP_DOLLAR) // –
146#define BP_NDSH BP_EN_DASH 137#define BP_NDSH BP_EN_DASH
147#define BP_EM_DASH ALTGR(KC_1) // — 138#define BP_EM_DASH ALGR(KC_1) // —
148#define BP_MDSH BP_EM_DASH 139#define BP_MDSH BP_EM_DASH
149#define BP_LESS ALTGR(KC_2) // < 140#define BP_LESS ALGR(KC_2) // <
150#define BP_GREATER ALTGR(KC_3) // > 141#define BP_GREATER ALGR(KC_3) // >
151#define BP_GRTR BP_GREATER 142#define BP_GRTR BP_GREATER
152#define BP_LBRACKET ALTGR(KC_4) // [ 143#define BP_LBRACKET ALGR(KC_4) // [
153#define BP_LBRC BP_LBRACKET 144#define BP_LBRC BP_LBRACKET
154#define BP_RBRACKET ALTGR(KC_5) // ] 145#define BP_RBRACKET ALGR(KC_5) // ]
155#define BP_RBRC BP_RBRACKET 146#define BP_RBRC BP_RBRACKET
156#define BP_CIRCUMFLEX ALTGR(KC_6) // ^ 147#define BP_CIRCUMFLEX ALGR(KC_6) // ^
157#define BP_CIRC BP_CIRCUMFLEX 148#define BP_CIRC BP_CIRCUMFLEX
158#define BP_PLUS_MINUS ALTGR(KC_7) // ± 149#define BP_PLUS_MINUS ALGR(KC_7) // ±
159#define BP_PSMS BP_PLUS_MINUS 150#define BP_PSMS BP_PLUS_MINUS
160#define BP_MATH_MINUS ALTGR(KC_8) // − 151#define BP_MATH_MINUS ALGR(KC_8) // −
161#define BP_MMNS BP_MATH_MINUS 152#define BP_MMNS BP_MATH_MINUS
162#define BP_OBELUS ALTGR(KC_9) // ÷ 153#define BP_OBELUS ALGR(KC_9) // ÷
163#define BP_OBEL BP_OBELUS 154#define BP_OBEL BP_OBELUS
164// more conventional name of the symbol 155// more conventional name of the symbol
165#define BP_DIVISION_SIGN BP_OBELUS 156#define BP_DIVISION_SIGN BP_OBELUS
166#define BP_DVSN BP_DIVISION_SIGN 157#define BP_DVSN BP_DIVISION_SIGN
167#define BP_TIMES ALTGR(KC_0) // × 158#define BP_TIMES ALGR(KC_0) // ×
168#define BP_TIMS BP_TIMES 159#define BP_TIMS BP_TIMES
169#define BP_DIFFERENT ALTGR(BP_EQUAL) // ≠ 160#define BP_DIFFERENT ALGR(BP_EQUAL) // ≠
170#define BP_DIFF BP_DIFFERENT 161#define BP_DIFF BP_DIFFERENT
171#define BP_PERMILLE ALTGR(BP_PERCENT) // ‰ 162#define BP_PERMILLE ALGR(BP_PERCENT) // ‰
172#define BP_PMIL BP_PERMILLE 163#define BP_PMIL BP_PERMILLE
173 164
174// Second row 165// Second row
175#define BP_PIPE ALTGR(BP_B) // | 166#define BP_PIPE ALGR(BP_B) // |
176#define BP_DEAD_ACUTE ALTGR(BP_E_ACUTE) // dead ´ 167#define BP_DEAD_ACUTE ALGR(BP_E_ACUTE) // dead ´
177#define BP_DACT BP_DEAD_ACUTE 168#define BP_DACT BP_DEAD_ACUTE
178#define BP_AMPERSAND ALTGR(BP_P) // & 169#define BP_AMPERSAND ALGR(BP_P) // &
179#define BP_AMPR BP_AMPERSAND 170#define BP_AMPR BP_AMPERSAND
180#define BP_OE_LIGATURE ALTGR(BP_O) // œ 171#define BP_OE_LIGATURE ALGR(BP_O) // œ
181#define BP_OE BP_OE_LIGATURE 172#define BP_OE BP_OE_LIGATURE
182#define BP_DEAD_GRAVE ALTGR(BP_E_GRAVE) // ` 173#define BP_DEAD_GRAVE ALGR(BP_E_GRAVE) // `
183#define BP_DGRV BP_DEAD_GRAVE 174#define BP_DGRV BP_DEAD_GRAVE
184#define BP_INVERTED_EXCLAIM ALTGR(BP_DEAD_CIRCUMFLEX) // ¡ 175#define BP_INVERTED_EXCLAIM ALGR(BP_DEAD_CIRCUMFLEX) // ¡
185#define BP_IXLM BP_INVERTED_EXCLAIM 176#define BP_IXLM BP_INVERTED_EXCLAIM
186#define BP_DEAD_CARON ALTGR(BP_V) // dead ˇ 177#define BP_DEAD_CARON ALGR(BP_V) // dead ˇ
187#define BP_DCAR BP_DEAD_CARON 178#define BP_DCAR BP_DEAD_CARON
188#define BP_ETH ALTGR(BP_D) // ð 179#define BP_ETH ALGR(BP_D) // ð
189#define BP_DEAD_SLASH ALTGR(BP_L) // dead / 180#define BP_DEAD_SLASH ALGR(BP_L) // dead /
190#define BP_DSLH BP_DEAD_SLASH 181#define BP_DSLH BP_DEAD_SLASH
191#define BP_IJ_LIGATURE ALTGR(BP_J) // ij 182#define BP_IJ_LIGATURE ALGR(BP_J) // ij
192#define BP_IJ BP_IJ_LIGATURE 183#define BP_IJ BP_IJ_LIGATURE
193#define BP_SCHWA ALTGR(BP_Z) // ə 184#define BP_SCHWA ALGR(BP_Z) // ə
194#define BP_SCWA BP_SCHWA 185#define BP_SCWA BP_SCHWA
195#define BP_DEAD_BREVE ALTGR(BP_W) // dead ˘ 186#define BP_DEAD_BREVE ALGR(BP_W) // dead ˘
196#define BP_DBRV BP_DEAD_BREVE 187#define BP_DBRV BP_DEAD_BREVE
197 188
198// Third row 189// Third row
199#define BP_AE_LIGATURE ALTGR(BP_A) // æ 190#define BP_AE_LIGATURE ALGR(BP_A) // æ
200#define BP_AE BP_AE_LIGATURE 191#define BP_AE BP_AE_LIGATURE
201#define BP_U_GRAVE ALTGR(BP_U) // ù 192#define BP_U_GRAVE ALGR(BP_U) // ù
202#define BP_UGRV BP_U_GRAVE 193#define BP_UGRV BP_U_GRAVE
203#define BP_DEAD_TREMA ALTGR(BP_I) // dead ¨ (trema/umlaut/diaresis) 194#define BP_DEAD_TREMA ALGR(BP_I) // dead ¨ (trema/umlaut/diaresis)
204#define BP_DTRM BP_DEAD_TREMA 195#define BP_DTRM BP_DEAD_TREMA
205#define BP_EURO ALTGR(BP_E) // € 196#define BP_EURO ALGR(BP_E) // €
206#define BP_TYPOGRAPHICAL_APOSTROPHE ALTGR(BP_COMMA) // ’ 197#define BP_TYPOGRAPHICAL_APOSTROPHE ALGR(BP_COMMA) // ’
207#define BP_TAPO BP_TYPOGRAPHICAL_APOSTROPHE 198#define BP_TAPO BP_TYPOGRAPHICAL_APOSTROPHE
208#define BP_COPYRIGHT ALTGR(BP_C) // © 199#define BP_COPYRIGHT ALGR(BP_C) // ©
209#define BP_CPRT BP_COPYRIGHT 200#define BP_CPRT BP_COPYRIGHT
210#define BP_THORN ALTGR(BP_T) // þ 201#define BP_THORN ALGR(BP_T) // þ
211#define BP_THRN BP_THORN 202#define BP_THRN BP_THORN
212#define BP_SHARP_S ALTGR(BP_S) // ß 203#define BP_SHARP_S ALGR(BP_S) // ß
213#define BP_SRPS BP_SHARP_S 204#define BP_SRPS BP_SHARP_S
214#define BP_REGISTERED_TRADEMARK ALTGR(BP_R) // ® 205#define BP_REGISTERED_TRADEMARK ALGR(BP_R) // ®
215#define BP_RTM BP_REGISTERED_TRADEMARK 206#define BP_RTM BP_REGISTERED_TRADEMARK
216#define BP_DEAD_TILDE ALTGR(BP_N) // dead ~ 207#define BP_DEAD_TILDE ALGR(BP_N) // dead ~
217#define BP_DTLD BP_DEAD_TILDE 208#define BP_DTLD BP_DEAD_TILDE
218#define BP_DEAD_MACRON ALTGR(BP_M) // dead ¯ 209#define BP_DEAD_MACRON ALGR(BP_M) // dead ¯
219#define BP_DMCR BP_DEAD_MACRON 210#define BP_DMCR BP_DEAD_MACRON
220#define BP_DEAD_CEDILLA ALTGR(BP_C_CEDILLA) // dead ¸ 211#define BP_DEAD_CEDILLA ALGR(BP_C_CEDILLA) // dead ¸
221#define BP_DCED BP_DEAD_CEDILLA 212#define BP_DCED BP_DEAD_CEDILLA
222 213
223// Fourth row 214// Fourth row
224#define BP_NONUS_SLASH ALTGR(BP_E_CIRCUMFLEX) // / on non-us backslash key (102nd key, ê in bépo) 215#define BP_NONUS_SLASH ALGR(BP_E_CIRCUMFLEX) // / on non-us backslash key (102nd key, ê in bépo)
225#define BP_NUSL BP_NONUS_SLASH 216#define BP_NUSL BP_NONUS_SLASH
226#define BP_BACKSLASH ALTGR(BP_A_GRAVE) /* \ */ 217#define BP_BACKSLASH ALGR(BP_A_GRAVE) /* \ */
227#define BP_BSLS BP_BACKSLASH 218#define BP_BSLS BP_BACKSLASH
228#define BP_LEFT_CURLY_BRACE ALTGR(BP_Y) // { 219#define BP_LEFT_CURLY_BRACE ALGR(BP_Y) // {
229#define BP_LCBR BP_LEFT_CURLY_BRACE 220#define BP_LCBR BP_LEFT_CURLY_BRACE
230#define BP_RIGHT_CURLY_BRACE ALTGR(BP_X) // } 221#define BP_RIGHT_CURLY_BRACE ALGR(BP_X) // }
231#define BP_RCBR BP_RIGHT_CURLY_BRACE 222#define BP_RCBR BP_RIGHT_CURLY_BRACE
232#define BP_ELLIPSIS ALTGR(BP_DOT) // … 223#define BP_ELLIPSIS ALGR(BP_DOT) // …
233#define BP_ELPS BP_ELLIPSIS 224#define BP_ELPS BP_ELLIPSIS
234#define BP_TILDE ALTGR(BP_K) // ~ 225#define BP_TILDE ALGR(BP_K) // ~
235#define BP_TILD BP_TILDE 226#define BP_TILD BP_TILDE
236#define BP_INVERTED_QUESTION ALTGR(BP_QUESTION) // ¿ 227#define BP_INVERTED_QUESTION ALGR(BP_QUESTION) // ¿
237#define BP_IQST BP_INVERTED_QUESTION 228#define BP_IQST BP_INVERTED_QUESTION
238#define BP_DEAD_RING ALTGR(BP_Q) // dead ° 229#define BP_DEAD_RING ALGR(BP_Q) // dead °
239#define BP_DRNG BP_DEAD_RING 230#define BP_DRNG BP_DEAD_RING
240#define BP_DEAD_GREEK ALTGR(BP_G) // dead Greek key (following key will make a Greek letter) 231#define BP_DEAD_GREEK ALGR(BP_G) // dead Greek key (following key will make a Greek letter)
241#define BP_DGRK BP_DEAD_GREEK 232#define BP_DGRK BP_DEAD_GREEK
242#define BP_DAGGER ALTGR(BP_H) // † 233#define BP_DAGGER ALGR(BP_H) // †
243#define BP_DAGR BP_DAGGER 234#define BP_DAGR BP_DAGGER
244#define BP_DEAD_OGONEK ALTGR(BP_F) // dead ˛ 235#define BP_DEAD_OGONEK ALGR(BP_F) // dead ˛
245#define BP_DOGO BP_DEAD_OGONEK 236#define BP_DOGO BP_DEAD_OGONEK
246 237
247// Space bar 238// Space bar
248#define BP_UNDERSCORE ALTGR(KC_SPACE) // _ 239#define BP_UNDERSCORE ALGR(KC_SPACE) // _
249#define BP_UNDS BP_UNDERSCORE 240#define BP_UNDS BP_UNDERSCORE
250 241
251// AltGr-Shifted characters (different from capitalised AltGr-ed characters) 242// AltGr-Shifted characters (different from capitalised AltGr-ed characters)
252// First row 243// First row
253#define BP_PARAGRAPH ALTGR(BP_HASH) // ¶ 244#define BP_PARAGRAPH ALGR(BP_HASH) // ¶
254#define BP_PARG BP_PARAGRAPH 245#define BP_PARG BP_PARAGRAPH
255#define BP_LOW_DOUBLE_QUOTE ALTGR(BP_1) // „ 246#define BP_LOW_DOUBLE_QUOTE ALGR(BP_1) // „
256#define BP_LWQT BP_LOW_DOUBLE_QUOTE 247#define BP_LWQT BP_LOW_DOUBLE_QUOTE
257#define BP_LEFT_DOUBLE_QUOTE ALTGR(BP_2) // “ 248#define BP_LEFT_DOUBLE_QUOTE ALGR(BP_2) // “
258#define BP_LDQT BP_LEFT_DOUBLE_QUOTE 249#define BP_LDQT BP_LEFT_DOUBLE_QUOTE
259#define BP_RIGHT_DOUBLE_QUOTE ALTGR(BP_3) // ” 250#define BP_RIGHT_DOUBLE_QUOTE ALGR(BP_3) // ”
260#define BP_RDQT BP_RIGHT_DOUBLE_QUOTE 251#define BP_RDQT BP_RIGHT_DOUBLE_QUOTE
261#define BP_LESS_OR_EQUAL ALTGR(BP_4) // ≤ 252#define BP_LESS_OR_EQUAL ALGR(BP_4) // ≤
262#define BP_LEQL BP_LESS_OR_EQUAL 253#define BP_LEQL BP_LESS_OR_EQUAL
263#define BP_GREATER_OR_EQUAL ALTGR(BP_5) // ≥ 254#define BP_GREATER_OR_EQUAL ALGR(BP_5) // ≥
264#define BP_GEQL BP_GREATER_OR_EQUAL 255#define BP_GEQL BP_GREATER_OR_EQUAL
265// nothing on ALTGR(BP_6) 256// nothing on ALGR(BP_6)
266#define BP_NEGATION ALTGR(BP_7) // ¬ 257#define BP_NEGATION ALGR(BP_7) // ¬
267#define BP_NEGT BP_NEGATION 258#define BP_NEGT BP_NEGATION
268#define BP_ONE_QUARTER ALTGR(BP_8) // ¼ 259#define BP_ONE_QUARTER ALGR(BP_8) // ¼
269#define BP_1QRT BP_ONE_QUARTER 260#define BP_1QRT BP_ONE_QUARTER
270#define BP_ONE_HALF ALTGR(BP_9) // ½ 261#define BP_ONE_HALF ALGR(BP_9) // ½
271#define BP_1HLF BP_ONE_HALF 262#define BP_1HLF BP_ONE_HALF
272#define BP_THREE_QUARTERS ALTGR(BP_0) // ¾ 263#define BP_THREE_QUARTERS ALGR(BP_0) // ¾
273#define BP_3QRT BP_THREE_QUARTERS 264#define BP_3QRT BP_THREE_QUARTERS
274#define BP_MINUTES ALTGR(BP_DEGREE) // ′ 265#define BP_MINUTES ALGR(BP_DEGREE) // ′
275#define BP_MNUT BP_MINUTES 266#define BP_MNUT BP_MINUTES
276#define BP_SECONDS ALTGR(BP_GRAVE) // ″ 267#define BP_SECONDS ALGR(BP_GRAVE) // ″
277#define BP_SCND BP_SECONDS 268#define BP_SCND BP_SECONDS
278 269
279// Second row 270// Second row
@@ -281,7 +272,7 @@
281#define BP_BPIP BP_BROKEN_PIPE 272#define BP_BPIP BP_BROKEN_PIPE
282#define BP_DEAD_DOUBLE_ACUTE LSFT(BP_DEAD_ACUTE) // ˝ 273#define BP_DEAD_DOUBLE_ACUTE LSFT(BP_DEAD_ACUTE) // ˝
283#define BP_DDCT BP_DEAD_DOUBLE_ACUTE 274#define BP_DDCT BP_DEAD_DOUBLE_ACUTE
284#define BP_SECTION ALTGR(LSFT(BP_P)) // § 275#define BP_SECTION ALGR(LSFT(BP_P)) // §
285#define BP_SECT BP_SECTION 276#define BP_SECT BP_SECTION
286// LSFT(BP_DEAD_GRAVE) is actually the same character as LSFT(BP_PERCENT) 277// LSFT(BP_DEAD_GRAVE) is actually the same character as LSFT(BP_PERCENT)
287#define BP_GRAVE_BIS LSFT(BP_DEAD_GRAVE) // ` 278#define BP_GRAVE_BIS LSFT(BP_DEAD_GRAVE) // `
@@ -292,35 +283,35 @@
292#define BP_DDTA BP_DEAD_DOT_ABOVE 283#define BP_DDTA BP_DEAD_DOT_ABOVE
293#define BP_DEAD_CURRENCY LSFT(BP_EURO) // dead ¤ (next key will generate a currency code like ¥ or £) 284#define BP_DEAD_CURRENCY LSFT(BP_EURO) // dead ¤ (next key will generate a currency code like ¥ or £)
294#define BP_DCUR BP_DEAD_CURRENCY 285#define BP_DCUR BP_DEAD_CURRENCY
295#define BP_DEAD_HORN LSFT(ALTGR(BP_COMMA)) // dead ̛ 286#define BP_DEAD_HORN LSFT(ALGR(BP_COMMA)) // dead ̛
296#define BP_DHRN BP_DEAD_HORN 287#define BP_DHRN BP_DEAD_HORN
297#define BP_LONG_S LSFT(ALTGR(BP_C)) // ſ 288#define BP_LONG_S LSFT(ALGR(BP_C)) // ſ
298#define BP_LNGS BP_LONG_S 289#define BP_LNGS BP_LONG_S
299#define BP_TRADEMARK LSFT(BP_REGISTERED_TRADEMARK) // ™ 290#define BP_TRADEMARK LSFT(BP_REGISTERED_TRADEMARK) // ™
300#define BP_TM BP_TRADEMARK 291#define BP_TM BP_TRADEMARK
301#define BP_ORDINAL_INDICATOR_O LSFT(ALTGR(BP_M)) // º 292#define BP_ORDINAL_INDICATOR_O LSFT(ALGR(BP_M)) // º
302#define BP_ORDO BP_ORDINAL_INDICATOR_O 293#define BP_ORDO BP_ORDINAL_INDICATOR_O
303#define BP_DEAD_COMMA LSFT(BP_DEAD_CEDILLA) // dead ˛ 294#define BP_DEAD_COMMA LSFT(BP_DEAD_CEDILLA) // dead ˛
304#define BP_DCOM BP_DEAD_COMMA 295#define BP_DCOM BP_DEAD_COMMA
305 296
306// Fourth row 297// Fourth row
307#define BP_LEFT_QUOTE LSFT(ALTGR(BP_Y)) // ‘ 298#define BP_LEFT_QUOTE LSFT(ALGR(BP_Y)) // ‘
308#define BP_LQOT BP_LEFT_QUOTE 299#define BP_LQOT BP_LEFT_QUOTE
309#define BP_RIGHT_QUOTE LSFT(ALTGR(BP_X)) // ’ 300#define BP_RIGHT_QUOTE LSFT(ALGR(BP_X)) // ’
310#define BP_RQOT BP_RIGHT_QUOTE 301#define BP_RQOT BP_RIGHT_QUOTE
311#define BP_INTERPUNCT LSFT(ALTGR(BP_DOT)) // · 302#define BP_INTERPUNCT LSFT(ALGR(BP_DOT)) // ·
312#define BP_IPCT BP_INTERPUNCT 303#define BP_IPCT BP_INTERPUNCT
313#define BP_DEAD_HOOK_ABOVE LSFT(ALTGR(BP_QUESTION)) // dead ̉ 304#define BP_DEAD_HOOK_ABOVE LSFT(ALGR(BP_QUESTION)) // dead ̉
314#define BP_DHKA BP_DEAD_HOOK_ABOVE 305#define BP_DHKA BP_DEAD_HOOK_ABOVE
315#define BP_DEAD_UNDERDOT LSFT(BP_DEAD_RING) // dead ̣ 306#define BP_DEAD_UNDERDOT LSFT(BP_DEAD_RING) // dead ̣
316#define BP_DUDT BP_DEAD_UNDERDOT 307#define BP_DUDT BP_DEAD_UNDERDOT
317#define BP_DOUBLE_DAGGER LSFT(BP_DAGGER) // ‡ 308#define BP_DOUBLE_DAGGER LSFT(BP_DAGGER) // ‡
318#define BP_DDGR BP_DOUBLE_DAGGER 309#define BP_DDGR BP_DOUBLE_DAGGER
319#define BP_ORDINAL_INDICATOR_A LSFT(ALTGR(BP_F)) // ª 310#define BP_ORDINAL_INDICATOR_A LSFT(ALGR(BP_F)) // ª
320#define BP_ORDA BP_ORDINAL_INDICATOR_A 311#define BP_ORDA BP_ORDINAL_INDICATOR_A
321 312
322// Space bar 313// Space bar
323#define BP_NARROW_NON_BREAKING_SPACE ALTGR(BP_NON_BREAKING_SPACE) 314#define BP_NARROW_NON_BREAKING_SPACE ALGR(BP_NON_BREAKING_SPACE)
324#define BP_NNBS BP_NARROW_NON_BREAKING_SPACE 315#define BP_NNBS BP_NARROW_NON_BREAKING_SPACE
325 316
326#endif 317#endif
diff --git a/quantum/keymap_extras/keymap_canadian_multilingual.h b/quantum/keymap_extras/keymap_canadian_multilingual.h
index 1d45bee32..2b5b95d6f 100644
--- a/quantum/keymap_extras/keymap_canadian_multilingual.h
+++ b/quantum/keymap_extras/keymap_canadian_multilingual.h
@@ -13,22 +13,11 @@
13 * You should have received a copy of the GNU General Public License 13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>. 14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */ 15 */
16#ifndef KEYMAP_CANADIAN_MULTILINGUAG_H 16#ifndef KEYMAP_CANADIAN_MULTILINGUAL_H
17#define KEYMAP_CANADIAN_MULTILINGUAG_H 17#define KEYMAP_CANADIAN_MULTILINGUAL_H
18 18
19#include "keymap.h" 19#include "keymap.h"
20 20
21// Alt gr
22#ifndef ALTGR
23#define ALTGR(kc) RALT(kc)
24#endif
25#ifndef ALGR
26#define ALGR(kc) ALTGR(kc)
27#endif
28
29#define CSA_ALTGR KC_RALT
30#define CSA_ALGR CSA_ALTGR
31
32#ifndef GR2A 21#ifndef GR2A
33#define GR2A(kc) RCTL(kc) 22#define GR2A(kc) RCTL(kc)
34#endif 23#endif
@@ -78,43 +67,43 @@
78 67
79// Alt Gr-ed characters 68// Alt Gr-ed characters
80// First row 69// First row
81#define CSA_PIPE ALTGR(CSA_SLASH) // | 70#define CSA_PIPE ALGR(CSA_SLASH) // |
82#define CSA_CURRENCY ALTGR(KC_4) // ¤ 71#define CSA_CURRENCY ALGR(KC_4) // ¤
83#define CSA_CURR CSA_CURRENCY 72#define CSA_CURR CSA_CURRENCY
84#define CSA_LEFT_CURLY_BRACE ALTGR(KC_7) // { 73#define CSA_LEFT_CURLY_BRACE ALGR(KC_7) // {
85#define CSA_LCBR CSA_LEFT_CURLY_BRACE 74#define CSA_LCBR CSA_LEFT_CURLY_BRACE
86#define CSA_RIGHT_CURLY_BRACE ALTGR(KC_8) // } 75#define CSA_RIGHT_CURLY_BRACE ALGR(KC_8) // }
87#define CSA_RCBR CSA_RIGHT_CURLY_BRACE 76#define CSA_RCBR CSA_RIGHT_CURLY_BRACE
88#define CSA_LBRACKET ALTGR(KC_9) // [ 77#define CSA_LBRACKET ALGR(KC_9) // [
89#define CSA_LBRC CSA_LBRACKET 78#define CSA_LBRC CSA_LBRACKET
90#define CSA_RBRACKET ALTGR(KC_0) // ] 79#define CSA_RBRACKET ALGR(KC_0) // ]
91#define CSA_RBRC CSA_RBRACKET 80#define CSA_RBRC CSA_RBRACKET
92#define CSA_NEGATION ALTGR(KC_EQUAL) // ¬ 81#define CSA_NEGATION ALGR(KC_EQUAL) // ¬
93#define CSA_NEGT CSA_NEGATION 82#define CSA_NEGT CSA_NEGATION
94 83
95// Second row 84// Second row
96// euro symbol not available on Linux? (X.org) 85// euro symbol not available on Linux? (X.org)
97#define CSA_EURO ALTGR(KC_E) // € 86#define CSA_EURO ALGR(KC_E) // €
98#define CSA_DEAD_GRAVE ALTGR(CSA_DEAD_CIRCUMFLEX) 87#define CSA_DEAD_GRAVE ALGR(CSA_DEAD_CIRCUMFLEX)
99#define CSA_DGRV CSA_DEAD_GRAVE // dead ` 88#define CSA_DGRV CSA_DEAD_GRAVE // dead `
100#define CSA_DEAD_TILDE ALTGR(CSA_C_CEDILLA) // ~ 89#define CSA_DEAD_TILDE ALGR(CSA_C_CEDILLA) // ~
101#define CSA_DTLD CSA_DEAD_TILDE 90#define CSA_DTLD CSA_DEAD_TILDE
102 91
103// Third row 92// Third row
104#define CSA_DEGREE ALTGR(KC_SCOLON) // ° 93#define CSA_DEGREE ALGR(KC_SCOLON) // °
105#define CSA_DEGR CSA_DEGREE 94#define CSA_DEGR CSA_DEGREE
106 95
107// Fourth row 96// Fourth row
108#define CSA_LEFT_GUILLEMET ALTGR(KC_Z) // « 97#define CSA_LEFT_GUILLEMET ALGR(KC_Z) // «
109#define CSA_LGIL CSA_LEFT_GUILLEMET 98#define CSA_LGIL CSA_LEFT_GUILLEMET
110#define CSA_RIGHT_GUILLEMET ALTGR(KC_X) // » 99#define CSA_RIGHT_GUILLEMET ALGR(KC_X) // »
111#define CSA_RGIL CSA_RIGHT_GUILLEMET 100#define CSA_RGIL CSA_RIGHT_GUILLEMET
112#define CSA_LESS ALTGR(KC_COMMA) // < 101#define CSA_LESS ALGR(KC_COMMA) // <
113#define CSA_GREATER ALTGR(KC_DOT) // > 102#define CSA_GREATER ALGR(KC_DOT) // >
114#define CSA_GRTR CSA_GREATER 103#define CSA_GRTR CSA_GREATER
115 104
116// Space bar 105// Space bar
117#define CSA_NON_BREAKING_SPACE ALTGR(KC_SPACE) 106#define CSA_NON_BREAKING_SPACE ALGR(KC_SPACE)
118#define CSA_NBSP CSA_NON_BREAKING_SPACE 107#define CSA_NBSP CSA_NON_BREAKING_SPACE
119 108
120// GR2A-ed characters 109// GR2A-ed characters
@@ -201,7 +190,7 @@
201// nothing on 2 190// nothing on 2
202#define CSA_POUND GR2A(LSFT(KC_3)) // £ 191#define CSA_POUND GR2A(LSFT(KC_3)) // £
203#define CSA_GBP CSA_POUND_SIGN 192#define CSA_GBP CSA_POUND_SIGN
204// already on ALTGR(KC_E) 193// already on ALGR(KC_E)
205#define CSA_EURO_BIS GR2A(LSFT(KC_4)) // € 194#define CSA_EURO_BIS GR2A(LSFT(KC_4)) // €
206#define CSA_EURB CSA_EURO_BIS 195#define CSA_EURB CSA_EURO_BIS
207#define CSA_THREE_EIGHTHS GR2A(LSFT(KC_5)) // ⅜ 196#define CSA_THREE_EIGHTHS GR2A(LSFT(KC_5)) // ⅜
diff --git a/quantum/keymap_extras/keymap_fr_ch.h b/quantum/keymap_extras/keymap_fr_ch.h
index c0ca832a6..69f9547bb 100644
--- a/quantum/keymap_extras/keymap_fr_ch.h
+++ b/quantum/keymap_extras/keymap_fr_ch.h
@@ -18,10 +18,6 @@
18 18
19#include "keymap.h" 19#include "keymap.h"
20 20
21// Alt gr
22#define ALGR(kc) RALT(kc)
23#define FR_CH_ALGR KC_RALT
24
25// normal characters 21// normal characters
26#define FR_CH_Z KC_Y 22#define FR_CH_Z KC_Y
27#define FR_CH_Y KC_Z 23#define FR_CH_Y KC_Z
diff --git a/quantum/keymap_extras/keymap_french.h b/quantum/keymap_extras/keymap_french.h
index 3308dc5f7..bef775470 100644
--- a/quantum/keymap_extras/keymap_french.h
+++ b/quantum/keymap_extras/keymap_french.h
@@ -18,12 +18,6 @@
18 18
19#include "keymap.h" 19#include "keymap.h"
20 20
21// Alt gr
22#ifndef ALGR
23#define ALGR(kc) RALT(kc)
24#endif
25#define NO_ALGR KC_RALT
26
27// Normal characters 21// Normal characters
28#define FR_SUP2 KC_GRV 22#define FR_SUP2 KC_GRV
29#define FR_AMP KC_1 23#define FR_AMP KC_1
diff --git a/quantum/keymap_extras/keymap_german.h b/quantum/keymap_extras/keymap_german.h
index e007c26ef..0ba3570df 100644
--- a/quantum/keymap_extras/keymap_german.h
+++ b/quantum/keymap_extras/keymap_german.h
@@ -19,10 +19,6 @@
19 19
20#include "keymap.h" 20#include "keymap.h"
21 21
22// Alt gr
23#define ALGR(kc) RALT(kc)
24#define DE_ALGR KC_RALT
25
26// normal characters 22// normal characters
27#define DE_Z KC_Y 23#define DE_Z KC_Y
28#define DE_Y KC_Z 24#define DE_Y KC_Z
diff --git a/quantum/keymap_extras/keymap_german_ch.h b/quantum/keymap_extras/keymap_german_ch.h
index 67350d660..bd1ef89a1 100644
--- a/quantum/keymap_extras/keymap_german_ch.h
+++ b/quantum/keymap_extras/keymap_german_ch.h
@@ -18,10 +18,6 @@
18 18
19#include "keymap.h" 19#include "keymap.h"
20 20
21// Alt gr
22#define ALGR(kc) RALT(kc)
23#define CH_ALGR KC_RALT
24
25// normal characters 21// normal characters
26#define CH_Z KC_Y 22#define CH_Z KC_Y
27#define CH_Y KC_Z 23#define CH_Y KC_Z
diff --git a/quantum/keymap_extras/keymap_hungarian.h b/quantum/keymap_extras/keymap_hungarian.h
index b37244092..ff43535f3 100644
--- a/quantum/keymap_extras/keymap_hungarian.h
+++ b/quantum/keymap_extras/keymap_hungarian.h
@@ -19,10 +19,6 @@
19 19
20#include "keymap.h" 20#include "keymap.h"
21 21
22// Alt gr
23#define ALGR(kc) RALT(kc)
24#define HU_ALGR KC_RALT
25
26// basic letters 22// basic letters
27#define HU_Z KC_Y 23#define HU_Z KC_Y
28#define HU_Y KC_Z 24#define HU_Y KC_Z
diff --git a/quantum/keymap_extras/keymap_italian.h b/quantum/keymap_extras/keymap_italian.h
index 0ff6ce876..fe0f5eb84 100644
--- a/quantum/keymap_extras/keymap_italian.h
+++ b/quantum/keymap_extras/keymap_italian.h
@@ -19,14 +19,7 @@
19 19
20#include "keymap.h" 20#include "keymap.h"
21 21
22// Alt gr
23#define ALGR(kc) RALT(kc)
24#define IT_ALGR KC_RALT
25
26// normal characters 22// normal characters
27
28
29
30#define IT_A KC_A 23#define IT_A KC_A
31#define IT_B KC_B 24#define IT_B KC_B
32#define IT_C KC_C 25#define IT_C KC_C
diff --git a/quantum/keymap_extras/keymap_jp.h b/quantum/keymap_extras/keymap_jp.h
index fb74bce8d..b0235f112 100644
--- a/quantum/keymap_extras/keymap_jp.h
+++ b/quantum/keymap_extras/keymap_jp.h
@@ -40,6 +40,9 @@
40#define JP_HENK KC_INT4 // henkan 40#define JP_HENK KC_INT4 // henkan
41#define JP_KANA KC_INT2 // katakana/hiragana|ro-mazi 41#define JP_KANA KC_INT2 // katakana/hiragana|ro-mazi
42 42
43#define JP_MKANA KC_LANG1 //kana on MacOSX
44#define JP_MEISU KC_LANG2 //eisu on MacOSX
45
43 46
44//Aliases for shifted symbols 47//Aliases for shifted symbols
45#define JP_DQT LSFT(KC_2) // " 48#define JP_DQT LSFT(KC_2) // "
diff --git a/quantum/keymap_extras/keymap_neo2.h b/quantum/keymap_extras/keymap_neo2.h
index 174f4a6ee..818a739c7 100644
--- a/quantum/keymap_extras/keymap_neo2.h
+++ b/quantum/keymap_extras/keymap_neo2.h
@@ -73,6 +73,6 @@
73#define NEO_L1_R DE_HASH 73#define NEO_L1_R DE_HASH
74 74
75#define NEO_L2_L DE_LESS 75#define NEO_L2_L DE_LESS
76#define NEO_L2_R DE_ALGR 76#define NEO_L2_R KC_ALGR
77 77
78#endif 78#endif
diff --git a/quantum/keymap_extras/keymap_nordic.h b/quantum/keymap_extras/keymap_nordic.h
index 6b34db558..551a4212b 100644
--- a/quantum/keymap_extras/keymap_nordic.h
+++ b/quantum/keymap_extras/keymap_nordic.h
@@ -18,10 +18,6 @@
18 18
19#include "keymap.h" 19#include "keymap.h"
20 20
21// Alt gr
22#define ALGR(kc) RALT(kc)
23#define NO_ALGR KC_RALT
24
25// Normal characters 21// Normal characters
26#define NO_HALF KC_GRV 22#define NO_HALF KC_GRV
27#define NO_PLUS KC_MINS 23#define NO_PLUS KC_MINS
diff --git a/quantum/keymap_extras/keymap_plover_dvorak.h b/quantum/keymap_extras/keymap_plover_dvorak.h
new file mode 100644
index 000000000..83bb1e8b8
--- /dev/null
+++ b/quantum/keymap_extras/keymap_plover_dvorak.h
@@ -0,0 +1,47 @@
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 */
16#ifndef KEYMAP_PLOVER_DVORAK_H
17#define KEYMAP_PLOVER_DVORAK_H
18
19#include "keymap_dvorak.h"
20
21#define PD_NUM DV_1
22#define PD_LS DV_Q
23#define PD_LT DV_W
24#define PD_LP DV_E
25#define PD_LH DV_R
26#define PD_LK DV_S
27#define PD_LW DV_D
28#define PD_LR DV_F
29
30#define PD_STAR DV_Y
31#define PD_RF DV_U
32#define PD_RP DV_I
33#define PD_RL DV_O
34#define PD_RT DV_P
35#define PD_RD DV_LBRC
36#define PD_RR DV_J
37#define PD_RB DV_K
38#define PD_RG DV_L
39#define PD_RS DV_SCLN
40#define PD_RZ DV_QUOT
41
42#define PD_A DV_C
43#define PD_O DV_V
44#define PD_E DV_N
45#define PD_U DV_M
46
47#endif
diff --git a/quantum/keymap_extras/keymap_slovenian.h b/quantum/keymap_extras/keymap_slovenian.h
new file mode 100644
index 000000000..892283e70
--- /dev/null
+++ b/quantum/keymap_extras/keymap_slovenian.h
@@ -0,0 +1,107 @@
1/* Copyright 2018 Žan Pevec
2
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#ifndef KEYMAP_SLOVENIAN
19#define KEYMAP_SLOVENIAN
20
21#include "keymap.h"
22
23//Swapped Z and Y
24#define SI_Z KC_Y
25#define SI_Y KC_Z
26
27//Special characters
28#define SI_CV KC_SCLN
29#define SI_SV KC_LBRC
30#define SI_ZV KC_BSLS
31
32#define SI_A KC_A
33#define SI_B KC_B
34#define SI_C KC_C
35#define SI_D KC_D
36#define SI_E KC_E
37#define SI_F KC_F
38#define SI_G KC_G
39#define SI_H KC_H
40#define SI_I KC_I
41#define SI_J KC_J
42#define SI_K KC_K
43#define SI_L KC_L
44#define SI_M KC_M
45#define SI_N KC_N
46#define SI_O KC_O
47#define SI_P KC_P
48#define SI_Q KC_Q
49#define SI_R KC_R
50#define SI_S KC_S
51#define SI_T KC_T
52#define SI_U KC_U
53#define SI_V KC_V
54#define SI_W KC_W
55#define SI_X KC_X
56
57#define SI_0 KC_0
58#define SI_1 KC_1
59#define SI_2 KC_2
60#define SI_3 KC_3
61#define SI_4 KC_4
62#define SI_5 KC_5
63#define SI_6 KC_6
64#define SI_7 KC_7
65#define SI_8 KC_8
66#define SI_9 KC_9
67
68#define SI_DOT KC_DOT
69#define SI_COMM KC_COMM
70
71#define SI_PLUS KC_EQL // + and * and ~
72#define SI_QOT KC_MINS // Single quote
73#define SI_MINS KC_SLSH // - and _
74
75// shifted characters
76#define SI_EXLM LSFT(KC_1) // !
77#define SI_DQOT LSFT(KC_2) // "
78#define SI_HASH LSFT(KC_3) // #
79#define SI_DLR LSFT(KC_4) // $
80#define SI_PERC LSFT(KC_5) // %
81#define SI_AMPR LSFT(KC_6) // &
82#define SI_SLSH LSFT(KC_7) // /
83#define SI_LPRN LSFT(KC_8) // (
84#define SI_RPRN LSFT(KC_9) // )
85#define SI_EQL LSFT(KC_0) // =
86#define SI_QST LSFT(SI_QOT) // ?
87#define SI_ASTR LSFT(SI_PLUS) // *
88#define SI_COLN LSFT(KC_DOT) // :
89#define SI_SCLN LSFT(KC_COMM) // ;
90#define SI_UNDS LSFT(SI_MINS) // _
91
92// Alt Gr-ed characters
93#define SI_CIRC ALGR(KC_3) // ^
94#define SI_DEG ALGR(KC_5) // °
95#define SI_GRV ALGR(KC_7) // `
96#define SI_ACCU ALGR(KC_9) // ´
97#define SI_LCBR ALGR(KC_B) // {
98#define SI_RCBR ALGR(KC_N) // }
99#define SI_LBRC ALGR(KC_F) // [
100#define SI_RBRC ALGR(KC_G) // ]
101#define SI_BSLS ALGR(KC_Q) // backslash
102#define SI_AT ALGR(KC_V) // @
103#define SI_EURO ALGR(KC_E) // €
104#define SI_TILD ALGR(KC_1) // ~
105#define SI_PIPE ALGR(KC_W) // |
106
107#endif
diff --git a/quantum/keymap_extras/keymap_spanish.h b/quantum/keymap_extras/keymap_spanish.h
index 224db7be1..1f183327f 100644
--- a/quantum/keymap_extras/keymap_spanish.h
+++ b/quantum/keymap_extras/keymap_spanish.h
@@ -18,10 +18,6 @@
18 18
19#include "keymap.h" 19#include "keymap.h"
20 20
21// Alt gr
22#define ALGR(kc) RALT(kc)
23#define NO_ALGR KC_RALT
24
25// Normal characters 21// Normal characters
26#define ES_OVRR KC_GRV 22#define ES_OVRR KC_GRV
27#define ES_APOS KC_MINS 23#define ES_APOS KC_MINS
diff --git a/quantum/keymap_extras/keymap_swedish.h b/quantum/keymap_extras/keymap_swedish.h
index 9044bb74e..d1a0f4f22 100644
--- a/quantum/keymap_extras/keymap_swedish.h
+++ b/quantum/keymap_extras/keymap_swedish.h
@@ -41,8 +41,8 @@
41#define NO_DLR_MAC LSFT(KC_4) // $ 41#define NO_DLR_MAC LSFT(KC_4) // $
42#define NO_GRV_MAC ALGR(NO_BSLS) // ` 42#define NO_GRV_MAC ALGR(NO_BSLS) // `
43#define NO_GRTR_MAC LSFT(KC_GRV) // > 43#define NO_GRTR_MAC LSFT(KC_GRV) // >
44#define NO_LCBR_MAC ALGR(LSFT(KC_8)) // } 44#define NO_LCBR_MAC ALGR(LSFT(KC_8)) // {
45#define NO_LESS_MAC KC_GRV // > 45#define NO_LESS_MAC KC_GRV // <
46#define NO_PIPE_MAC ALGR(KC_7) // | 46#define NO_PIPE_MAC ALGR(KC_7) // |
47#define NO_RCBR_MAC ALGR(LSFT(KC_9)) // } 47#define NO_RCBR_MAC ALGR(LSFT(KC_9)) // }
48 48
diff --git a/quantum/keymap_extras/keymap_uk.h b/quantum/keymap_extras/keymap_uk.h
index de47103cb..cc3d0039e 100644
--- a/quantum/keymap_extras/keymap_uk.h
+++ b/quantum/keymap_extras/keymap_uk.h
@@ -18,10 +18,6 @@
18 18
19#include "keymap.h" 19#include "keymap.h"
20 20
21// Alt gr
22#define ALGR(kc) RALT(kc)
23#define NO_ALGR KC_RALT
24
25// Normal characters 21// Normal characters
26#define UK_HASH KC_NUHS 22#define UK_HASH KC_NUHS
27#define UK_BSLS KC_NUBS 23#define UK_BSLS KC_NUBS
diff --git a/quantum/keymap_extras/sendstring_german.h b/quantum/keymap_extras/sendstring_german.h
new file mode 100644
index 000000000..1eaafee31
--- /dev/null
+++ b/quantum/keymap_extras/sendstring_german.h
@@ -0,0 +1,81 @@
1/* Copyright 2018 Patrick Hener
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16/* Sendstring definitions for the German layout */
17#ifndef SENDSTRING_GERMAN
18#define SENDSTRING_GERMAN
19
20#include "keymap_german.h"
21
22const bool ascii_to_shift_lut[0x80] PROGMEM = {
23 0, 0, 0, 0, 0, 0, 0, 0,
24 0, 0, 0, 0, 0, 0, 0, 0,
25 0, 0, 0, 0, 0, 0, 0, 0,
26 0, 0, 0, 0, 0, 0, 0, 0,
27
28 0, 1, 1, 0, 1, 1, 1, 1,
29 1, 1, 1, 0, 0, 0, 0, 1,
30 0, 0, 0, 0, 0, 0, 0, 0,
31 0, 0, 1, 1, 0, 1, 1, 1,
32 1, 1, 1, 1, 1, 1, 1, 1,
33 1, 1, 1, 1, 1, 1, 1, 1,
34 1, 1, 1, 1, 1, 1, 1, 1,
35 1, 1, 1, 0, 0, 0, 0, 1,
36 1, 0, 0, 0, 0, 0, 0, 0,
37 0, 0, 0, 0, 0, 0, 0, 0,
38 0, 0, 0, 0, 0, 0, 0, 0,
39 0, 0, 0, 1, 1, 1, 1, 0
40};
41
42/* Until an ALT table/functionality is added, the following symbols will not work:
43* § @ [ ] { } \ ~ äA öÖ ß ´
44* Following characters can be printed using other characters like so:
45* [ in makro will be ü
46* { in makro will be Ü
47* ~ in makro will be °
48*/
49const uint8_t ascii_to_keycode_lut[0x80] PROGMEM = {
50 0, 0, 0, 0, 0, 0, 0, 0,
51 KC_BSPC, KC_TAB, KC_ENT, 0, 0, 0, 0, 0,
52 0, 0, 0, 0, 0, 0, 0, 0,
53 0, 0, 0, KC_ESC, 0, 0, 0, 0,
54
55 /* SPACE ! " # $ % & ' */
56 KC_SPC, KC_1, KC_2, DE_HASH, KC_4, KC_5, KC_6, DE_HASH,
57 /* ( ) * + , - . / */
58 KC_8, KC_9, DE_PLUS, DE_PLUS, KC_COMM, DE_MINS, KC_DOT, KC_7,
59 /* 0 1 2 3 4 5 6 7 */
60 KC_0, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7,
61 /* 8 9 : ; < = > ? */
62 KC_8, KC_9, KC_DOT, KC_COMM, DE_LESS, KC_0, DE_LESS, KC_MINS,
63 /* @ A B C D E F G */
64 KC_2, KC_A, KC_B, KC_C, KC_D, KC_E, KC_F, KC_G,
65 /* H I J K L M N O */
66 KC_H, KC_I, KC_J, KC_K, KC_L, KC_M, KC_N, KC_O,
67 /* P Q R S T U V W */
68 KC_P, KC_Q, KC_R, KC_S, KC_T, KC_U, KC_V, KC_W,
69 /* X Y Z [ \ ] ^ _ */
70 KC_X, KC_Y, KC_Z, KC_LBRC, KC_BSLS, KC_RBRC, DE_CIRC, DE_MINS,
71 /* ` a b c d e f g */
72 DE_ACUT, KC_A, KC_B, KC_C, KC_D, KC_E, KC_F, KC_G,
73 /* h i j k l m n o */
74 KC_H, KC_I, KC_J, KC_K, KC_L, KC_M, KC_N, KC_O,
75 /* p q r s t u v w */
76 KC_P, KC_Q, KC_R, KC_S, KC_T, KC_U, KC_V, KC_W,
77 /* x y z { | } ~ DELETE */
78 KC_X, KC_Y, KC_Z, KC_LBRC, KC_BSLS, KC_RBRC, KC_GRV, KC_DEL
79};
80
81#endif
diff --git a/quantum/matrix.c b/quantum/matrix.c
index bc7eb6b58..292171490 100644
--- a/quantum/matrix.c
+++ b/quantum/matrix.c
@@ -1,5 +1,5 @@
1/* 1/*
2Copyright 2012-2017 Jun Wako, Jack Humbert 2Copyright 2012-2018 Jun Wako, Jack Humbert, Yiancar
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
@@ -16,15 +16,13 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
16*/ 16*/
17#include <stdint.h> 17#include <stdint.h>
18#include <stdbool.h> 18#include <stdbool.h>
19#if defined(__AVR__)
20#include <avr/io.h>
21#endif
22#include "wait.h" 19#include "wait.h"
23#include "print.h" 20#include "print.h"
24#include "debug.h" 21#include "debug.h"
25#include "util.h" 22#include "util.h"
26#include "matrix.h" 23#include "matrix.h"
27#include "timer.h" 24#include "timer.h"
25#include "quantum.h"
28 26
29 27
30#if (MATRIX_COLS <= 8) 28#if (MATRIX_COLS <= 8)
@@ -49,8 +47,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
49#endif 47#endif
50 48
51#if (DIODE_DIRECTION == ROW2COL) || (DIODE_DIRECTION == COL2ROW) 49#if (DIODE_DIRECTION == ROW2COL) || (DIODE_DIRECTION == COL2ROW)
52static const uint8_t row_pins[MATRIX_ROWS] = MATRIX_ROW_PINS; 50static const pin_t row_pins[MATRIX_ROWS] = MATRIX_ROW_PINS;
53static const uint8_t col_pins[MATRIX_COLS] = MATRIX_COL_PINS; 51static const pin_t col_pins[MATRIX_COLS] = MATRIX_COL_PINS;
54#endif 52#endif
55 53
56/* matrix state(1:on, 0:off) */ 54/* matrix state(1:on, 0:off) */
@@ -198,9 +196,7 @@ uint8_t matrix_key_count(void)
198static void init_cols(void) 196static void init_cols(void)
199{ 197{
200 for(uint8_t x = 0; x < MATRIX_COLS; x++) { 198 for(uint8_t x = 0; x < MATRIX_COLS; x++) {
201 uint8_t pin = col_pins[x]; 199 setPinInputHigh(col_pins[x]);
202 _SFR_IO8((pin >> 4) + 1) &= ~_BV(pin & 0xF); // IN
203 _SFR_IO8((pin >> 4) + 2) |= _BV(pin & 0xF); // HI
204 } 200 }
205} 201}
206 202
@@ -220,8 +216,7 @@ static bool read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row)
220 for(uint8_t col_index = 0; col_index < MATRIX_COLS; col_index++) { 216 for(uint8_t col_index = 0; col_index < MATRIX_COLS; col_index++) {
221 217
222 // Select the col pin to read (active low) 218 // Select the col pin to read (active low)
223 uint8_t pin = col_pins[col_index]; 219 uint8_t pin_state = readPin(col_pins[col_index]);
224 uint8_t pin_state = (_SFR_IO8(pin >> 4) & _BV(pin & 0xF));
225 220
226 // Populate the matrix row with the state of the col pin 221 // Populate the matrix row with the state of the col pin
227 current_matrix[current_row] |= pin_state ? 0 : (ROW_SHIFTER << col_index); 222 current_matrix[current_row] |= pin_state ? 0 : (ROW_SHIFTER << col_index);
@@ -235,24 +230,19 @@ static bool read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row)
235 230
236static void select_row(uint8_t row) 231static void select_row(uint8_t row)
237{ 232{
238 uint8_t pin = row_pins[row]; 233 setPinOutput(row_pins[row]);
239 _SFR_IO8((pin >> 4) + 1) |= _BV(pin & 0xF); // OUT 234 writePinLow(row_pins[row]);
240 _SFR_IO8((pin >> 4) + 2) &= ~_BV(pin & 0xF); // LOW
241} 235}
242 236
243static void unselect_row(uint8_t row) 237static void unselect_row(uint8_t row)
244{ 238{
245 uint8_t pin = row_pins[row]; 239 setPinInputHigh(row_pins[row]);
246 _SFR_IO8((pin >> 4) + 1) &= ~_BV(pin & 0xF); // IN
247 _SFR_IO8((pin >> 4) + 2) |= _BV(pin & 0xF); // HI
248} 240}
249 241
250static void unselect_rows(void) 242static void unselect_rows(void)
251{ 243{
252 for(uint8_t x = 0; x < MATRIX_ROWS; x++) { 244 for(uint8_t x = 0; x < MATRIX_ROWS; x++) {
253 uint8_t pin = row_pins[x]; 245 setPinInput(row_pins[x]);
254 _SFR_IO8((pin >> 4) + 1) &= ~_BV(pin & 0xF); // IN
255 _SFR_IO8((pin >> 4) + 2) |= _BV(pin & 0xF); // HI
256 } 246 }
257} 247}
258 248
@@ -261,9 +251,7 @@ static void unselect_rows(void)
261static void init_rows(void) 251static void init_rows(void)
262{ 252{
263 for(uint8_t x = 0; x < MATRIX_ROWS; x++) { 253 for(uint8_t x = 0; x < MATRIX_ROWS; x++) {
264 uint8_t pin = row_pins[x]; 254 setPinInputHigh(row_pins[x]);
265 _SFR_IO8((pin >> 4) + 1) &= ~_BV(pin & 0xF); // IN
266 _SFR_IO8((pin >> 4) + 2) |= _BV(pin & 0xF); // HI
267 } 255 }
268} 256}
269 257
@@ -283,7 +271,7 @@ static bool read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col)
283 matrix_row_t last_row_value = current_matrix[row_index]; 271 matrix_row_t last_row_value = current_matrix[row_index];
284 272
285 // Check row pin state 273 // Check row pin state
286 if ((_SFR_IO8(row_pins[row_index] >> 4) & _BV(row_pins[row_index] & 0xF)) == 0) 274 if (readPin(row_pins[row_index]) == 0)
287 { 275 {
288 // Pin LO, set col bit 276 // Pin LO, set col bit
289 current_matrix[row_index] |= (ROW_SHIFTER << current_col); 277 current_matrix[row_index] |= (ROW_SHIFTER << current_col);
@@ -309,24 +297,19 @@ static bool read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col)
309 297
310static void select_col(uint8_t col) 298static void select_col(uint8_t col)
311{ 299{
312 uint8_t pin = col_pins[col]; 300 setPinOutput(col_pins[col]);
313 _SFR_IO8((pin >> 4) + 1) |= _BV(pin & 0xF); // OUT 301 writePinLow(col_pins[col]);
314 _SFR_IO8((pin >> 4) + 2) &= ~_BV(pin & 0xF); // LOW
315} 302}
316 303
317static void unselect_col(uint8_t col) 304static void unselect_col(uint8_t col)
318{ 305{
319 uint8_t pin = col_pins[col]; 306 setPinInputHigh(col_pins[col]);
320 _SFR_IO8((pin >> 4) + 1) &= ~_BV(pin & 0xF); // IN
321 _SFR_IO8((pin >> 4) + 2) |= _BV(pin & 0xF); // HI
322} 307}
323 308
324static void unselect_cols(void) 309static void unselect_cols(void)
325{ 310{
326 for(uint8_t x = 0; x < MATRIX_COLS; x++) { 311 for(uint8_t x = 0; x < MATRIX_COLS; x++) {
327 uint8_t pin = col_pins[x]; 312 setPinInputHigh(col_pins[x]);
328 _SFR_IO8((pin >> 4) + 1) &= ~_BV(pin & 0xF); // IN
329 _SFR_IO8((pin >> 4) + 2) |= _BV(pin & 0xF); // HI
330 } 313 }
331} 314}
332 315
diff --git a/quantum/process_keycode/process_auto_shift.c b/quantum/process_keycode/process_auto_shift.c
index 01d99445b..0d0930ee6 100644
--- a/quantum/process_keycode/process_auto_shift.c
+++ b/quantum/process_keycode/process_auto_shift.c
@@ -173,6 +173,8 @@ bool process_auto_shift(uint16_t keycode, keyrecord_t *record) {
173 case KC_DOT: 173 case KC_DOT:
174 case KC_SLSH: 174 case KC_SLSH:
175 case KC_GRAVE: 175 case KC_GRAVE:
176 case KC_NONUS_BSLASH:
177 case KC_NONUS_HASH:
176#endif 178#endif
177 179
178 autoshift_flush(); 180 autoshift_flush();
diff --git a/quantum/process_keycode/process_chording.c b/quantum/process_keycode/process_chording.c
deleted file mode 100644
index 6c6ebe300..000000000
--- a/quantum/process_keycode/process_chording.c
+++ /dev/null
@@ -1,76 +0,0 @@
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_chording.h"
18
19bool keys_chord(uint8_t keys[]) {
20 uint8_t keys_size = sizeof(keys)/sizeof(keys[0]);
21 bool pass = true;
22 uint8_t in = 0;
23 for (uint8_t i = 0; i < chord_key_count; i++) {
24 bool found = false;
25 for (uint8_t j = 0; j < keys_size; j++) {
26 if (chord_keys[i] == (keys[j] & 0xFF)) {
27 in++; // detects key in chord
28 found = true;
29 break;
30 }
31 }
32 if (found)
33 continue;
34 if (chord_keys[i] != 0) {
35 pass = false; // makes sure rest are blank
36 }
37 }
38 return (pass && (in == keys_size));
39}
40
41bool process_chording(uint16_t keycode, keyrecord_t *record) {
42 if (keycode >= QK_CHORDING && keycode <= QK_CHORDING_MAX) {
43 if (record->event.pressed) {
44 if (!chording) {
45 chording = true;
46 for (uint8_t i = 0; i < CHORDING_MAX; i++)
47 chord_keys[i] = 0;
48 chord_key_count = 0;
49 chord_key_down = 0;
50 }
51 chord_keys[chord_key_count] = (keycode & 0xFF);
52 chord_key_count++;
53 chord_key_down++;
54 return false;
55 } else {
56 if (chording) {
57 chord_key_down--;
58 if (chord_key_down == 0) {
59 chording = false;
60 // Chord Dictionary
61 if (keys_chord((uint8_t[]){KC_ENTER, KC_SPACE})) {
62 register_code(KC_A);
63 unregister_code(KC_A);
64 return false;
65 }
66 for (uint8_t i = 0; i < chord_key_count; i++) {
67 register_code(chord_keys[i]);
68 unregister_code(chord_keys[i]);
69 return false;
70 }
71 }
72 }
73 }
74 }
75 return true;
76}
diff --git a/quantum/process_keycode/process_clicky.c b/quantum/process_keycode/process_clicky.c
index 1e950d111..8238c263f 100644
--- a/quantum/process_keycode/process_clicky.c
+++ b/quantum/process_keycode/process_clicky.c
@@ -3,11 +3,6 @@
3 3
4#ifdef AUDIO_CLICKY 4#ifdef AUDIO_CLICKY
5 5
6#ifdef AUDIO_CLICKY_ON
7bool clicky_enable = true;
8#else // AUDIO_CLICKY_ON
9bool clicky_enable = false;
10#endif // AUDIO_CLICKY_ON
11#ifndef AUDIO_CLICKY_FREQ_DEFAULT 6#ifndef AUDIO_CLICKY_FREQ_DEFAULT
12#define AUDIO_CLICKY_FREQ_DEFAULT 440.0f 7#define AUDIO_CLICKY_FREQ_DEFAULT 440.0f
13#endif // !AUDIO_CLICKY_FREQ_DEFAULT 8#endif // !AUDIO_CLICKY_FREQ_DEFAULT
@@ -25,8 +20,11 @@ bool clicky_enable = false;
25#endif // !AUDIO_CLICKY_FREQ_RANDOMNESS 20#endif // !AUDIO_CLICKY_FREQ_RANDOMNESS
26 21
27float clicky_freq = AUDIO_CLICKY_FREQ_DEFAULT; 22float clicky_freq = AUDIO_CLICKY_FREQ_DEFAULT;
23float clicky_rand = AUDIO_CLICKY_FREQ_RANDOMNESS;
28float clicky_song[][2] = {{AUDIO_CLICKY_FREQ_DEFAULT, 3}, {AUDIO_CLICKY_FREQ_DEFAULT, 1}}; // 3 and 1 --> durations 24float clicky_song[][2] = {{AUDIO_CLICKY_FREQ_DEFAULT, 3}, {AUDIO_CLICKY_FREQ_DEFAULT, 1}}; // 3 and 1 --> durations
29 25
26extern audio_config_t audio_config;
27
30#ifndef NO_MUSIC_MODE 28#ifndef NO_MUSIC_MODE
31extern bool music_activated; 29extern bool music_activated;
32extern bool midi_activated; 30extern bool midi_activated;
@@ -36,31 +34,61 @@ void clicky_play(void) {
36#ifndef NO_MUSIC_MODE 34#ifndef NO_MUSIC_MODE
37 if (music_activated || midi_activated) return; 35 if (music_activated || midi_activated) return;
38#endif // !NO_MUSIC_MODE 36#endif // !NO_MUSIC_MODE
39 clicky_song[0][0] = 2.0f * clicky_freq * (1.0f + AUDIO_CLICKY_FREQ_RANDOMNESS * ( ((float)rand()) / ((float)(RAND_MAX)) ) ); 37 clicky_song[0][0] = 2.0f * clicky_freq * (1.0f + clicky_rand * ( ((float)rand()) / ((float)(RAND_MAX)) ) );
40 clicky_song[1][0] = clicky_freq * (1.0f + AUDIO_CLICKY_FREQ_RANDOMNESS * ( ((float)rand()) / ((float)(RAND_MAX)) ) ); 38 clicky_song[1][0] = clicky_freq * (1.0f + clicky_rand * ( ((float)rand()) / ((float)(RAND_MAX)) ) );
41 PLAY_SONG(clicky_song); 39 PLAY_SONG(clicky_song);
42} 40}
43 41
42void clicky_freq_up(void) {
43 float new_freq = clicky_freq * AUDIO_CLICKY_FREQ_FACTOR;
44 if (new_freq < AUDIO_CLICKY_FREQ_MAX) {
45 clicky_freq = new_freq;
46 }
47}
48
49void clicky_freq_down(void) {
50 float new_freq = clicky_freq / AUDIO_CLICKY_FREQ_FACTOR;
51 if (new_freq > AUDIO_CLICKY_FREQ_MIN) {
52 clicky_freq = new_freq;
53 }
54}
55
56void clicky_freq_reset(void) {
57 clicky_freq = AUDIO_CLICKY_FREQ_DEFAULT;
58}
59
60void clicky_toggle(void) {
61 audio_config.clicky_enable ^= 1;
62 eeconfig_update_audio(audio_config.raw);
63}
64
65void clicky_on(void) {
66 audio_config.clicky_enable = 1;
67 eeconfig_update_audio(audio_config.raw);
68}
69
70void clicky_off(void) {
71 audio_config.clicky_enable = 0;
72 eeconfig_update_audio(audio_config.raw);
73}
74
75bool is_clicky_on(void) {
76 return (audio_config.clicky_enable != 0);
77}
78
44bool process_clicky(uint16_t keycode, keyrecord_t *record) { 79bool process_clicky(uint16_t keycode, keyrecord_t *record) {
45 if (keycode == CLICKY_TOGGLE && record->event.pressed) { clicky_enable = !clicky_enable; } 80 if (keycode == CLICKY_TOGGLE && record->event.pressed) { clicky_toggle(); }
46 81
47 if (keycode == CLICKY_RESET && record->event.pressed) { clicky_freq = AUDIO_CLICKY_FREQ_DEFAULT; } 82 if (keycode == CLICKY_ENABLE && record->event.pressed) { clicky_on(); }
83 if (keycode == CLICKY_DISABLE && record->event.pressed) { clicky_off(); }
48 84
49 if (keycode == CLICKY_UP && record->event.pressed) { 85 if (keycode == CLICKY_RESET && record->event.pressed) { clicky_freq_reset(); }
50 float new_freq = clicky_freq * AUDIO_CLICKY_FREQ_FACTOR; 86
51 if (new_freq < AUDIO_CLICKY_FREQ_MAX) { 87 if (keycode == CLICKY_UP && record->event.pressed) { clicky_freq_up(); }
52 clicky_freq = new_freq; 88 if (keycode == CLICKY_DOWN && record->event.pressed) { clicky_freq_down(); }
53 }
54 }
55 if (keycode == CLICKY_DOWN && record->event.pressed) {
56 float new_freq = clicky_freq / AUDIO_CLICKY_FREQ_FACTOR;
57 if (new_freq > AUDIO_CLICKY_FREQ_MIN) {
58 clicky_freq = new_freq;
59 }
60 }
61 89
62 90
63 if ( clicky_enable ) { 91 if ( audio_config.clicky_enable ) {
64 if (record->event.pressed) { 92 if (record->event.pressed) {
65 clicky_play();; 93 clicky_play();;
66 } 94 }
diff --git a/quantum/process_keycode/process_clicky.h b/quantum/process_keycode/process_clicky.h
index e274af56f..f746edb95 100644
--- a/quantum/process_keycode/process_clicky.h
+++ b/quantum/process_keycode/process_clicky.h
@@ -4,4 +4,14 @@
4void clicky_play(void); 4void clicky_play(void);
5bool process_clicky(uint16_t keycode, keyrecord_t *record); 5bool process_clicky(uint16_t keycode, keyrecord_t *record);
6 6
7void clicky_freq_up(void);
8void clicky_freq_down(void);
9void clicky_freq_reset(void);
10
11void clicky_toggle(void);
12void clicky_on(void);
13void clicky_off(void);
14
15bool is_clicky_on(void);
16
7#endif 17#endif
diff --git a/quantum/process_keycode/process_leader.c b/quantum/process_keycode/process_leader.c
index c87ef115a..897e9eabf 100644
--- a/quantum/process_keycode/process_leader.c
+++ b/quantum/process_keycode/process_leader.c
@@ -14,7 +14,7 @@
14 * along with this program. If not, see <http://www.gnu.org/licenses/>. 14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */ 15 */
16 16
17#ifndef DISABLE_LEADER 17#ifdef LEADER_ENABLE
18 18
19#include "process_leader.h" 19#include "process_leader.h"
20 20
@@ -35,25 +35,40 @@ uint16_t leader_time = 0;
35uint16_t leader_sequence[5] = {0, 0, 0, 0, 0}; 35uint16_t leader_sequence[5] = {0, 0, 0, 0, 0};
36uint8_t leader_sequence_size = 0; 36uint8_t leader_sequence_size = 0;
37 37
38void qk_leader_start(void) {
39 if (leading) { return; }
40 leader_start();
41 leading = true;
42 leader_time = timer_read();
43 leader_sequence_size = 0;
44 leader_sequence[0] = 0;
45 leader_sequence[1] = 0;
46 leader_sequence[2] = 0;
47 leader_sequence[3] = 0;
48 leader_sequence[4] = 0;
49}
50
38bool process_leader(uint16_t keycode, keyrecord_t *record) { 51bool process_leader(uint16_t keycode, keyrecord_t *record) {
39 // Leader key set-up 52 // Leader key set-up
40 if (record->event.pressed) { 53 if (record->event.pressed) {
41 if (!leading && keycode == KC_LEAD) { 54 if (leading) {
42 leader_start(); 55 if (timer_elapsed(leader_time) < LEADER_TIMEOUT) {
43 leading = true; 56#ifndef LEADER_KEY_STRICT_KEY_PROCESSING
44 leader_time = timer_read(); 57 if ((keycode >= QK_MOD_TAP && keycode <= QK_MOD_TAP_MAX) || (keycode >= QK_LAYER_TAP && keycode <= QK_LAYER_TAP_MAX)) {
45 leader_sequence_size = 0; 58 keycode = keycode & 0xFF;
46 leader_sequence[0] = 0; 59 }
47 leader_sequence[1] = 0; 60#endif // LEADER_KEY_STRICT_KEY_PROCESSING
48 leader_sequence[2] = 0; 61 leader_sequence[leader_sequence_size] = keycode;
49 leader_sequence[3] = 0; 62 leader_sequence_size++;
50 leader_sequence[4] = 0; 63#ifdef LEADER_PER_KEY_TIMING
51 return false; 64 leader_time = timer_read();
52 } 65#endif
53 if (leading && timer_elapsed(leader_time) < LEADER_TIMEOUT) { 66 return false;
54 leader_sequence[leader_sequence_size] = keycode; 67 }
55 leader_sequence_size++; 68 } else {
56 return false; 69 if (keycode == KC_LEAD) {
70 qk_leader_start();
71 }
57 } 72 }
58 } 73 }
59 return true; 74 return true;
diff --git a/quantum/process_keycode/process_leader.h b/quantum/process_keycode/process_leader.h
index 59c3eed1b..15bccc3f6 100644
--- a/quantum/process_keycode/process_leader.h
+++ b/quantum/process_keycode/process_leader.h
@@ -24,7 +24,7 @@ bool process_leader(uint16_t keycode, keyrecord_t *record);
24 24
25void leader_start(void); 25void leader_start(void);
26void leader_end(void); 26void leader_end(void);
27 27void qk_leader_start(void);
28 28
29#define SEQ_ONE_KEY(key) if (leader_sequence[0] == (key) && leader_sequence[1] == 0 && leader_sequence[2] == 0 && leader_sequence[3] == 0 && leader_sequence[4] == 0) 29#define SEQ_ONE_KEY(key) if (leader_sequence[0] == (key) && leader_sequence[1] == 0 && leader_sequence[2] == 0 && leader_sequence[3] == 0 && leader_sequence[4] == 0)
30#define SEQ_TWO_KEYS(key1, key2) if (leader_sequence[0] == (key1) && leader_sequence[1] == (key2) && leader_sequence[2] == 0 && leader_sequence[3] == 0 && leader_sequence[4] == 0) 30#define SEQ_TWO_KEYS(key1, key2) if (leader_sequence[0] == (key1) && leader_sequence[1] == (key2) && leader_sequence[2] == 0 && leader_sequence[3] == 0 && leader_sequence[4] == 0)
diff --git a/quantum/process_keycode/process_tap_dance.c b/quantum/process_keycode/process_tap_dance.c
index 833780691..16d33ddde 100644
--- a/quantum/process_keycode/process_tap_dance.c
+++ b/quantum/process_keycode/process_tap_dance.c
@@ -16,6 +16,10 @@
16#include "quantum.h" 16#include "quantum.h"
17#include "action_tapping.h" 17#include "action_tapping.h"
18 18
19#ifndef TAPPING_TERM
20#define TAPPING_TERM 200
21#endif
22
19#ifndef NO_ACTION_ONESHOT 23#ifndef NO_ACTION_ONESHOT
20uint8_t get_oneshot_mods(void); 24uint8_t get_oneshot_mods(void);
21#endif 25#endif
@@ -127,6 +131,7 @@ void preprocess_tap_dance(uint16_t keycode, keyrecord_t *record) {
127 if (keycode == action->state.keycode && keycode == last_td) 131 if (keycode == action->state.keycode && keycode == last_td)
128 continue; 132 continue;
129 action->state.interrupted = true; 133 action->state.interrupted = true;
134 action->state.interrupting_keycode = keycode;
130 process_tap_dance_action_on_dance_finished (action); 135 process_tap_dance_action_on_dance_finished (action);
131 reset_tap_dance (&action->state); 136 reset_tap_dance (&action->state);
132 } 137 }
@@ -205,5 +210,6 @@ void reset_tap_dance (qk_tap_dance_state_t *state) {
205 state->count = 0; 210 state->count = 0;
206 state->interrupted = false; 211 state->interrupted = false;
207 state->finished = false; 212 state->finished = false;
213 state->interrupting_keycode = 0;
208 last_td = 0; 214 last_td = 0;
209} 215}
diff --git a/quantum/process_keycode/process_tap_dance.h b/quantum/process_keycode/process_tap_dance.h
index 8b0a47c49..ca12f4746 100644
--- a/quantum/process_keycode/process_tap_dance.h
+++ b/quantum/process_keycode/process_tap_dance.h
@@ -27,6 +27,7 @@ typedef struct
27 uint8_t oneshot_mods; 27 uint8_t oneshot_mods;
28 uint8_t weak_mods; 28 uint8_t weak_mods;
29 uint16_t keycode; 29 uint16_t keycode;
30 uint16_t interrupting_keycode;
30 uint16_t timer; 31 uint16_t timer;
31 bool interrupted; 32 bool interrupted;
32 bool pressed; 33 bool pressed;
diff --git a/quantum/process_keycode/process_ucis.c b/quantum/process_keycode/process_ucis.c
index 86c0937f5..5de2e41fc 100644
--- a/quantum/process_keycode/process_ucis.c
+++ b/quantum/process_keycode/process_ucis.c
@@ -32,6 +32,10 @@ void qk_ucis_start_user(void) {
32 unicode_input_finish(); 32 unicode_input_finish();
33} 33}
34 34
35__attribute__((weak))
36void qk_ucis_success(uint8_t symbol_index) {
37}
38
35static bool is_uni_seq(char *seq) { 39static bool is_uni_seq(char *seq) {
36 uint8_t i; 40 uint8_t i;
37 41
@@ -142,6 +146,10 @@ bool process_ucis (uint16_t keycode, keyrecord_t *record) {
142 } 146 }
143 unicode_input_finish(); 147 unicode_input_finish();
144 148
149 if (symbol_found) {
150 qk_ucis_success(i);
151 }
152
145 qk_ucis_state.in_progress = false; 153 qk_ucis_state.in_progress = false;
146 return false; 154 return false;
147 } 155 }
diff --git a/quantum/process_keycode/process_ucis.h b/quantum/process_keycode/process_ucis.h
index 3f736a709..b114d839a 100644
--- a/quantum/process_keycode/process_ucis.h
+++ b/quantum/process_keycode/process_ucis.h
@@ -14,8 +14,7 @@
14 * along with this program. If not, see <http://www.gnu.org/licenses/>. 14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */ 15 */
16 16
17#ifndef PROCESS_UCIS_H 17#pragma once
18#define PROCESS_UCIS_H
19 18
20#include "quantum.h" 19#include "quantum.h"
21#include "process_unicode_common.h" 20#include "process_unicode_common.h"
@@ -45,7 +44,6 @@ extern const qk_ucis_symbol_t ucis_symbol_table[];
45void qk_ucis_start(void); 44void qk_ucis_start(void);
46void qk_ucis_start_user(void); 45void qk_ucis_start_user(void);
47void qk_ucis_symbol_fallback (void); 46void qk_ucis_symbol_fallback (void);
47void qk_ucis_success(uint8_t symbol_index);
48void register_ucis(const char *hex); 48void register_ucis(const char *hex);
49bool process_ucis (uint16_t keycode, keyrecord_t *record); 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 fd008eca1..19beb8452 100644
--- a/quantum/process_keycode/process_unicode.c
+++ b/quantum/process_keycode/process_unicode.c
@@ -17,14 +17,8 @@
17#include "action_util.h" 17#include "action_util.h"
18#include "eeprom.h" 18#include "eeprom.h"
19 19
20static uint8_t first_flag = 0;
21
22bool process_unicode(uint16_t keycode, keyrecord_t *record) { 20bool process_unicode(uint16_t keycode, keyrecord_t *record) {
23 if (keycode > QK_UNICODE && record->event.pressed) { 21 if (keycode > QK_UNICODE && record->event.pressed) {
24 if (first_flag == 0) {
25 set_unicode_input_mode(eeprom_read_byte(EECONFIG_UNICODEMODE));
26 first_flag = 1;
27 }
28 uint16_t unicode = keycode & 0x7FFF; 22 uint16_t unicode = keycode & 0x7FFF;
29 unicode_input_start(); 23 unicode_input_start();
30 register_hex(unicode); 24 register_hex(unicode);
@@ -32,4 +26,3 @@ bool process_unicode(uint16_t keycode, keyrecord_t *record) {
32 } 26 }
33 return true; 27 return true;
34} 28}
35
diff --git a/quantum/process_keycode/process_unicode.h b/quantum/process_keycode/process_unicode.h
index c525b74f0..0913e9910 100644
--- a/quantum/process_keycode/process_unicode.h
+++ b/quantum/process_keycode/process_unicode.h
@@ -13,12 +13,9 @@
13 * You should have received a copy of the GNU General Public License 13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>. 14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */ 15 */
16#ifndef PROCESS_UNICODE_H 16#pragma once
17#define PROCESS_UNICODE_H
18 17
19#include "quantum.h" 18#include "quantum.h"
20#include "process_unicode_common.h" 19#include "process_unicode_common.h"
21 20
22bool process_unicode(uint16_t keycode, keyrecord_t *record); 21bool process_unicode(uint16_t keycode, keyrecord_t *record);
23
24#endif
diff --git a/quantum/process_keycode/process_unicode_common.c b/quantum/process_keycode/process_unicode_common.c
index 7f34ad57c..3286f45b5 100644
--- a/quantum/process_keycode/process_unicode_common.c
+++ b/quantum/process_keycode/process_unicode_common.c
@@ -16,94 +16,115 @@
16 16
17#include "process_unicode_common.h" 17#include "process_unicode_common.h"
18#include "eeprom.h" 18#include "eeprom.h"
19#include <ctype.h>
20#include <string.h>
19 21
20static uint8_t input_mode; 22unicode_config_t unicode_config;
21uint8_t mods; 23#if UNICODE_SELECTED_MODES != -1
24static uint8_t selected[] = { UNICODE_SELECTED_MODES };
25static uint8_t selected_count = sizeof selected / sizeof *selected;
26static uint8_t selected_index;
27#endif
22 28
23void set_unicode_input_mode(uint8_t os_target) 29void unicode_input_mode_init(void) {
24{ 30 unicode_config.raw = eeprom_read_byte(EECONFIG_UNICODEMODE);
25 input_mode = os_target; 31#if UNICODE_SELECTED_MODES != -1
26 eeprom_update_byte(EECONFIG_UNICODEMODE, os_target); 32 #if UNICODE_CYCLE_PERSIST
33 // Find input_mode in selected modes
34 uint8_t i;
35 for (i = 0; i < selected_count; i++) {
36 if (selected[i] == unicode_config.input_mode) {
37 selected_index = i;
38 break;
39 }
40 }
41 if (i == selected_count) {
42 // Not found: input_mode isn't selected, change to one that is
43 unicode_config.input_mode = selected[selected_index = 0];
44 }
45 #else
46 // Always change to the first selected input mode
47 unicode_config.input_mode = selected[selected_index = 0];
48 #endif
49#endif
50 dprintf("Unicode input mode init to: %u\n", unicode_config.input_mode);
27} 51}
28 52
29uint8_t get_unicode_input_mode(void) { 53uint8_t get_unicode_input_mode(void) {
30 return input_mode; 54 return unicode_config.input_mode;
31} 55}
32 56
57void set_unicode_input_mode(uint8_t mode) {
58 unicode_config.input_mode = mode;
59 persist_unicode_input_mode();
60 dprintf("Unicode input mode set to: %u\n", unicode_config.input_mode);
61}
62
63void cycle_unicode_input_mode(uint8_t offset) {
64#if UNICODE_SELECTED_MODES != -1
65 selected_index = (selected_index + offset) % selected_count;
66 unicode_config.input_mode = selected[selected_index];
67 #if UNICODE_CYCLE_PERSIST
68 persist_unicode_input_mode();
69 #endif
70 dprintf("Unicode input mode cycle to: %u\n", unicode_config.input_mode);
71#endif
72}
73
74void persist_unicode_input_mode(void) {
75 eeprom_update_byte(EECONFIG_UNICODEMODE, unicode_config.input_mode);
76}
77
78static uint8_t saved_mods;
79
33__attribute__((weak)) 80__attribute__((weak))
34void unicode_input_start (void) { 81void unicode_input_start(void) {
35 // save current mods 82 saved_mods = get_mods(); // Save current mods
36 mods = keyboard_report->mods; 83 clear_mods(); // Unregister mods to start from a clean state
37 84
38 // unregister all mods to start from clean state 85 switch (unicode_config.input_mode) {
39 if (mods & MOD_BIT(KC_LSFT)) unregister_code(KC_LSFT);
40 if (mods & MOD_BIT(KC_RSFT)) unregister_code(KC_RSFT);
41 if (mods & MOD_BIT(KC_LCTL)) unregister_code(KC_LCTL);
42 if (mods & MOD_BIT(KC_RCTL)) unregister_code(KC_RCTL);
43 if (mods & MOD_BIT(KC_LALT)) unregister_code(KC_LALT);
44 if (mods & MOD_BIT(KC_RALT)) unregister_code(KC_RALT);
45 if (mods & MOD_BIT(KC_LGUI)) unregister_code(KC_LGUI);
46 if (mods & MOD_BIT(KC_RGUI)) unregister_code(KC_RGUI);
47
48 switch(input_mode) {
49 case UC_OSX: 86 case UC_OSX:
50 register_code(KC_LALT); 87 register_code(UNICODE_OSX_KEY);
51 break;
52 case UC_OSX_RALT:
53 register_code(KC_RALT);
54 break; 88 break;
55 case UC_LNX: 89 case UC_LNX:
56 register_code(KC_LCTL); 90 register_code(KC_LCTL);
57 register_code(KC_LSFT); 91 register_code(KC_LSFT);
58 register_code(KC_U); 92 tap_code(KC_U); // TODO: Replace with tap_code16(LCTL(LSFT(KC_U))); and test
59 unregister_code(KC_U);
60 unregister_code(KC_LSFT); 93 unregister_code(KC_LSFT);
61 unregister_code(KC_LCTL); 94 unregister_code(KC_LCTL);
62 break; 95 break;
63 case UC_WIN: 96 case UC_WIN:
64 register_code(KC_LALT); 97 register_code(KC_LALT);
65 register_code(KC_PPLS); 98 tap_code(KC_PPLS);
66 unregister_code(KC_PPLS);
67 break; 99 break;
68 case UC_WINC: 100 case UC_WINC:
69 register_code(KC_RALT); 101 tap_code(UNICODE_WINC_KEY);
70 unregister_code(KC_RALT); 102 tap_code(KC_U);
71 register_code(KC_U); 103 break;
72 unregister_code(KC_U);
73 } 104 }
105
74 wait_ms(UNICODE_TYPE_DELAY); 106 wait_ms(UNICODE_TYPE_DELAY);
75} 107}
76 108
77__attribute__((weak)) 109__attribute__((weak))
78void unicode_input_finish (void) { 110void unicode_input_finish(void) {
79 switch(input_mode) { 111 switch (unicode_config.input_mode) {
80 case UC_OSX: 112 case UC_OSX:
81 case UC_WIN: 113 unregister_code(UNICODE_OSX_KEY);
82 unregister_code(KC_LALT); 114 break;
83 break; 115 case UC_LNX:
84 case UC_OSX_RALT: 116 tap_code(KC_SPC);
85 unregister_code(KC_RALT); 117 break;
86 break; 118 case UC_WIN:
87 case UC_LNX: 119 unregister_code(KC_LALT);
88 register_code(KC_SPC); 120 break;
89 unregister_code(KC_SPC);
90 break;
91 } 121 }
92 122
93 // reregister previously set mods 123 set_mods(saved_mods); // Reregister previously set mods
94 if (mods & MOD_BIT(KC_LSFT)) register_code(KC_LSFT);
95 if (mods & MOD_BIT(KC_RSFT)) register_code(KC_RSFT);
96 if (mods & MOD_BIT(KC_LCTL)) register_code(KC_LCTL);
97 if (mods & MOD_BIT(KC_RCTL)) register_code(KC_RCTL);
98 if (mods & MOD_BIT(KC_LALT)) register_code(KC_LALT);
99 if (mods & MOD_BIT(KC_RALT)) register_code(KC_RALT);
100 if (mods & MOD_BIT(KC_LGUI)) register_code(KC_LGUI);
101 if (mods & MOD_BIT(KC_RGUI)) register_code(KC_RGUI);
102} 124}
103 125
104__attribute__((weak)) 126__attribute__((weak))
105uint16_t hex_to_keycode(uint8_t hex) 127uint16_t hex_to_keycode(uint8_t hex) {
106{
107 if (hex == 0x0) { 128 if (hex == 0x0) {
108 return KC_0; 129 return KC_0;
109 } else if (hex < 0xA) { 130 } else if (hex < 0xA) {
@@ -116,7 +137,89 @@ uint16_t hex_to_keycode(uint8_t hex)
116void register_hex(uint16_t hex) { 137void register_hex(uint16_t hex) {
117 for(int i = 3; i >= 0; i--) { 138 for(int i = 3; i >= 0; i--) {
118 uint8_t digit = ((hex >> (i*4)) & 0xF); 139 uint8_t digit = ((hex >> (i*4)) & 0xF);
119 register_code(hex_to_keycode(digit)); 140 tap_code(hex_to_keycode(digit));
120 unregister_code(hex_to_keycode(digit)); 141 }
142}
143
144void send_unicode_hex_string(const char *str) {
145 if (!str) { return; }
146
147 while (*str) {
148 // Find the next code point (token) in the string
149 for (; *str == ' '; str++);
150 size_t n = strcspn(str, " "); // Length of the current token
151 char code_point[n+1];
152 strncpy(code_point, str, n);
153 code_point[n] = '\0'; // Make sure it's null-terminated
154
155 // Normalize the code point: make all hex digits lowercase
156 for (char *p = code_point; *p; p++) {
157 *p = tolower((unsigned char)*p);
158 }
159
160 // Send the code point as a Unicode input string
161 unicode_input_start();
162 send_string(code_point);
163 unicode_input_finish();
164
165 str += n; // Move to the first ' ' (or '\0') after the current token
166 }
167}
168
169bool process_unicode_common(uint16_t keycode, keyrecord_t *record) {
170 if (record->event.pressed) {
171 switch (keycode) {
172 case UNICODE_MODE_FORWARD:
173 cycle_unicode_input_mode(+1);
174 break;
175 case UNICODE_MODE_REVERSE:
176 cycle_unicode_input_mode(-1);
177 break;
178
179 case UNICODE_MODE_OSX:
180 set_unicode_input_mode(UC_OSX);
181#if defined(AUDIO_ENABLE) && defined(UNICODE_SONG_OSX)
182 static float song_osx[][2] = UNICODE_SONG_OSX;
183 PLAY_SONG(song_osx);
184#endif
185 break;
186 case UNICODE_MODE_LNX:
187 set_unicode_input_mode(UC_LNX);
188#if defined(AUDIO_ENABLE) && defined(UNICODE_SONG_LNX)
189 static float song_lnx[][2] = UNICODE_SONG_LNX;
190 PLAY_SONG(song_lnx);
191#endif
192 break;
193 case UNICODE_MODE_WIN:
194 set_unicode_input_mode(UC_WIN);
195#if defined(AUDIO_ENABLE) && defined(UNICODE_SONG_WIN)
196 static float song_win[][2] = UNICODE_SONG_WIN;
197 PLAY_SONG(song_win);
198#endif
199 break;
200 case UNICODE_MODE_BSD:
201 set_unicode_input_mode(UC_BSD);
202#if defined(AUDIO_ENABLE) && defined(UNICODE_SONG_BSD)
203 static float song_bsd[][2] = UNICODE_SONG_BSD;
204 PLAY_SONG(song_bsd);
205#endif
206 break;
207 case UNICODE_MODE_WINC:
208 set_unicode_input_mode(UC_WINC);
209#if defined(AUDIO_ENABLE) && defined(UNICODE_SONG_WINC)
210 static float song_winc[][2] = UNICODE_SONG_WINC;
211 PLAY_SONG(song_winc);
212#endif
213 break;
214 }
121 } 215 }
216#if defined(UNICODE_ENABLE)
217 return process_unicode(keycode, record);
218#elif defined(UNICODEMAP_ENABLE)
219 return process_unicode_map(keycode, record);
220#elif defined(UCIS_ENABLE)
221 return process_ucis(keycode, record);
222#else
223 return true;
224#endif
122} 225}
diff --git a/quantum/process_keycode/process_unicode_common.h b/quantum/process_keycode/process_unicode_common.h
index 4d2b04fb3..e608ab76b 100644
--- a/quantum/process_keycode/process_unicode_common.h
+++ b/quantum/process_keycode/process_unicode_common.h
@@ -14,33 +14,71 @@
14 * along with this program. If not, see <http://www.gnu.org/licenses/>. 14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */ 15 */
16 16
17#ifndef PROCESS_UNICODE_COMMON_H 17#pragma once
18#define PROCESS_UNICODE_COMMON_H
19 18
20#include "quantum.h" 19#include "quantum.h"
21 20
22#ifndef UNICODE_TYPE_DELAY 21#if defined(UNICODE_ENABLE) + defined(UNICODEMAP_ENABLE) + defined(UCIS_ENABLE) > 1
23#define UNICODE_TYPE_DELAY 10 22 #error "Cannot enable more than one Unicode method (UNICODE, UNICODEMAP, UCIS) at the same time"
23#endif
24
25// Keycodes used for starting Unicode input on different platforms
26#ifndef UNICODE_OSX_KEY
27 #define UNICODE_OSX_KEY KC_LALT
28#endif
29#ifndef UNICODE_WINC_KEY
30 #define UNICODE_WINC_KEY KC_RALT
24#endif 31#endif
25 32
26__attribute__ ((unused)) 33// Comma-delimited, ordered list of input modes selected for use (e.g. in cycle)
27static uint8_t input_mode; 34// Example: #define UNICODE_SELECTED_MODES UC_WINC, UC_LNX
35#ifndef UNICODE_SELECTED_MODES
36 #define UNICODE_SELECTED_MODES -1
37#endif
38
39// Whether input mode changes in cycle should be written to EEPROM
40#ifndef UNICODE_CYCLE_PERSIST
41 #define UNICODE_CYCLE_PERSIST true
42#endif
28 43
29void set_unicode_input_mode(uint8_t os_target); 44// Delay between starting Unicode input and sending a sequence, in ms
45#ifndef UNICODE_TYPE_DELAY
46 #define UNICODE_TYPE_DELAY 10
47#endif
48
49enum unicode_input_modes {
50 UC_OSX, // Mac OS X using Unicode Hex Input
51 UC_LNX, // Linux using IBus
52 UC_WIN, // Windows using EnableHexNumpad
53 UC_BSD, // BSD (not implemented)
54 UC_WINC, // Windows using WinCompose (https://github.com/samhocevar/wincompose)
55 UC__COUNT // Number of available input modes (always leave at the end)
56};
57
58typedef union {
59 uint32_t raw;
60 struct {
61 uint8_t input_mode : 8;
62 };
63} unicode_config_t;
64
65extern unicode_config_t unicode_config;
66
67void unicode_input_mode_init(void);
30uint8_t get_unicode_input_mode(void); 68uint8_t get_unicode_input_mode(void);
69void set_unicode_input_mode(uint8_t mode);
70void cycle_unicode_input_mode(uint8_t offset);
71void persist_unicode_input_mode(void);
72
31void unicode_input_start(void); 73void unicode_input_start(void);
32void unicode_input_finish(void); 74void unicode_input_finish(void);
75
33void register_hex(uint16_t hex); 76void register_hex(uint16_t hex);
77void send_unicode_hex_string(const char *str);
34 78
35#define UC_OSX 0 // Mac OS X 79bool process_unicode_common(uint16_t keycode, keyrecord_t *record);
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#define UC_OSX_RALT 5 // Mac OS X using Right Alt key for Unicode Compose
41 80
42#define UC_BSPC UC(0x0008) 81#define UC_BSPC UC(0x0008)
43
44#define UC_SPC UC(0x0020) 82#define UC_SPC UC(0x0020)
45 83
46#define UC_EXLM UC(0x0021) 84#define UC_EXLM UC(0x0021)
@@ -145,5 +183,3 @@ void register_hex(uint16_t hex);
145#define UC_RCBR UC(0x007D) 183#define UC_RCBR UC(0x007D)
146#define UC_TILD UC(0x007E) 184#define UC_TILD UC(0x007E)
147#define UC_DEL UC(0x007F) 185#define UC_DEL UC(0x007F)
148
149#endif
diff --git a/quantum/process_keycode/process_unicodemap.c b/quantum/process_keycode/process_unicodemap.c
index 47c27b911..75f35112b 100644
--- a/quantum/process_keycode/process_unicodemap.c
+++ b/quantum/process_keycode/process_unicodemap.c
@@ -50,7 +50,7 @@ bool process_unicode_map(uint16_t keycode, keyrecord_t *record) {
50 const uint32_t* map = unicode_map; 50 const uint32_t* map = unicode_map;
51 uint16_t index = keycode - QK_UNICODE_MAP; 51 uint16_t index = keycode - QK_UNICODE_MAP;
52 uint32_t code = pgm_read_dword(&map[index]); 52 uint32_t code = pgm_read_dword(&map[index]);
53 if (code > 0xFFFF && code <= 0x10ffff && (input_mode == UC_OSX || input_mode == UC_OSX_RALT)) { 53 if (code > 0xFFFF && code <= 0x10ffff && input_mode == UC_OSX) {
54 // Convert to UTF-16 surrogate pair 54 // Convert to UTF-16 surrogate pair
55 code -= 0x10000; 55 code -= 0x10000;
56 uint32_t lo = code & 0x3ff; 56 uint32_t lo = code & 0x3ff;
@@ -59,7 +59,7 @@ bool process_unicode_map(uint16_t keycode, keyrecord_t *record) {
59 register_hex32(hi + 0xd800); 59 register_hex32(hi + 0xd800);
60 register_hex32(lo + 0xdc00); 60 register_hex32(lo + 0xdc00);
61 unicode_input_finish(); 61 unicode_input_finish();
62 } else if ((code > 0x10ffff && (input_mode == UC_OSX || input_mode == UC_OSX_RALT)) || (code > 0xFFFFF && input_mode == UC_LNX)) { 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 63 // when character is out of range supported by the OS
64 unicode_map_input_error(); 64 unicode_map_input_error();
65 } else { 65 } else {
diff --git a/quantum/process_keycode/process_unicodemap.h b/quantum/process_keycode/process_unicodemap.h
index 929c88c0b..f6d64bb86 100644
--- a/quantum/process_keycode/process_unicodemap.h
+++ b/quantum/process_keycode/process_unicodemap.h
@@ -14,12 +14,10 @@
14 * along with this program. If not, see <http://www.gnu.org/licenses/>. 14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */ 15 */
16 16
17#ifndef PROCESS_UNICODEMAP_H 17#pragma once
18#define PROCESS_UNICODEMAP_H
19 18
20#include "quantum.h" 19#include "quantum.h"
21#include "process_unicode_common.h" 20#include "process_unicode_common.h"
22 21
23void unicode_map_input_error(void); 22void unicode_map_input_error(void);
24bool process_unicode_map(uint16_t keycode, keyrecord_t *record); 23bool process_unicode_map(uint16_t keycode, keyrecord_t *record);
25#endif
diff --git a/quantum/quantum.c b/quantum/quantum.c
index ab47fa48f..85db100ab 100644
--- a/quantum/quantum.c
+++ b/quantum/quantum.c
@@ -42,6 +42,11 @@ extern backlight_config_t backlight_config;
42#include "process_midi.h" 42#include "process_midi.h"
43#endif 43#endif
44 44
45
46#ifdef ENCODER_ENABLE
47#include "encoder.h"
48#endif
49
45#ifdef AUDIO_ENABLE 50#ifdef AUDIO_ENABLE
46 #ifndef GOODBYE_SONG 51 #ifndef GOODBYE_SONG
47 #define GOODBYE_SONG SONG(GOODBYE_SOUND) 52 #define GOODBYE_SONG SONG(GOODBYE_SOUND)
@@ -127,6 +132,14 @@ void unregister_code16 (uint16_t code) {
127 } 132 }
128} 133}
129 134
135void tap_code16(uint16_t code) {
136 register_code16(code);
137 #if TAP_CODE_DELAY > 0
138 wait_ms(TAP_CODE_DELAY);
139 #endif
140 unregister_code16(code);
141}
142
130__attribute__ ((weak)) 143__attribute__ ((weak))
131bool process_action_kb(keyrecord_t *record) { 144bool process_action_kb(keyrecord_t *record) {
132 return true; 145 return true;
@@ -196,7 +209,7 @@ bool process_record_quantum(keyrecord_t *record) {
196 keypos_t key = record->event.key; 209 keypos_t key = record->event.key;
197 uint16_t keycode; 210 uint16_t keycode;
198 211
199 #if !defined(NO_ACTION_LAYER) && defined(PREVENT_STUCK_MODIFIERS) 212 #if !defined(NO_ACTION_LAYER) && !defined(STRICT_LAYER_RELEASE)
200 /* TODO: Use store_or_get_action() or a similar function. */ 213 /* TODO: Use store_or_get_action() or a similar function. */
201 if (!disable_action_cache) { 214 if (!disable_action_cache) {
202 uint8_t layer; 215 uint8_t layer;
@@ -230,7 +243,7 @@ bool process_record_quantum(keyrecord_t *record) {
230 process_key_lock(&keycode, record) && 243 process_key_lock(&keycode, record) &&
231 #endif 244 #endif
232 #if defined(AUDIO_ENABLE) && defined(AUDIO_CLICKY) 245 #if defined(AUDIO_ENABLE) && defined(AUDIO_CLICKY)
233 process_clicky(keycode, record) && 246 process_clicky(keycode, record) &&
234 #endif //AUDIO_CLICKY 247 #endif //AUDIO_CLICKY
235 process_record_kb(keycode, record) && 248 process_record_kb(keycode, record) &&
236 #if defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_KEYPRESSES) 249 #if defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_KEYPRESSES)
@@ -245,36 +258,27 @@ bool process_record_quantum(keyrecord_t *record) {
245 #ifdef STENO_ENABLE 258 #ifdef STENO_ENABLE
246 process_steno(keycode, record) && 259 process_steno(keycode, record) &&
247 #endif 260 #endif
248 #if ( defined(AUDIO_ENABLE) || (defined(MIDI_ENABLE) && defined(MIDI_BASIC))) && !defined(NO_MUSIC_MODE) 261 #if (defined(AUDIO_ENABLE) || (defined(MIDI_ENABLE) && defined(MIDI_BASIC))) && !defined(NO_MUSIC_MODE)
249 process_music(keycode, record) && 262 process_music(keycode, record) &&
250 #endif 263 #endif
251 #ifdef TAP_DANCE_ENABLE 264 #ifdef TAP_DANCE_ENABLE
252 process_tap_dance(keycode, record) && 265 process_tap_dance(keycode, record) &&
253 #endif 266 #endif
254 #ifndef DISABLE_LEADER 267 #if defined(UNICODE_ENABLE) || defined(UNICODEMAP_ENABLE) || defined(UCIS_ENABLE)
255 process_leader(keycode, record) && 268 process_unicode_common(keycode, record) &&
256 #endif 269 #endif
257 #ifndef DISABLE_CHORDING 270 #ifdef LEADER_ENABLE
258 process_chording(keycode, record) && 271 process_leader(keycode, record) &&
259 #endif 272 #endif
260 #ifdef COMBO_ENABLE 273 #ifdef COMBO_ENABLE
261 process_combo(keycode, record) && 274 process_combo(keycode, record) &&
262 #endif 275 #endif
263 #ifdef UNICODE_ENABLE
264 process_unicode(keycode, record) &&
265 #endif
266 #ifdef UCIS_ENABLE
267 process_ucis(keycode, record) &&
268 #endif
269 #ifdef PRINTING_ENABLE 276 #ifdef PRINTING_ENABLE
270 process_printer(keycode, record) && 277 process_printer(keycode, record) &&
271 #endif 278 #endif
272 #ifdef AUTO_SHIFT_ENABLE 279 #ifdef AUTO_SHIFT_ENABLE
273 process_auto_shift(keycode, record) && 280 process_auto_shift(keycode, record) &&
274 #endif 281 #endif
275 #ifdef UNICODEMAP_ENABLE
276 process_unicode_map(keycode, record) &&
277 #endif
278 #ifdef TERMINAL_ENABLE 282 #ifdef TERMINAL_ENABLE
279 process_terminal(keycode, record) && 283 process_terminal(keycode, record) &&
280 #endif 284 #endif
@@ -296,6 +300,11 @@ bool process_record_quantum(keyrecord_t *record) {
296 print("DEBUG: enabled.\n"); 300 print("DEBUG: enabled.\n");
297 } 301 }
298 return false; 302 return false;
303 case EEPROM_RESET:
304 if (record->event.pressed) {
305 eeconfig_init();
306 }
307 return false;
299 #ifdef FAUXCLICKY_ENABLE 308 #ifdef FAUXCLICKY_ENABLE
300 case FC_TOG: 309 case FC_TOG:
301 if (record->event.pressed) { 310 if (record->event.pressed) {
@@ -445,75 +454,97 @@ bool process_record_quantum(keyrecord_t *record) {
445 return false; 454 return false;
446 case RGB_MODE_PLAIN: 455 case RGB_MODE_PLAIN:
447 if (record->event.pressed) { 456 if (record->event.pressed) {
448 rgblight_mode(1); 457 rgblight_mode(RGBLIGHT_MODE_STATIC_LIGHT);
449 #ifdef SPLIT_KEYBOARD 458 #ifdef SPLIT_KEYBOARD
450 RGB_DIRTY = true; 459 RGB_DIRTY = true;
451 #endif 460 #endif
452 } 461 }
453 return false; 462 return false;
454 case RGB_MODE_BREATHE: 463 case RGB_MODE_BREATHE:
464 #ifdef RGBLIGHT_EFFECT_BREATHING
455 if (record->event.pressed) { 465 if (record->event.pressed) {
456 if ((2 <= rgblight_get_mode()) && (rgblight_get_mode() < 5)) { 466 if ((RGBLIGHT_MODE_BREATHING <= rgblight_get_mode()) &&
467 (rgblight_get_mode() < RGBLIGHT_MODE_BREATHING_end)) {
457 rgblight_step(); 468 rgblight_step();
458 } else { 469 } else {
459 rgblight_mode(2); 470 rgblight_mode(RGBLIGHT_MODE_BREATHING);
460 } 471 }
461 } 472 }
473 #endif
462 return false; 474 return false;
463 case RGB_MODE_RAINBOW: 475 case RGB_MODE_RAINBOW:
476 #ifdef RGBLIGHT_EFFECT_RAINBOW_MOOD
464 if (record->event.pressed) { 477 if (record->event.pressed) {
465 if ((6 <= rgblight_get_mode()) && (rgblight_get_mode() < 8)) { 478 if ((RGBLIGHT_MODE_RAINBOW_MOOD <= rgblight_get_mode()) &&
479 (rgblight_get_mode() < RGBLIGHT_MODE_RAINBOW_MOOD_end)) {
466 rgblight_step(); 480 rgblight_step();
467 } else { 481 } else {
468 rgblight_mode(6); 482 rgblight_mode(RGBLIGHT_MODE_RAINBOW_MOOD);
469 } 483 }
470 } 484 }
485 #endif
471 return false; 486 return false;
472 case RGB_MODE_SWIRL: 487 case RGB_MODE_SWIRL:
488 #ifdef RGBLIGHT_EFFECT_RAINBOW_SWIRL
473 if (record->event.pressed) { 489 if (record->event.pressed) {
474 if ((9 <= rgblight_get_mode()) && (rgblight_get_mode() < 14)) { 490 if ((RGBLIGHT_MODE_RAINBOW_SWIRL <= rgblight_get_mode()) &&
491 (rgblight_get_mode() < RGBLIGHT_MODE_RAINBOW_SWIRL_end)) {
475 rgblight_step(); 492 rgblight_step();
476 } else { 493 } else {
477 rgblight_mode(9); 494 rgblight_mode(RGBLIGHT_MODE_RAINBOW_SWIRL);
478 } 495 }
479 } 496 }
497 #endif
480 return false; 498 return false;
481 case RGB_MODE_SNAKE: 499 case RGB_MODE_SNAKE:
500 #ifdef RGBLIGHT_EFFECT_SNAKE
482 if (record->event.pressed) { 501 if (record->event.pressed) {
483 if ((15 <= rgblight_get_mode()) && (rgblight_get_mode() < 20)) { 502 if ((RGBLIGHT_MODE_SNAKE <= rgblight_get_mode()) &&
503 (rgblight_get_mode() < RGBLIGHT_MODE_SNAKE_end)) {
484 rgblight_step(); 504 rgblight_step();
485 } else { 505 } else {
486 rgblight_mode(15); 506 rgblight_mode(RGBLIGHT_MODE_SNAKE);
487 } 507 }
488 } 508 }
509 #endif
489 return false; 510 return false;
490 case RGB_MODE_KNIGHT: 511 case RGB_MODE_KNIGHT:
512 #ifdef RGBLIGHT_EFFECT_KNIGHT
491 if (record->event.pressed) { 513 if (record->event.pressed) {
492 if ((21 <= rgblight_get_mode()) && (rgblight_get_mode() < 23)) { 514 if ((RGBLIGHT_MODE_KNIGHT <= rgblight_get_mode()) &&
515 (rgblight_get_mode() < RGBLIGHT_MODE_KNIGHT_end)) {
493 rgblight_step(); 516 rgblight_step();
494 } else { 517 } else {
495 rgblight_mode(21); 518 rgblight_mode(RGBLIGHT_MODE_KNIGHT);
496 } 519 }
497 } 520 }
521 #endif
498 return false; 522 return false;
499 case RGB_MODE_XMAS: 523 case RGB_MODE_XMAS:
524 #ifdef RGBLIGHT_EFFECT_CHRISTMAS
500 if (record->event.pressed) { 525 if (record->event.pressed) {
501 rgblight_mode(24); 526 rgblight_mode(RGBLIGHT_MODE_CHRISTMAS);
502 } 527 }
528 #endif
503 return false; 529 return false;
504 case RGB_MODE_GRADIENT: 530 case RGB_MODE_GRADIENT:
531 #ifdef RGBLIGHT_EFFECT_STATIC_GRADIENT
505 if (record->event.pressed) { 532 if (record->event.pressed) {
506 if ((25 <= rgblight_get_mode()) && (rgblight_get_mode() < 34)) { 533 if ((RGBLIGHT_MODE_STATIC_GRADIENT <= rgblight_get_mode()) &&
534 (rgblight_get_mode() < RGBLIGHT_MODE_STATIC_GRADIENT_end)) {
507 rgblight_step(); 535 rgblight_step();
508 } else { 536 } else {
509 rgblight_mode(25); 537 rgblight_mode(RGBLIGHT_MODE_STATIC_GRADIENT);
510 } 538 }
511 } 539 }
540 #endif
512 return false; 541 return false;
513 case RGB_MODE_RGBTEST: 542 case RGB_MODE_RGBTEST:
543 #ifdef RGBLIGHT_EFFECT_RGB_TEST
514 if (record->event.pressed) { 544 if (record->event.pressed) {
515 rgblight_mode(35); 545 rgblight_mode(RGBLIGHT_MODE_RGB_TEST);
516 } 546 }
547 #endif
517 return false; 548 return false;
518 #endif // defined(RGBLIGHT_ENABLE) || defined(RGB_MATRIX_ENABLE) 549 #endif // defined(RGBLIGHT_ENABLE) || defined(RGB_MATRIX_ENABLE)
519 #ifdef PROTOCOL_LUFA 550 #ifdef PROTOCOL_LUFA
@@ -607,6 +638,17 @@ bool process_record_quantum(keyrecord_t *record) {
607 PLAY_SONG(ag_norm_song); 638 PLAY_SONG(ag_norm_song);
608 #endif 639 #endif
609 break; 640 break;
641 case MAGIC_TOGGLE_ALT_GUI:
642 keymap_config.swap_lalt_lgui = !keymap_config.swap_lalt_lgui;
643 keymap_config.swap_ralt_rgui = !keymap_config.swap_ralt_rgui;
644 #ifdef AUDIO_ENABLE
645 if (keymap_config.swap_ralt_rgui) {
646 PLAY_SONG(ag_swap_song);
647 } else {
648 PLAY_SONG(ag_norm_song);
649 }
650 #endif
651 break;
610 case MAGIC_TOGGLE_NKRO: 652 case MAGIC_TOGGLE_NKRO:
611 keymap_config.nkro = !keymap_config.nkro; 653 keymap_config.nkro = !keymap_config.nkro;
612 break; 654 break;
@@ -914,7 +956,42 @@ void tap_random_base64(void) {
914 } 956 }
915} 957}
916 958
959__attribute__((weak))
960void bootmagic_lite(void) {
961 // The lite version of TMK's bootmagic based on Wilba.
962 // 100% less potential for accidentally making the
963 // keyboard do stupid things.
964
965 // We need multiple scans because debouncing can't be turned off.
966 matrix_scan();
967 #if defined(DEBOUNCING_DELAY) && DEBOUNCING_DELAY > 0
968 wait_ms(DEBOUNCING_DELAY * 2);
969 #elif defined(DEBOUNCE) && DEBOUNCE > 0
970 wait_ms(DEBOUNCE * 2);
971 #else
972 wait_ms(30);
973 #endif
974 matrix_scan();
975
976 // If the Esc and space bar are held down on power up,
977 // reset the EEPROM valid state and jump to bootloader.
978 // Assumes Esc is at [0,0].
979 // This isn't very generalized, but we need something that doesn't
980 // rely on user's keymaps in firmware or EEPROM.
981 if (matrix_get_row(BOOTMAGIC_LITE_ROW) & (1 << BOOTMAGIC_LITE_COLUMN)) {
982 eeconfig_disable();
983 // Jump to bootloader.
984 bootloader_jump();
985 }
986}
987
917void matrix_init_quantum() { 988void matrix_init_quantum() {
989 #ifdef BOOTMAGIC_LITE
990 bootmagic_lite();
991 #endif
992 if (!eeconfig_is_enabled()) {
993 eeconfig_init();
994 }
918 #ifdef BACKLIGHT_ENABLE 995 #ifdef BACKLIGHT_ENABLE
919 backlight_init_ports(); 996 backlight_init_ports();
920 #endif 997 #endif
@@ -924,6 +1001,12 @@ void matrix_init_quantum() {
924 #ifdef RGB_MATRIX_ENABLE 1001 #ifdef RGB_MATRIX_ENABLE
925 rgb_matrix_init(); 1002 rgb_matrix_init();
926 #endif 1003 #endif
1004 #ifdef ENCODER_ENABLE
1005 encoder_init();
1006 #endif
1007 #if defined(UNICODE_ENABLE) || defined(UNICODEMAP_ENABLE) || defined(UCIS_ENABLE)
1008 unicode_input_mode_init();
1009 #endif
927 matrix_init_kb(); 1010 matrix_init_kb();
928} 1011}
929 1012
@@ -958,6 +1041,10 @@ void matrix_scan_quantum() {
958 rgb_matrix_task_counter = ((rgb_matrix_task_counter + 1) % (RGB_MATRIX_SKIP_FRAMES + 1)); 1041 rgb_matrix_task_counter = ((rgb_matrix_task_counter + 1) % (RGB_MATRIX_SKIP_FRAMES + 1));
959 #endif 1042 #endif
960 1043
1044 #ifdef ENCODER_ENABLE
1045 encoder_read();
1046 #endif
1047
961 matrix_scan_kb(); 1048 matrix_scan_kb();
962} 1049}
963#if defined(BACKLIGHT_ENABLE) && defined(BACKLIGHT_PIN) 1050#if defined(BACKLIGHT_ENABLE) && defined(BACKLIGHT_PIN)
diff --git a/quantum/quantum.h b/quantum/quantum.h
index b4e4de174..f78915fdf 100644
--- a/quantum/quantum.h
+++ b/quantum/quantum.h
@@ -1,4 +1,4 @@
1/* Copyright 2016-2017 Erez Zukerman, Jack Humbert 1/* Copyright 2016-2018 Erez Zukerman, Jack Humbert, Yiancar
2 * 2 *
3 * This program is free software: you can redistribute it and/or modify 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 4 * it under the terms of the GNU General Public License as published by
@@ -17,9 +17,12 @@
17#define QUANTUM_H 17#define QUANTUM_H
18 18
19#if defined(__AVR__) 19#if defined(__AVR__)
20#include <avr/pgmspace.h> 20 #include <avr/pgmspace.h>
21#include <avr/io.h> 21 #include <avr/io.h>
22#include <avr/interrupt.h> 22 #include <avr/interrupt.h>
23#endif
24#if defined(PROTOCOL_CHIBIOS)
25 #include "hal.h"
23#endif 26#endif
24#include "wait.h" 27#include "wait.h"
25#include "matrix.h" 28#include "matrix.h"
@@ -28,10 +31,16 @@
28 #include "backlight.h" 31 #include "backlight.h"
29#endif 32#endif
30#if !defined(RGBLIGHT_ENABLE) && !defined(RGB_MATRIX_ENABLE) 33#if !defined(RGBLIGHT_ENABLE) && !defined(RGB_MATRIX_ENABLE)
31 #include "rgb.h" 34 #include "rgb.h"
32#endif 35#endif
33#ifdef RGBLIGHT_ENABLE 36#ifdef RGBLIGHT_ENABLE
34 #include "rgblight.h" 37 #include "rgblight.h"
38#else
39 #ifdef RGB_MATRIX_ENABLE
40 /* dummy define RGBLIGHT_MODE_xxxx */
41 #define RGBLIGHT_H_DUMMY_DEFINE
42 #include "rgblight.h"
43 #endif
35#endif 44#endif
36 45
37#ifdef SPLIT_KEYBOARD 46#ifdef SPLIT_KEYBOARD
@@ -70,9 +79,9 @@ extern uint32_t default_layer_state;
70#ifdef AUDIO_ENABLE 79#ifdef AUDIO_ENABLE
71 #include "audio.h" 80 #include "audio.h"
72 #include "process_audio.h" 81 #include "process_audio.h"
73 #ifdef AUDIO_CLICKY 82 #ifdef AUDIO_CLICKY
74 #include "process_clicky.h" 83 #include "process_clicky.h"
75 #endif // AUDIO_CLICKY 84 #endif // AUDIO_CLICKY
76#endif 85#endif
77 86
78#ifdef STENO_ENABLE 87#ifdef STENO_ENABLE
@@ -83,15 +92,10 @@ extern uint32_t default_layer_state;
83 #include "process_music.h" 92 #include "process_music.h"
84#endif 93#endif
85 94
86#ifndef DISABLE_LEADER 95#ifdef LEADER_ENABLE
87 #include "process_leader.h" 96 #include "process_leader.h"
88#endif 97#endif
89 98
90#define DISABLE_CHORDING
91#ifndef DISABLE_CHORDING
92 #include "process_chording.h"
93#endif
94
95#ifdef UNICODE_ENABLE 99#ifdef UNICODE_ENABLE
96 #include "process_unicode.h" 100 #include "process_unicode.h"
97#endif 101#endif
@@ -104,7 +108,9 @@ extern uint32_t default_layer_state;
104 #include "process_unicodemap.h" 108 #include "process_unicodemap.h"
105#endif 109#endif
106 110
107#include "process_tap_dance.h" 111#ifdef TAP_DANCE_ENABLE
112 #include "process_tap_dance.h"
113#endif
108 114
109#ifdef PRINTING_ENABLE 115#ifdef PRINTING_ENABLE
110 #include "process_printer.h" 116 #include "process_printer.h"
@@ -132,6 +138,50 @@ extern uint32_t default_layer_state;
132 #include "hd44780.h" 138 #include "hd44780.h"
133#endif 139#endif
134 140
141//Function substitutions to ease GPIO manipulation
142#ifdef __AVR__
143 #define PIN_ADDRESS(p, offset) _SFR_IO8(ADDRESS_BASE + (p >> PORT_SHIFTER) + offset)
144
145 #define pin_t uint8_t
146 #define setPinInput(pin) PIN_ADDRESS(pin, 1) &= ~ _BV(pin & 0xF)
147 #define setPinInputHigh(pin) ({\
148 PIN_ADDRESS(pin, 1) &= ~ _BV(pin & 0xF);\
149 PIN_ADDRESS(pin, 2) |= _BV(pin & 0xF);\
150 })
151 #define setPinInputLow(pin) _Static_assert(0, "AVR Processors cannot impliment an input as pull low")
152 #define setPinOutput(pin) PIN_ADDRESS(pin, 1) |= _BV(pin & 0xF)
153
154 #define writePinHigh(pin) PIN_ADDRESS(pin, 2) |= _BV(pin & 0xF)
155 #define writePinLow(pin) PIN_ADDRESS(pin, 2) &= ~_BV(pin & 0xF)
156 static inline void writePin(pin_t pin, uint8_t level){
157 if (level){
158 PIN_ADDRESS(pin, 2) |= _BV(pin & 0xF);
159 } else {
160 PIN_ADDRESS(pin, 2) &= ~_BV(pin & 0xF);
161 }
162 }
163
164 #define readPin(pin) ((bool)(PIN_ADDRESS(pin, 0) & _BV(pin & 0xF)))
165#elif defined(PROTOCOL_CHIBIOS)
166 #define pin_t ioline_t
167 #define setPinInput(pin) palSetLineMode(pin, PAL_MODE_INPUT)
168 #define setPinInputHigh(pin) palSetLineMode(pin, PAL_MODE_INPUT_PULLUP)
169 #define setPinInputLow(pin) palSetLineMode(pin, PAL_MODE_INPUT_PULLDOWN)
170 #define setPinOutput(pin) palSetLineMode(pin, PAL_MODE_OUTPUT_PUSHPULL)
171
172 #define writePinHigh(pin) palSetLine(pin)
173 #define writePinLow(pin) palClearLine(pin)
174 static inline void writePin(pin_t pin, uint8_t level){
175 if (level){
176 palSetLine(pin);
177 } else {
178 palClearLine(pin);
179 }
180 }
181
182 #define readPin(pin) palReadLine(pin)
183#endif
184
135#define STRINGIZE(z) #z 185#define STRINGIZE(z) #z
136#define ADD_SLASH_X(y) STRINGIZE(\x ## y) 186#define ADD_SLASH_X(y) STRINGIZE(\x ## y)
137#define SYMBOL_STR(x) ADD_SLASH_X(x) 187#define SYMBOL_STR(x) ADD_SLASH_X(x)
@@ -147,6 +197,7 @@ extern uint32_t default_layer_state;
147#define SS_LALT(string) SS_DOWN(X_LALT) string SS_UP(X_LALT) 197#define SS_LALT(string) SS_DOWN(X_LALT) string SS_UP(X_LALT)
148#define SS_LSFT(string) SS_DOWN(X_LSHIFT) string SS_UP(X_LSHIFT) 198#define SS_LSFT(string) SS_DOWN(X_LSHIFT) string SS_UP(X_LSHIFT)
149#define SS_RALT(string) SS_DOWN(X_RALT) string SS_UP(X_RALT) 199#define SS_RALT(string) SS_DOWN(X_RALT) string SS_UP(X_RALT)
200#define SS_ALGR(string) SS_RALT(string)
150 201
151#define SEND_STRING(str) send_string_P(PSTR(str)) 202#define SEND_STRING(str) send_string_P(PSTR(str))
152extern const bool ascii_to_shift_lut[0x80]; 203extern const bool ascii_to_shift_lut[0x80];
@@ -176,13 +227,23 @@ bool process_action_kb(keyrecord_t *record);
176bool process_record_kb(uint16_t keycode, keyrecord_t *record); 227bool process_record_kb(uint16_t keycode, keyrecord_t *record);
177bool process_record_user(uint16_t keycode, keyrecord_t *record); 228bool process_record_user(uint16_t keycode, keyrecord_t *record);
178 229
230#ifndef BOOTMAGIC_LITE_COLUMN
231 #define BOOTMAGIC_LITE_COLUMN 0
232#endif
233#ifndef BOOTMAGIC_LITE_ROW
234 #define BOOTMAGIC_LITE_ROW 0
235#endif
236
237void bootmagic_lite(void);
238
179void reset_keyboard(void); 239void reset_keyboard(void);
180 240
181void startup_user(void); 241void startup_user(void);
182void shutdown_user(void); 242void shutdown_user(void);
183 243
184void register_code16 (uint16_t code); 244void register_code16(uint16_t code);
185void unregister_code16 (uint16_t code); 245void unregister_code16(uint16_t code);
246void tap_code16(uint16_t code);
186 247
187#ifdef BACKLIGHT_ENABLE 248#ifdef BACKLIGHT_ENABLE
188void backlight_init_ports(void); 249void backlight_init_ports(void);
diff --git a/quantum/quantum_keycodes.h b/quantum/quantum_keycodes.h
index f2cdb8a3b..2b309f4d5 100644
--- a/quantum/quantum_keycodes.h
+++ b/quantum/quantum_keycodes.h
@@ -63,10 +63,6 @@ enum quantum_keycodes {
63 QK_ONE_SHOT_LAYER_MAX = 0x54FF, 63 QK_ONE_SHOT_LAYER_MAX = 0x54FF,
64 QK_ONE_SHOT_MOD = 0x5500, 64 QK_ONE_SHOT_MOD = 0x5500,
65 QK_ONE_SHOT_MOD_MAX = 0x55FF, 65 QK_ONE_SHOT_MOD_MAX = 0x55FF,
66#ifndef DISABLE_CHORDING
67 QK_CHORDING = 0x5600,
68 QK_CHORDING_MAX = 0x56FF,
69#endif
70 QK_TAP_DANCE = 0x5700, 66 QK_TAP_DANCE = 0x5700,
71 QK_TAP_DANCE_MAX = 0x57FF, 67 QK_TAP_DANCE_MAX = 0x57FF,
72 QK_LAYER_TAP_TOGGLE = 0x5800, 68 QK_LAYER_TAP_TOGGLE = 0x5800,
@@ -85,9 +81,6 @@ enum quantum_keycodes {
85#endif 81#endif
86 QK_MOD_TAP = 0x6000, 82 QK_MOD_TAP = 0x6000,
87 QK_MOD_TAP_MAX = 0x7FFF, 83 QK_MOD_TAP_MAX = 0x7FFF,
88#if defined(UNICODEMAP_ENABLE) && defined(UNICODE_ENABLE)
89 #error "Cannot enable both UNICODEMAP && UNICODE"
90#endif
91#ifdef UNICODE_ENABLE 84#ifdef UNICODE_ENABLE
92 QK_UNICODE = 0x8000, 85 QK_UNICODE = 0x8000,
93 QK_UNICODE_MAX = 0xFFFF, 86 QK_UNICODE_MAX = 0xFFFF,
@@ -120,10 +113,11 @@ enum quantum_keycodes {
120 MAGIC_UNHOST_NKRO, 113 MAGIC_UNHOST_NKRO,
121 MAGIC_UNSWAP_ALT_GUI, 114 MAGIC_UNSWAP_ALT_GUI,
122 MAGIC_TOGGLE_NKRO, 115 MAGIC_TOGGLE_NKRO,
116 MAGIC_TOGGLE_ALT_GUI,
123 GRAVE_ESC, 117 GRAVE_ESC,
124 118
125 // Leader key 119 // Leader key
126#ifndef DISABLE_LEADER 120#ifdef LEADER_ENABLE
127 KC_LEAD, 121 KC_LEAD,
128#endif 122#endif
129 123
@@ -142,10 +136,13 @@ enum quantum_keycodes {
142 136
143 // Faux clicky as part of main audio feature 137 // Faux clicky as part of main audio feature
144 CLICKY_TOGGLE, 138 CLICKY_TOGGLE,
139 CLICKY_ENABLE,
140 CLICKY_DISABLE,
145 CLICKY_UP, 141 CLICKY_UP,
146 CLICKY_DOWN, 142 CLICKY_DOWN,
147 CLICKY_RESET, 143 CLICKY_RESET,
148 144
145
149#ifdef FAUXCLICKY_ENABLE 146#ifdef FAUXCLICKY_ENABLE
150 // Faux clicky 147 // Faux clicky
151 FC_ON, 148 FC_ON,
@@ -454,32 +451,43 @@ enum quantum_keycodes {
454 TERM_OFF, 451 TERM_OFF,
455#endif 452#endif
456 453
454 EEPROM_RESET,
455
456 UNICODE_MODE_FORWARD,
457 UNICODE_MODE_REVERSE,
458
459 UNICODE_MODE_OSX,
460 UNICODE_MODE_LNX,
461 UNICODE_MODE_WIN,
462 UNICODE_MODE_BSD,
463 UNICODE_MODE_WINC,
464
457 // always leave at the end 465 // always leave at the end
458 SAFE_RANGE 466 SAFE_RANGE
459}; 467};
460 468
461// Ability to use mods in layouts 469// Ability to use mods in layouts
462#define LCTL(kc) (kc | QK_LCTL) 470#define LCTL(kc) (QK_LCTL | (kc))
463#define LSFT(kc) (kc | QK_LSFT) 471#define LSFT(kc) (QK_LSFT | (kc))
464#define LALT(kc) (kc | QK_LALT) 472#define LALT(kc) (QK_LALT | (kc))
465#define LGUI(kc) (kc | QK_LGUI) 473#define LGUI(kc) (QK_LGUI | (kc))
466#define LCMD(kc) LGUI(kc) 474#define LCMD(kc) LGUI(kc)
467#define LWIN(kc) LGUI(kc) 475#define LWIN(kc) LGUI(kc)
468#define RCTL(kc) (kc | QK_RCTL) 476#define RCTL(kc) (QK_RCTL | (kc))
469#define RSFT(kc) (kc | QK_RSFT) 477#define RSFT(kc) (QK_RSFT | (kc))
470#define RALT(kc) (kc | QK_RALT) 478#define RALT(kc) (QK_RALT | (kc))
471#define RGUI(kc) (kc | QK_RGUI) 479#define ALGR(kc) RALT(kc)
480#define RGUI(kc) (QK_RGUI | (kc))
472#define RCMD(kc) RGUI(kc) 481#define RCMD(kc) RGUI(kc)
473#define RWIN(kc) RGUI(kc) 482#define RWIN(kc) RGUI(kc)
474 483
475#define HYPR(kc) (kc | QK_LCTL | QK_LSFT | QK_LALT | QK_LGUI) 484#define HYPR(kc) (QK_LCTL | QK_LSFT | QK_LALT | QK_LGUI | (kc))
476#define MEH(kc) (kc | QK_LCTL | QK_LSFT | QK_LALT) 485#define MEH(kc) (QK_LCTL | QK_LSFT | QK_LALT | (kc))
477#define LCAG(kc) (kc | QK_LCTL | QK_LALT | QK_LGUI) 486#define LCAG(kc) (QK_LCTL | QK_LALT | QK_LGUI | (kc))
478#define ALTG(kc) (kc | QK_RCTL | QK_RALT) 487#define SGUI(kc) (QK_LGUI | QK_LSFT | (kc))
479#define SGUI(kc) (kc | QK_LGUI | QK_LSFT)
480#define SCMD(kc) SGUI(kc) 488#define SCMD(kc) SGUI(kc)
481#define SWIN(kc) SGUI(kc) 489#define SWIN(kc) SGUI(kc)
482#define LCA(kc) (kc | QK_LCTL | QK_LALT) 490#define LCA(kc) (QK_LCTL | QK_LALT | (kc))
483 491
484#define MOD_HYPR 0xf 492#define MOD_HYPR 0xf
485#define MOD_MEH 0x7 493#define MOD_MEH 0x7
@@ -557,26 +565,29 @@ enum quantum_keycodes {
557#define KC_DELT KC_DELETE // Del key (four letter code) 565#define KC_DELT KC_DELETE // Del key (four letter code)
558 566
559// Alias for function layers than expand past FN31 567// Alias for function layers than expand past FN31
560#define FUNC(kc) (kc | QK_FUNCTION) 568#define FUNC(kc) (QK_FUNCTION | (kc))
561 569
562// Aliases 570// Aliases
563#define S(kc) LSFT(kc) 571#define S(kc) LSFT(kc)
564#define F(kc) FUNC(kc) 572#define F(kc) FUNC(kc)
565 573
566#define M(kc) (kc | QK_MACRO) 574#define M(kc) (QK_MACRO | (kc))
567 575
568#define MACROTAP(kc) (kc | QK_MACRO | FUNC_TAP<<8) 576#define MACROTAP(kc) (QK_MACRO | (FUNC_TAP << 8) | (kc))
569#define MACRODOWN(...) (record->event.pressed ? MACRO(__VA_ARGS__) : MACRO_NONE) 577#define MACRODOWN(...) (record->event.pressed ? MACRO(__VA_ARGS__) : MACRO_NONE)
570 578
571#define KC_GESC GRAVE_ESC 579#define KC_GESC GRAVE_ESC
572 580
581#define EEP_RST EEPROM_RESET
582
573#define CK_TOGG CLICKY_TOGGLE 583#define CK_TOGG CLICKY_TOGGLE
574#define CK_RST CLICKY_RESET 584#define CK_RST CLICKY_RESET
575#define CK_UP CLICKY_UP 585#define CK_UP CLICKY_UP
576#define CK_DOWN CLICKY_DOWN 586#define CK_DOWN CLICKY_DOWN
587#define CK_ON CLICKY_ENABLE
588#define CK_OFF CLICKY_DISABLE
577 589
578#define RGB_MOD RGB_MODE_FORWARD 590#define RGB_MOD RGB_MODE_FORWARD
579#define RGB_SMOD RGB_MODE_FORWARD
580#define RGB_RMOD RGB_MODE_REVERSE 591#define RGB_RMOD RGB_MODE_REVERSE
581 592
582#define RGB_M_P RGB_MODE_PLAIN 593#define RGB_M_P RGB_MODE_PLAIN
@@ -590,10 +601,11 @@ enum quantum_keycodes {
590#define RGB_M_T RGB_MODE_RGBTEST 601#define RGB_M_T RGB_MODE_RGBTEST
591 602
592// L-ayer, T-ap - 256 keycode max, 16 layer max 603// L-ayer, T-ap - 256 keycode max, 16 layer max
593#define LT(layer, kc) (kc | QK_LAYER_TAP | ((layer & 0xF) << 8)) 604#define LT(layer, kc) (QK_LAYER_TAP | ((layer & 0xF) << 8) | ((kc) & 0xFF))
594 605
595#define AG_SWAP MAGIC_SWAP_ALT_GUI 606#define AG_SWAP MAGIC_SWAP_ALT_GUI
596#define AG_NORM MAGIC_UNSWAP_ALT_GUI 607#define AG_NORM MAGIC_UNSWAP_ALT_GUI
608#define AG_TOGG MAGIC_TOGGLE_ALT_GUI
597 609
598// GOTO layer - 16 layers max 610// GOTO layer - 16 layers max
599// when: 611// when:
@@ -602,32 +614,32 @@ enum quantum_keycodes {
602// Unless you have a good reason not to do so, prefer ON_PRESS (1) as your default. 614// Unless you have a good reason not to do so, prefer ON_PRESS (1) as your default.
603// In fact, we changed it to assume ON_PRESS for sanity/simplicity. If needed, you can add your own 615// In fact, we changed it to assume ON_PRESS for sanity/simplicity. If needed, you can add your own
604// keycode modeled after the old version, kept below for this. 616// keycode modeled after the old version, kept below for this.
605/* #define TO(layer, when) (layer | QK_TO | (when << 0x4)) */ 617/* #define TO(layer, when) (QK_TO | (when << 0x4) | (layer & 0xFF)) */
606#define TO(layer) (layer | QK_TO | (ON_PRESS << 0x4)) 618#define TO(layer) (QK_TO | (ON_PRESS << 0x4) | (layer & 0xFF))
607 619
608// Momentary switch layer - 256 layer max 620// Momentary switch layer - 256 layer max
609#define MO(layer) (layer | QK_MOMENTARY) 621#define MO(layer) (QK_MOMENTARY | (layer & 0xFF))
610 622
611// Set default layer - 256 layer max 623// Set default layer - 256 layer max
612#define DF(layer) (layer | QK_DEF_LAYER) 624#define DF(layer) (QK_DEF_LAYER | (layer & 0xFF))
613 625
614// Toggle to layer - 256 layer max 626// Toggle to layer - 256 layer max
615#define TG(layer) (layer | QK_TOGGLE_LAYER) 627#define TG(layer) (QK_TOGGLE_LAYER | (layer & 0xFF))
616 628
617// One-shot layer - 256 layer max 629// One-shot layer - 256 layer max
618#define OSL(layer) (layer | QK_ONE_SHOT_LAYER) 630#define OSL(layer) (QK_ONE_SHOT_LAYER | (layer & 0xFF))
619 631
620// L-ayer M-od: Momentary switch layer with modifiers active - 16 layer max, left mods only 632// L-ayer M-od: Momentary switch layer with modifiers active - 16 layer max, left mods only
621#define LM(layer, mod) (QK_LAYER_MOD | (((layer) & 0xF) << 4) | ((mod) & 0xF)) 633#define LM(layer, mod) (QK_LAYER_MOD | ((layer & 0xF) << 4) | ((mod) & 0xF))
622 634
623// One-shot mod 635// One-shot mod
624#define OSM(mod) ((mod) | QK_ONE_SHOT_MOD) 636#define OSM(mod) (QK_ONE_SHOT_MOD | ((mod) & 0xFF))
625 637
626// Layer tap-toggle 638// Layer tap-toggle
627#define TT(layer) (layer | QK_LAYER_TAP_TOGGLE) 639#define TT(layer) (QK_LAYER_TAP_TOGGLE | (layer & 0xFF))
628 640
629// M-od, T-ap - 256 keycode max 641// M-od, T-ap - 256 keycode max
630#define MT(mod, kc) (kc | QK_MOD_TAP | (((mod) & 0x1F) << 8)) 642#define MT(mod, kc) (QK_MOD_TAP | (((mod) & 0x1F) << 8) | ((kc) & 0xFF))
631 643
632#define CTL_T(kc) MT(MOD_LCTL, kc) 644#define CTL_T(kc) MT(MOD_LCTL, kc)
633#define LCTL_T(kc) MT(MOD_LCTL, kc) 645#define LCTL_T(kc) MT(MOD_LCTL, kc)
@@ -640,7 +652,7 @@ enum quantum_keycodes {
640#define ALT_T(kc) MT(MOD_LALT, kc) 652#define ALT_T(kc) MT(MOD_LALT, kc)
641#define LALT_T(kc) MT(MOD_LALT, kc) 653#define LALT_T(kc) MT(MOD_LALT, kc)
642#define RALT_T(kc) MT(MOD_RALT, kc) 654#define RALT_T(kc) MT(MOD_RALT, kc)
643#define ALGR_T(kc) MT(MOD_RALT, kc) // dual-function AltGR 655#define ALGR_T(kc) RALT_T(kc)
644 656
645#define GUI_T(kc) MT(MOD_LGUI, kc) 657#define GUI_T(kc) MT(MOD_LGUI, kc)
646#define CMD_T(kc) GUI_T(kc) 658#define CMD_T(kc) GUI_T(kc)
@@ -652,15 +664,15 @@ enum quantum_keycodes {
652#define RCMD_T(kc) RGUI_T(kc) 664#define RCMD_T(kc) RGUI_T(kc)
653#define RWIN_T(kc) RGUI_T(kc) 665#define RWIN_T(kc) RGUI_T(kc)
654 666
655#define C_S_T(kc) MT((MOD_LCTL | MOD_LSFT), kc) // Control + Shift e.g. for gnome-terminal 667#define C_S_T(kc) MT(MOD_LCTL | MOD_LSFT, kc) // Control + Shift e.g. for gnome-terminal
656#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 668#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
657#define LCAG_T(kc) MT((MOD_LCTL | MOD_LALT | MOD_LGUI), kc) // Left control alt and gui 669#define LCAG_T(kc) MT(MOD_LCTL | MOD_LALT | MOD_LGUI, kc) // Left control alt and gui
658#define RCAG_T(kc) MT((MOD_RCTL | MOD_RALT | MOD_RGUI), kc) // Right control alt and gui 670#define RCAG_T(kc) MT(MOD_RCTL | MOD_RALT | MOD_RGUI, kc) // Right control alt and gui
659#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/ 671#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/
660#define SGUI_T(kc) MT((MOD_LGUI | MOD_LSFT), kc) 672#define SGUI_T(kc) MT(MOD_LGUI | MOD_LSFT, kc)
661#define SCMD_T(kc) SGUI_T(kc) 673#define SCMD_T(kc) SGUI_T(kc)
662#define SWIN_T(kc) SGUI_T(kc) 674#define SWIN_T(kc) SGUI_T(kc)
663#define LCA_T(kc) MT((MOD_LCTL | MOD_LALT), kc) // Left control and left alt 675#define LCA_T(kc) MT(MOD_LCTL | MOD_LALT, kc) // Left control and left alt
664 676
665// Dedicated keycode versions for Hyper and Meh, if you want to use them as standalone keys rather than mod-tap 677// Dedicated keycode versions for Hyper and Meh, if you want to use them as standalone keys rather than mod-tap
666#define KC_HYPR HYPR(KC_NO) 678#define KC_HYPR HYPR(KC_NO)
@@ -670,22 +682,31 @@ enum quantum_keycodes {
670 // For sending unicode codes. 682 // For sending unicode codes.
671 // You may not send codes over 7FFF -- this supports most of UTF8. 683 // You may not send codes over 7FFF -- this supports most of UTF8.
672 // To have a key that sends out Œ, go UC(0x0152) 684 // To have a key that sends out Œ, go UC(0x0152)
673 #define UNICODE(n) (n | QK_UNICODE) 685 #define UNICODE(n) (QK_UNICODE | (n))
674 #define UC(n) UNICODE(n) 686 #define UC(n) UNICODE(n)
675#endif 687#endif
676 688
677#ifdef UNICODEMAP_ENABLE 689#ifdef UNICODEMAP_ENABLE
678 #define X(n) (n | QK_UNICODE_MAP) 690 #define X(n) (QK_UNICODE_MAP | (n))
679#endif 691#endif
680 692
693#define UC_MOD UNICODE_MODE_FORWARD
694#define UC_RMOD UNICODE_MODE_REVERSE
695
696#define UC_M_OS UNICODE_MODE_OSX
697#define UC_M_LN UNICODE_MODE_LNX
698#define UC_M_WI UNICODE_MODE_WIN
699#define UC_M_BS UNICODE_MODE_BSD
700#define UC_M_WC UNICODE_MODE_WINC
701
681#ifdef SWAP_HANDS_ENABLE 702#ifdef SWAP_HANDS_ENABLE
682 #define SH_T(key) (QK_SWAP_HANDS | key) 703 #define SH_T(kc) (QK_SWAP_HANDS | (kc))
683 #define SH_TG (QK_SWAP_HANDS | OP_SH_TOGGLE) 704 #define SH_TG (QK_SWAP_HANDS | OP_SH_TOGGLE)
684 #define SH_TT (QK_SWAP_HANDS | OP_SH_TAP_TOGGLE) 705 #define SH_TT (QK_SWAP_HANDS | OP_SH_TAP_TOGGLE)
685 #define SH_MON (QK_SWAP_HANDS | OP_SH_ON_OFF) 706 #define SH_MON (QK_SWAP_HANDS | OP_SH_ON_OFF)
686 #define SH_MOFF (QK_SWAP_HANDS | OP_SH_OFF_ON) 707 #define SH_MOFF (QK_SWAP_HANDS | OP_SH_OFF_ON)
687 #define SH_ON (QK_SWAP_HANDS | OP_SH_ON) 708 #define SH_ON (QK_SWAP_HANDS | OP_SH_ON)
688 #define SH_OFF (QK_SWAP_HANDS | OP_SH_OFF) 709 #define SH_OFF (QK_SWAP_HANDS | OP_SH_OFF)
689#endif 710#endif
690 711
691#endif // QUANTUM_KEYCODES_H 712#endif // QUANTUM_KEYCODES_H
diff --git a/quantum/rgb_matrix.c b/quantum/rgb_matrix.c
index 197bc1ac5..2ed36304d 100644
--- a/quantum/rgb_matrix.c
+++ b/quantum/rgb_matrix.c
@@ -18,10 +18,10 @@
18 18
19 19
20#include "rgb_matrix.h" 20#include "rgb_matrix.h"
21#include "i2c_master.h"
22#include "progmem.h" 21#include "progmem.h"
23#include "config.h" 22#include "config.h"
24#include "eeprom.h" 23#include "eeprom.h"
24#include <string.h>
25#include <math.h> 25#include <math.h>
26 26
27rgb_config_t rgb_matrix_config; 27rgb_config_t rgb_matrix_config;
@@ -50,6 +50,15 @@ rgb_config_t rgb_matrix_config;
50 #define RGB_MATRIX_MAXIMUM_BRIGHTNESS 255 50 #define RGB_MATRIX_MAXIMUM_BRIGHTNESS 255
51#endif 51#endif
52 52
53#ifndef RGB_DIGITAL_RAIN_DROPS
54 // lower the number for denser effect/wider keyboard
55 #define RGB_DIGITAL_RAIN_DROPS 24
56#endif
57
58#if !defined(DISABLE_RGB_MATRIX_RAINDROPS) || !defined(DISABLE_RGB_MATRIX_JELLYBEAN_RAINDROPS) || !defined(DISABLE_RGB_MATRIX_DIGITAL_RAIN)
59 #define TRACK_PREVIOUS_EFFECT
60#endif
61
53bool g_suspend_state = false; 62bool g_suspend_state = false;
54 63
55// Global tick at 20 Hz 64// Global tick at 20 Hz
@@ -74,7 +83,12 @@ void eeconfig_update_rgb_matrix(uint32_t val) {
74void eeconfig_update_rgb_matrix_default(void) { 83void eeconfig_update_rgb_matrix_default(void) {
75 dprintf("eeconfig_update_rgb_matrix_default\n"); 84 dprintf("eeconfig_update_rgb_matrix_default\n");
76 rgb_matrix_config.enable = 1; 85 rgb_matrix_config.enable = 1;
86#ifndef DISABLE_RGB_MATRIX_CYCLE_ALL
77 rgb_matrix_config.mode = RGB_MATRIX_CYCLE_LEFT_RIGHT; 87 rgb_matrix_config.mode = RGB_MATRIX_CYCLE_LEFT_RIGHT;
88#else
89 // fallback to solid colors if RGB_MATRIX_CYCLE_LEFT_RIGHT is disabled in userspace
90 rgb_matrix_config.mode = RGB_MATRIX_SOLID_COLOR;
91#endif
78 rgb_matrix_config.hue = 0; 92 rgb_matrix_config.hue = 0;
79 rgb_matrix_config.sat = 255; 93 rgb_matrix_config.sat = 255;
80 rgb_matrix_config.val = RGB_MATRIX_MAXIMUM_BRIGHTNESS; 94 rgb_matrix_config.val = RGB_MATRIX_MAXIMUM_BRIGHTNESS;
@@ -111,29 +125,15 @@ void map_row_column_to_led( uint8_t row, uint8_t column, uint8_t *led_i, uint8_t
111} 125}
112 126
113void rgb_matrix_update_pwm_buffers(void) { 127void rgb_matrix_update_pwm_buffers(void) {
114#ifdef IS31FL3731 128 rgb_matrix_driver.flush();
115 IS31FL3731_update_pwm_buffers( DRIVER_ADDR_1, DRIVER_ADDR_2 );
116 IS31FL3731_update_led_control_registers( DRIVER_ADDR_1, DRIVER_ADDR_2 );
117#elif defined(IS31FL3733)
118 IS31FL3733_update_pwm_buffers( DRIVER_ADDR_1, DRIVER_ADDR_2 );
119 IS31FL3733_update_led_control_registers( DRIVER_ADDR_1, DRIVER_ADDR_2 );
120#endif
121} 129}
122 130
123void rgb_matrix_set_color( int index, uint8_t red, uint8_t green, uint8_t blue ) { 131void rgb_matrix_set_color( int index, uint8_t red, uint8_t green, uint8_t blue ) {
124#ifdef IS31FL3731 132 rgb_matrix_driver.set_color(index, red, green, blue);
125 IS31FL3731_set_color( index, red, green, blue );
126#elif defined(IS31FL3733)
127 IS31FL3733_set_color( index, red, green, blue );
128#endif
129} 133}
130 134
131void rgb_matrix_set_color_all( uint8_t red, uint8_t green, uint8_t blue ) { 135void rgb_matrix_set_color_all( uint8_t red, uint8_t green, uint8_t blue ) {
132#ifdef IS31FL3731 136 rgb_matrix_driver.set_color_all(red, green, blue);
133 IS31FL3731_set_color_all( red, green, blue );
134#elif defined(IS31FL3733)
135 IS31FL3733_set_color_all( red, green, blue );
136#endif
137} 137}
138 138
139bool process_rgb_matrix(uint16_t keycode, keyrecord_t *record) { 139bool process_rgb_matrix(uint16_t keycode, keyrecord_t *record) {
@@ -196,47 +196,6 @@ void rgb_matrix_test(void) {
196 } 196 }
197} 197}
198 198
199// This tests the LEDs
200// Note that it will change the LED control registers
201// in the LED drivers, and leave them in an invalid
202// state for other backlight effects.
203// ONLY USE THIS FOR TESTING LEDS!
204void rgb_matrix_single_LED_test(void) {
205 static uint8_t color = 0; // 0,1,2 for R,G,B
206 static uint8_t row = 0;
207 static uint8_t column = 0;
208
209 static uint8_t tick = 0;
210 tick++;
211
212 if ( tick > 2 )
213 {
214 tick = 0;
215 column++;
216 }
217 if ( column > MATRIX_COLS )
218 {
219 column = 0;
220 row++;
221 }
222 if ( row > MATRIX_ROWS )
223 {
224 row = 0;
225 color++;
226 }
227 if ( color > 2 )
228 {
229 color = 0;
230 }
231
232 uint8_t led[8], led_count;
233 map_row_column_to_led(row,column,led,&led_count);
234 for(uint8_t i = 0; i < led_count; i++) {
235 rgb_matrix_set_color_all( 40, 40, 40 );
236 rgb_matrix_test_led( led[i], color==0, color==1, color==2 );
237 }
238}
239
240// All LEDs off 199// All LEDs off
241void rgb_matrix_all_off(void) { 200void rgb_matrix_all_off(void) {
242 rgb_matrix_set_color_all( 0, 0, 0 ); 201 rgb_matrix_set_color_all( 0, 0, 0 );
@@ -438,10 +397,12 @@ void rgb_matrix_cycle_up_down(void) {
438void rgb_matrix_dual_beacon(void) { 397void rgb_matrix_dual_beacon(void) {
439 HSV hsv = { .h = rgb_matrix_config.hue, .s = rgb_matrix_config.sat, .v = rgb_matrix_config.val }; 398 HSV hsv = { .h = rgb_matrix_config.hue, .s = rgb_matrix_config.sat, .v = rgb_matrix_config.val };
440 RGB rgb; 399 RGB rgb;
441 rgb_led led; 400 Point point;
401 double cos_value = cos(g_tick * PI / 128) / 32;
402 double sin_value = sin(g_tick * PI / 128) / 112;
442 for (uint8_t i = 0; i < DRIVER_LED_TOTAL; i++) { 403 for (uint8_t i = 0; i < DRIVER_LED_TOTAL; i++) {
443 led = g_rgb_leds[i]; 404 point = g_rgb_leds[i].point;
444 hsv.h = ((led.point.y - 32.0)* cos(g_tick * PI / 128) / 32 + (led.point.x - 112.0) * sin(g_tick * PI / 128) / (112)) * (180) + rgb_matrix_config.hue; 405 hsv.h = ((point.y - 32.0)* cos_value + (point.x - 112.0) * sin_value) * (180) + rgb_matrix_config.hue;
445 rgb = hsv_to_rgb( hsv ); 406 rgb = hsv_to_rgb( hsv );
446 rgb_matrix_set_color( i, rgb.r, rgb.g, rgb.b ); 407 rgb_matrix_set_color( i, rgb.r, rgb.g, rgb.b );
447 } 408 }
@@ -450,10 +411,12 @@ void rgb_matrix_dual_beacon(void) {
450void rgb_matrix_rainbow_beacon(void) { 411void rgb_matrix_rainbow_beacon(void) {
451 HSV hsv = { .h = rgb_matrix_config.hue, .s = rgb_matrix_config.sat, .v = rgb_matrix_config.val }; 412 HSV hsv = { .h = rgb_matrix_config.hue, .s = rgb_matrix_config.sat, .v = rgb_matrix_config.val };
452 RGB rgb; 413 RGB rgb;
453 rgb_led led; 414 Point point;
415 double cos_value = cos(g_tick * PI / 128);
416 double sin_value = sin(g_tick * PI / 128);
454 for (uint8_t i = 0; i < DRIVER_LED_TOTAL; i++) { 417 for (uint8_t i = 0; i < DRIVER_LED_TOTAL; i++) {
455 led = g_rgb_leds[i]; 418 point = g_rgb_leds[i].point;
456 hsv.h = (1.5 * (rgb_matrix_config.speed == 0 ? 1 : rgb_matrix_config.speed)) * (led.point.y - 32.0)* cos(g_tick * PI / 128) + (1.5 * (rgb_matrix_config.speed == 0 ? 1 : rgb_matrix_config.speed)) * (led.point.x - 112.0) * sin(g_tick * PI / 128) + rgb_matrix_config.hue; 419 hsv.h = (1.5 * (rgb_matrix_config.speed == 0 ? 1 : rgb_matrix_config.speed)) * (point.y - 32.0)* cos_value + (1.5 * (rgb_matrix_config.speed == 0 ? 1 : rgb_matrix_config.speed)) * (point.x - 112.0) * sin_value + rgb_matrix_config.hue;
457 rgb = hsv_to_rgb( hsv ); 420 rgb = hsv_to_rgb( hsv );
458 rgb_matrix_set_color( i, rgb.r, rgb.g, rgb.b ); 421 rgb_matrix_set_color( i, rgb.r, rgb.g, rgb.b );
459 } 422 }
@@ -462,10 +425,12 @@ void rgb_matrix_rainbow_beacon(void) {
462void rgb_matrix_rainbow_pinwheels(void) { 425void rgb_matrix_rainbow_pinwheels(void) {
463 HSV hsv = { .h = rgb_matrix_config.hue, .s = rgb_matrix_config.sat, .v = rgb_matrix_config.val }; 426 HSV hsv = { .h = rgb_matrix_config.hue, .s = rgb_matrix_config.sat, .v = rgb_matrix_config.val };
464 RGB rgb; 427 RGB rgb;
465 rgb_led led; 428 Point point;
429 double cos_value = cos(g_tick * PI / 128);
430 double sin_value = sin(g_tick * PI / 128);
466 for (uint8_t i = 0; i < DRIVER_LED_TOTAL; i++) { 431 for (uint8_t i = 0; i < DRIVER_LED_TOTAL; i++) {
467 led = g_rgb_leds[i]; 432 point = g_rgb_leds[i].point;
468 hsv.h = (2 * (rgb_matrix_config.speed == 0 ? 1 : rgb_matrix_config.speed)) * (led.point.y - 32.0)* cos(g_tick * PI / 128) + (2 * (rgb_matrix_config.speed == 0 ? 1 : rgb_matrix_config.speed)) * (66 - abs(led.point.x - 112.0)) * sin(g_tick * PI / 128) + rgb_matrix_config.hue; 433 hsv.h = (2 * (rgb_matrix_config.speed == 0 ? 1 : rgb_matrix_config.speed)) * (point.y - 32.0)* cos_value + (2 * (rgb_matrix_config.speed == 0 ? 1 : rgb_matrix_config.speed)) * (66 - abs(point.x - 112.0)) * sin_value + rgb_matrix_config.hue;
469 rgb = hsv_to_rgb( hsv ); 434 rgb = hsv_to_rgb( hsv );
470 rgb_matrix_set_color( i, rgb.r, rgb.g, rgb.b ); 435 rgb_matrix_set_color( i, rgb.r, rgb.g, rgb.b );
471 } 436 }
@@ -474,12 +439,14 @@ void rgb_matrix_rainbow_pinwheels(void) {
474void rgb_matrix_rainbow_moving_chevron(void) { 439void rgb_matrix_rainbow_moving_chevron(void) {
475 HSV hsv = { .h = rgb_matrix_config.hue, .s = rgb_matrix_config.sat, .v = rgb_matrix_config.val }; 440 HSV hsv = { .h = rgb_matrix_config.hue, .s = rgb_matrix_config.sat, .v = rgb_matrix_config.val };
476 RGB rgb; 441 RGB rgb;
477 rgb_led led; 442 Point point;
443 uint8_t r = 128;
444 double cos_value = cos(r * PI / 128);
445 double sin_value = sin(r * PI / 128);
446 double multiplier = (g_tick / 256.0 * 224);
478 for (uint8_t i = 0; i < DRIVER_LED_TOTAL; i++) { 447 for (uint8_t i = 0; i < DRIVER_LED_TOTAL; i++) {
479 led = g_rgb_leds[i]; 448 point = g_rgb_leds[i].point;
480 // uint8_t r = g_tick; 449 hsv.h = (1.5 * (rgb_matrix_config.speed == 0 ? 1 : rgb_matrix_config.speed)) * abs(point.y - 32.0)* sin_value + (1.5 * (rgb_matrix_config.speed == 0 ? 1 : rgb_matrix_config.speed)) * (point.x - multiplier) * cos_value + rgb_matrix_config.hue;
481 uint8_t r = 128;
482 hsv.h = (1.5 * (rgb_matrix_config.speed == 0 ? 1 : rgb_matrix_config.speed)) * abs(led.point.y - 32.0)* sin(r * PI / 128) + (1.5 * (rgb_matrix_config.speed == 0 ? 1 : rgb_matrix_config.speed)) * (led.point.x - (g_tick / 256.0 * 224)) * cos(r * PI / 128) + rgb_matrix_config.hue;
483 rgb = hsv_to_rgb( hsv ); 450 rgb = hsv_to_rgb( hsv );
484 rgb_matrix_set_color( i, rgb.r, rgb.g, rgb.b ); 451 rgb_matrix_set_color( i, rgb.r, rgb.g, rgb.b );
485 } 452 }
@@ -510,6 +477,68 @@ void rgb_matrix_jellybean_raindrops( bool initialize ) {
510 } 477 }
511} 478}
512 479
480void rgb_matrix_digital_rain( const bool initialize ) {
481 // algorithm ported from https://github.com/tremby/Kaleidoscope-LEDEffect-DigitalRain
482 const uint8_t drop_ticks = 28;
483 const uint8_t pure_green_intensity = 0xd0;
484 const uint8_t max_brightness_boost = 0xc0;
485 const uint8_t max_intensity = 0xff;
486
487 static uint8_t map[MATRIX_COLS][MATRIX_ROWS] = {{0}};
488 static uint8_t drop = 0;
489
490 if (initialize) {
491 rgb_matrix_set_color_all(0, 0, 0);
492 memset(map, 0, sizeof map);
493 drop = 0;
494 }
495 for (uint8_t col = 0; col < MATRIX_COLS; col++) {
496 for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
497 if (row == 0 && drop == 0 && rand() < RAND_MAX / RGB_DIGITAL_RAIN_DROPS) {
498 // top row, pixels have just fallen and we're
499 // making a new rain drop in this column
500 map[col][row] = max_intensity;
501 }
502 else if (map[col][row] > 0 && map[col][row] < max_intensity) {
503 // neither fully bright nor dark, decay it
504 map[col][row]--;
505 }
506 // set the pixel colour
507 uint8_t led, led_count;
508 map_row_column_to_led(row, col, &led, &led_count);
509
510 if (map[col][row] > pure_green_intensity) {
511 const uint8_t boost = (uint8_t) ((uint16_t) max_brightness_boost
512 * (map[col][row] - pure_green_intensity) / (max_intensity - pure_green_intensity));
513 rgb_matrix_set_color(led, boost, max_intensity, boost);
514 }
515 else {
516 const uint8_t green = (uint8_t) ((uint16_t) max_intensity * map[col][row] / pure_green_intensity);
517 rgb_matrix_set_color(led, 0, green, 0);
518 }
519 }
520 }
521 if (++drop > drop_ticks) {
522 // reset drop timer
523 drop = 0;
524 for (uint8_t row = MATRIX_ROWS - 1; row > 0; row--) {
525 for (uint8_t col = 0; col < MATRIX_COLS; col++) {
526 // if ths is on the bottom row and bright allow decay
527 if (row == MATRIX_ROWS - 1 && map[col][row] == max_intensity) {
528 map[col][row]--;
529 }
530 // check if the pixel above is bright
531 if (map[col][row - 1] == max_intensity) {
532 // allow old bright pixel to decay
533 map[col][row - 1]--;
534 // make this pixel bright
535 map[col][row] = max_intensity;
536 }
537 }
538 }
539 }
540}
541
513void rgb_matrix_multisplash(void) { 542void rgb_matrix_multisplash(void) {
514 // if (g_any_key_hit < 0xFF) { 543 // if (g_any_key_hit < 0xFF) {
515 HSV hsv = { .h = rgb_matrix_config.hue, .s = rgb_matrix_config.sat, .v = rgb_matrix_config.val }; 544 HSV hsv = { .h = rgb_matrix_config.hue, .s = rgb_matrix_config.sat, .v = rgb_matrix_config.val };
@@ -598,11 +627,16 @@ void rgb_matrix_custom(void) {
598} 627}
599 628
600void rgb_matrix_task(void) { 629void rgb_matrix_task(void) {
601 static uint8_t toggle_enable_last = 255; 630 #ifdef TRACK_PREVIOUS_EFFECT
631 static uint8_t toggle_enable_last = 255;
632 #endif
602 if (!rgb_matrix_config.enable) { 633 if (!rgb_matrix_config.enable) {
603 rgb_matrix_all_off(); 634 rgb_matrix_all_off();
604 toggle_enable_last = rgb_matrix_config.enable; 635 rgb_matrix_indicators();
605 return; 636 #ifdef TRACK_PREVIOUS_EFFECT
637 toggle_enable_last = rgb_matrix_config.enable;
638 #endif
639 return;
606 } 640 }
607 // delay 1 second before driving LEDs or doing anything else 641 // delay 1 second before driving LEDs or doing anything else
608 static uint8_t startup_tick = 0; 642 static uint8_t startup_tick = 0;
@@ -637,13 +671,16 @@ void rgb_matrix_task(void) {
637 (RGB_DISABLE_AFTER_TIMEOUT > 0 && g_any_key_hit > RGB_DISABLE_AFTER_TIMEOUT * 60 * 20)); 671 (RGB_DISABLE_AFTER_TIMEOUT > 0 && g_any_key_hit > RGB_DISABLE_AFTER_TIMEOUT * 60 * 20));
638 uint8_t effect = suspend_backlight ? 0 : rgb_matrix_config.mode; 672 uint8_t effect = suspend_backlight ? 0 : rgb_matrix_config.mode;
639 673
640 // Keep track of the effect used last time, 674 #ifdef TRACK_PREVIOUS_EFFECT
641 // detect change in effect, so each effect can 675 // Keep track of the effect used last time,
642 // have an optional initialization. 676 // detect change in effect, so each effect can
643 static uint8_t effect_last = 255; 677 // have an optional initialization.
644 bool initialize = (effect != effect_last) || (rgb_matrix_config.enable != toggle_enable_last); 678
645 effect_last = effect; 679 static uint8_t effect_last = 255;
646 toggle_enable_last = rgb_matrix_config.enable; 680 bool initialize = (effect != effect_last) || (rgb_matrix_config.enable != toggle_enable_last);
681 effect_last = effect;
682 toggle_enable_last = rgb_matrix_config.enable;
683 #endif
647 684
648 // this gets ticked at 20 Hz. 685 // this gets ticked at 20 Hz.
649 // each effect can opt to do calculations 686 // each effect can opt to do calculations
@@ -652,56 +689,93 @@ void rgb_matrix_task(void) {
652 case RGB_MATRIX_SOLID_COLOR: 689 case RGB_MATRIX_SOLID_COLOR:
653 rgb_matrix_solid_color(); 690 rgb_matrix_solid_color();
654 break; 691 break;
655 case RGB_MATRIX_ALPHAS_MODS: 692 #ifndef DISABLE_RGB_MATRIX_ALPHAS_MODS
656 rgb_matrix_alphas_mods(); 693 case RGB_MATRIX_ALPHAS_MODS:
657 break; 694 rgb_matrix_alphas_mods();
658 case RGB_MATRIX_DUAL_BEACON: 695 break;
659 rgb_matrix_dual_beacon(); 696 #endif
660 break; 697 #ifndef DISABLE_RGB_MATRIX_DUAL_BEACON
661 case RGB_MATRIX_GRADIENT_UP_DOWN: 698 case RGB_MATRIX_DUAL_BEACON:
662 rgb_matrix_gradient_up_down(); 699 rgb_matrix_dual_beacon();
663 break;
664 case RGB_MATRIX_RAINDROPS:
665 rgb_matrix_raindrops( initialize );
666 break;
667 case RGB_MATRIX_CYCLE_ALL:
668 rgb_matrix_cycle_all();
669 break;
670 case RGB_MATRIX_CYCLE_LEFT_RIGHT:
671 rgb_matrix_cycle_left_right();
672 break;
673 case RGB_MATRIX_CYCLE_UP_DOWN:
674 rgb_matrix_cycle_up_down();
675 break;
676 case RGB_MATRIX_RAINBOW_BEACON:
677 rgb_matrix_rainbow_beacon();
678 break;
679 case RGB_MATRIX_RAINBOW_PINWHEELS:
680 rgb_matrix_rainbow_pinwheels();
681 break;
682 case RGB_MATRIX_RAINBOW_MOVING_CHEVRON:
683 rgb_matrix_rainbow_moving_chevron();
684 break;
685 case RGB_MATRIX_JELLYBEAN_RAINDROPS:
686 rgb_matrix_jellybean_raindrops( initialize );
687 break;
688 #ifdef RGB_MATRIX_KEYPRESSES
689 case RGB_MATRIX_SOLID_REACTIVE:
690 rgb_matrix_solid_reactive();
691 break; 700 break;
692 case RGB_MATRIX_SPLASH: 701 #endif
693 rgb_matrix_splash(); 702 #ifndef DISABLE_RGB_MATRIX_GRADIENT_UP_DOWN
703 case RGB_MATRIX_GRADIENT_UP_DOWN:
704 rgb_matrix_gradient_up_down();
705 break;
706 #endif
707 #ifndef DISABLE_RGB_MATRIX_RAINDROPS
708 case RGB_MATRIX_RAINDROPS:
709 rgb_matrix_raindrops( initialize );
710 break;
711 #endif
712 #ifndef DISABLE_RGB_MATRIX_CYCLE_ALL
713 case RGB_MATRIX_CYCLE_ALL:
714 rgb_matrix_cycle_all();
694 break; 715 break;
695 case RGB_MATRIX_MULTISPLASH: 716 #endif
696 rgb_matrix_multisplash(); 717 #ifndef DISABLE_RGB_MATRIX_CYCLE_LEFT_RIGHT
718 case RGB_MATRIX_CYCLE_LEFT_RIGHT:
719 rgb_matrix_cycle_left_right();
697 break; 720 break;
698 case RGB_MATRIX_SOLID_SPLASH: 721 #endif
699 rgb_matrix_solid_splash(); 722 #ifndef DISABLE_RGB_MATRIX_CYCLE_UP_DOWN
723 case RGB_MATRIX_CYCLE_UP_DOWN:
724 rgb_matrix_cycle_up_down();
700 break; 725 break;
701 case RGB_MATRIX_SOLID_MULTISPLASH: 726 #endif
702 rgb_matrix_solid_multisplash(); 727 #ifndef DISABLE_RGB_MATRIX_RAINBOW_BEACON
728 case RGB_MATRIX_RAINBOW_BEACON:
729 rgb_matrix_rainbow_beacon();
703 break; 730 break;
704 #endif 731 #endif
732 #ifndef DISABLE_RGB_MATRIX_RAINBOW_PINWHEELS
733 case RGB_MATRIX_RAINBOW_PINWHEELS:
734 rgb_matrix_rainbow_pinwheels();
735 break;
736 #endif
737 #ifndef DISABLE_RGB_MATRIX_RAINBOW_MOVING_CHEVRON
738 case RGB_MATRIX_RAINBOW_MOVING_CHEVRON:
739 rgb_matrix_rainbow_moving_chevron();
740 break;
741 #endif
742 #ifndef DISABLE_RGB_MATRIX_JELLYBEAN_RAINDROPS
743 case RGB_MATRIX_JELLYBEAN_RAINDROPS:
744 rgb_matrix_jellybean_raindrops( initialize );
745 break;
746 #endif
747 #ifndef DISABLE_RGB_MATRIX_DIGITAL_RAIN
748 case RGB_MATRIX_DIGITAL_RAIN:
749 rgb_matrix_digital_rain( initialize );
750 break;
751 #endif
752 #ifdef RGB_MATRIX_KEYPRESSES
753 #ifndef DISABLE_RGB_MATRIX_SOLID_REACTIVE
754 case RGB_MATRIX_SOLID_REACTIVE:
755 rgb_matrix_solid_reactive();
756 break;
757 #endif
758 #ifndef DISABLE_RGB_MATRIX_SPLASH
759 case RGB_MATRIX_SPLASH:
760 rgb_matrix_splash();
761 break;
762 #endif
763 #ifndef DISABLE_RGB_MATRIX_MULTISPLASH
764 case RGB_MATRIX_MULTISPLASH:
765 rgb_matrix_multisplash();
766 break;
767 #endif
768 #ifndef DISABLE_RGB_MATRIX_SOLID_SPLASH
769 case RGB_MATRIX_SOLID_SPLASH:
770 rgb_matrix_solid_splash();
771 break;
772 #endif
773 #ifndef DISABLE_RGB_MATRIX_SOLID_MULTISPLASH
774 case RGB_MATRIX_SOLID_MULTISPLASH:
775 rgb_matrix_solid_multisplash();
776 break;
777 #endif
778 #endif
705 default: 779 default:
706 rgb_matrix_custom(); 780 rgb_matrix_custom();
707 break; 781 break;
@@ -743,7 +817,7 @@ void rgb_matrix_indicators_user(void) {}
743// } 817// }
744 818
745void rgb_matrix_init(void) { 819void rgb_matrix_init(void) {
746 rgb_matrix_setup_drivers(); 820 rgb_matrix_driver.init();
747 821
748 // TODO: put the 1 second startup delay here? 822 // TODO: put the 1 second startup delay here?
749 823
@@ -767,41 +841,14 @@ void rgb_matrix_init(void) {
767 eeconfig_debug_rgb_matrix(); // display current eeprom values 841 eeconfig_debug_rgb_matrix(); // display current eeprom values
768} 842}
769 843
770void rgb_matrix_setup_drivers(void) {
771 // Initialize TWI
772 i2c_init();
773#ifdef IS31FL3731
774 IS31FL3731_init( DRIVER_ADDR_1 );
775 IS31FL3731_init( DRIVER_ADDR_2 );
776#elif defined (IS31FL3733)
777 IS31FL3733_init( DRIVER_ADDR_1 );
778#endif
779
780 for ( int index = 0; index < DRIVER_LED_TOTAL; index++ ) {
781 bool enabled = true;
782 // This only caches it for later
783#ifdef IS31FL3731
784 IS31FL3731_set_led_control_register( index, enabled, enabled, enabled );
785#elif defined (IS31FL3733)
786 IS31FL3733_set_led_control_register( index, enabled, enabled, enabled );
787#endif
788 }
789 // This actually updates the LED drivers
790#ifdef IS31FL3731
791 IS31FL3731_update_led_control_registers( DRIVER_ADDR_1, DRIVER_ADDR_2 );
792#elif defined (IS31FL3733)
793 IS31FL3733_update_led_control_registers( DRIVER_ADDR_1, DRIVER_ADDR_2 );
794#endif
795}
796
797// Deals with the messy details of incrementing an integer 844// Deals with the messy details of incrementing an integer
798uint8_t increment( uint8_t value, uint8_t step, uint8_t min, uint8_t max ) { 845static uint8_t increment( uint8_t value, uint8_t step, uint8_t min, uint8_t max ) {
799 int16_t new_value = value; 846 int16_t new_value = value;
800 new_value += step; 847 new_value += step;
801 return MIN( MAX( new_value, min ), max ); 848 return MIN( MAX( new_value, min ), max );
802} 849}
803 850
804uint8_t decrement( uint8_t value, uint8_t step, uint8_t min, uint8_t max ) { 851static uint8_t decrement( uint8_t value, uint8_t step, uint8_t min, uint8_t max ) {
805 int16_t new_value = value; 852 int16_t new_value = value;
806 new_value -= step; 853 new_value -= step;
807 return MIN( MAX( new_value, min ), max ); 854 return MIN( MAX( new_value, min ), max );
@@ -836,96 +883,109 @@ uint8_t decrement( uint8_t value, uint8_t step, uint8_t min, uint8_t max ) {
836// } 883// }
837// } 884// }
838 885
839void rgb_matrix_test_led( uint8_t index, bool red, bool green, bool blue ) {
840 for ( int i=0; i<DRIVER_LED_TOTAL; i++ )
841 {
842 if ( i == index )
843 {
844#ifdef IS31FL3731
845 IS31FL3731_set_led_control_register( i, red, green, blue );
846#elif defined (IS31FL3733)
847 IS31FL3733_set_led_control_register( i, red, green, blue );
848#endif
849 }
850 else
851 {
852#ifdef IS31FL3731
853 IS31FL3731_set_led_control_register( i, false, false, false );
854#elif defined (IS31FL3733)
855 IS31FL3733_set_led_control_register( i, false, false, false );
856#endif
857 }
858 }
859}
860
861uint32_t rgb_matrix_get_tick(void) { 886uint32_t rgb_matrix_get_tick(void) {
862 return g_tick; 887 return g_tick;
863} 888}
864 889
865void rgblight_toggle(void) { 890void rgb_matrix_toggle(void) {
866 rgb_matrix_config.enable ^= 1; 891 rgb_matrix_config.enable ^= 1;
867 eeconfig_update_rgb_matrix(rgb_matrix_config.raw); 892 eeconfig_update_rgb_matrix(rgb_matrix_config.raw);
868} 893}
869 894
870void rgblight_step(void) { 895void rgb_matrix_enable(void) {
896 rgb_matrix_config.enable = 1;
897 eeconfig_update_rgb_matrix(rgb_matrix_config.raw);
898}
899
900void rgb_matrix_enable_noeeprom(void) {
901 rgb_matrix_config.enable = 1;
902}
903
904void rgb_matrix_disable(void) {
905 rgb_matrix_config.enable = 0;
906 eeconfig_update_rgb_matrix(rgb_matrix_config.raw);
907}
908
909void rgb_matrix_disable_noeeprom(void) {
910 rgb_matrix_config.enable = 0;
911}
912
913void rgb_matrix_step(void) {
871 rgb_matrix_config.mode++; 914 rgb_matrix_config.mode++;
872 if (rgb_matrix_config.mode >= RGB_MATRIX_EFFECT_MAX) 915 if (rgb_matrix_config.mode >= RGB_MATRIX_EFFECT_MAX)
873 rgb_matrix_config.mode = 1; 916 rgb_matrix_config.mode = 1;
874 eeconfig_update_rgb_matrix(rgb_matrix_config.raw); 917 eeconfig_update_rgb_matrix(rgb_matrix_config.raw);
875} 918}
876 919
877void rgblight_step_reverse(void) { 920void rgb_matrix_step_reverse(void) {
878 rgb_matrix_config.mode--; 921 rgb_matrix_config.mode--;
879 if (rgb_matrix_config.mode < 1) 922 if (rgb_matrix_config.mode < 1)
880 rgb_matrix_config.mode = RGB_MATRIX_EFFECT_MAX - 1; 923 rgb_matrix_config.mode = RGB_MATRIX_EFFECT_MAX - 1;
881 eeconfig_update_rgb_matrix(rgb_matrix_config.raw); 924 eeconfig_update_rgb_matrix(rgb_matrix_config.raw);
882} 925}
883 926
884void rgblight_increase_hue(void) { 927void rgb_matrix_increase_hue(void) {
885 rgb_matrix_config.hue = increment( rgb_matrix_config.hue, 8, 0, 255 ); 928 rgb_matrix_config.hue = increment( rgb_matrix_config.hue, 8, 0, 255 );
886 eeconfig_update_rgb_matrix(rgb_matrix_config.raw); 929 eeconfig_update_rgb_matrix(rgb_matrix_config.raw);
887} 930}
888 931
889void rgblight_decrease_hue(void) { 932void rgb_matrix_decrease_hue(void) {
890 rgb_matrix_config.hue = decrement( rgb_matrix_config.hue, 8, 0, 255 ); 933 rgb_matrix_config.hue = decrement( rgb_matrix_config.hue, 8, 0, 255 );
891 eeconfig_update_rgb_matrix(rgb_matrix_config.raw); 934 eeconfig_update_rgb_matrix(rgb_matrix_config.raw);
892} 935}
893 936
894void rgblight_increase_sat(void) { 937void rgb_matrix_increase_sat(void) {
895 rgb_matrix_config.sat = increment( rgb_matrix_config.sat, 8, 0, 255 ); 938 rgb_matrix_config.sat = increment( rgb_matrix_config.sat, 8, 0, 255 );
896 eeconfig_update_rgb_matrix(rgb_matrix_config.raw); 939 eeconfig_update_rgb_matrix(rgb_matrix_config.raw);
897} 940}
898 941
899void rgblight_decrease_sat(void) { 942void rgb_matrix_decrease_sat(void) {
900 rgb_matrix_config.sat = decrement( rgb_matrix_config.sat, 8, 0, 255 ); 943 rgb_matrix_config.sat = decrement( rgb_matrix_config.sat, 8, 0, 255 );
901 eeconfig_update_rgb_matrix(rgb_matrix_config.raw); 944 eeconfig_update_rgb_matrix(rgb_matrix_config.raw);
902} 945}
903 946
904void rgblight_increase_val(void) { 947void rgb_matrix_increase_val(void) {
905 rgb_matrix_config.val = increment( rgb_matrix_config.val, 8, 0, RGB_MATRIX_MAXIMUM_BRIGHTNESS ); 948 rgb_matrix_config.val = increment( rgb_matrix_config.val, 8, 0, RGB_MATRIX_MAXIMUM_BRIGHTNESS );
906 eeconfig_update_rgb_matrix(rgb_matrix_config.raw); 949 eeconfig_update_rgb_matrix(rgb_matrix_config.raw);
907} 950}
908 951
909void rgblight_decrease_val(void) { 952void rgb_matrix_decrease_val(void) {
910 rgb_matrix_config.val = decrement( rgb_matrix_config.val, 8, 0, RGB_MATRIX_MAXIMUM_BRIGHTNESS ); 953 rgb_matrix_config.val = decrement( rgb_matrix_config.val, 8, 0, RGB_MATRIX_MAXIMUM_BRIGHTNESS );
911 eeconfig_update_rgb_matrix(rgb_matrix_config.raw); 954 eeconfig_update_rgb_matrix(rgb_matrix_config.raw);
912} 955}
913 956
914void rgblight_increase_speed(void) { 957void rgb_matrix_increase_speed(void) {
915 rgb_matrix_config.speed = increment( rgb_matrix_config.speed, 1, 0, 3 ); 958 rgb_matrix_config.speed = increment( rgb_matrix_config.speed, 1, 0, 3 );
916 eeconfig_update_rgb_matrix(rgb_matrix_config.raw);//EECONFIG needs to be increased to support this 959 eeconfig_update_rgb_matrix(rgb_matrix_config.raw);//EECONFIG needs to be increased to support this
917} 960}
918 961
919void rgblight_decrease_speed(void) { 962void rgb_matrix_decrease_speed(void) {
920 rgb_matrix_config.speed = decrement( rgb_matrix_config.speed, 1, 0, 3 ); 963 rgb_matrix_config.speed = decrement( rgb_matrix_config.speed, 1, 0, 3 );
921 eeconfig_update_rgb_matrix(rgb_matrix_config.raw);//EECONFIG needs to be increased to support this 964 eeconfig_update_rgb_matrix(rgb_matrix_config.raw);//EECONFIG needs to be increased to support this
922} 965}
923 966
924void rgblight_mode(uint8_t mode) { 967void rgb_matrix_mode(uint8_t mode) {
925 rgb_matrix_config.mode = mode; 968 rgb_matrix_config.mode = mode;
926 eeconfig_update_rgb_matrix(rgb_matrix_config.raw); 969 eeconfig_update_rgb_matrix(rgb_matrix_config.raw);
927} 970}
928 971
929uint32_t rgblight_get_mode(void) { 972void rgb_matrix_mode_noeeprom(uint8_t mode) {
973 rgb_matrix_config.mode = mode;
974}
975
976uint8_t rgb_matrix_get_mode(void) {
930 return rgb_matrix_config.mode; 977 return rgb_matrix_config.mode;
931} 978}
979
980void rgb_matrix_sethsv(uint16_t hue, uint8_t sat, uint8_t val) {
981 rgb_matrix_config.hue = hue;
982 rgb_matrix_config.sat = sat;
983 rgb_matrix_config.val = val;
984 eeconfig_update_rgb_matrix(rgb_matrix_config.raw);
985}
986
987void rgb_matrix_sethsv_noeeprom(uint16_t hue, uint8_t sat, uint8_t val) {
988 rgb_matrix_config.hue = hue;
989 rgb_matrix_config.sat = sat;
990 rgb_matrix_config.val = val;
991}
diff --git a/quantum/rgb_matrix.h b/quantum/rgb_matrix.h
index b91c9fba5..e43532d11 100644
--- a/quantum/rgb_matrix.h
+++ b/quantum/rgb_matrix.h
@@ -70,28 +70,64 @@ typedef union {
70 70
71enum rgb_matrix_effects { 71enum rgb_matrix_effects {
72 RGB_MATRIX_SOLID_COLOR = 1, 72 RGB_MATRIX_SOLID_COLOR = 1,
73#ifndef DISABLE_RGB_MATRIX_ALPHAS_MODS
73 RGB_MATRIX_ALPHAS_MODS, 74 RGB_MATRIX_ALPHAS_MODS,
75#endif
76#ifndef DISABLE_RGB_MATRIX_DUAL_BEACON
74 RGB_MATRIX_DUAL_BEACON, 77 RGB_MATRIX_DUAL_BEACON,
78#endif
79#ifndef DISABLE_RGB_MATRIX_GRADIENT_UP_DOWN
75 RGB_MATRIX_GRADIENT_UP_DOWN, 80 RGB_MATRIX_GRADIENT_UP_DOWN,
81#endif
82#ifndef DISABLE_RGB_MATRIX_RAINDROPS
76 RGB_MATRIX_RAINDROPS, 83 RGB_MATRIX_RAINDROPS,
84#endif
85#ifndef DISABLE_RGB_MATRIX_CYCLE_ALL
77 RGB_MATRIX_CYCLE_ALL, 86 RGB_MATRIX_CYCLE_ALL,
87#endif
88#ifndef DISABLE_RGB_MATRIX_CYCLE_LEFT_RIGHT
78 RGB_MATRIX_CYCLE_LEFT_RIGHT, 89 RGB_MATRIX_CYCLE_LEFT_RIGHT,
90#endif
91#ifndef DISABLE_RGB_MATRIX_CYCLE_UP_DOWN
79 RGB_MATRIX_CYCLE_UP_DOWN, 92 RGB_MATRIX_CYCLE_UP_DOWN,
93#endif
94#ifndef DISABLE_RGB_MATRIX_RAINBOW_BEACON
80 RGB_MATRIX_RAINBOW_BEACON, 95 RGB_MATRIX_RAINBOW_BEACON,
96#endif
97#ifndef DISABLE_RGB_MATRIX_RAINBOW_PINWHEELS
81 RGB_MATRIX_RAINBOW_PINWHEELS, 98 RGB_MATRIX_RAINBOW_PINWHEELS,
99#endif
100#ifndef DISABLE_RGB_MATRIX_RAINBOW_MOVING_CHEVRON
82 RGB_MATRIX_RAINBOW_MOVING_CHEVRON, 101 RGB_MATRIX_RAINBOW_MOVING_CHEVRON,
102#endif
103#ifndef DISABLE_RGB_MATRIX_JELLYBEAN_RAINDROPS
83 RGB_MATRIX_JELLYBEAN_RAINDROPS, 104 RGB_MATRIX_JELLYBEAN_RAINDROPS,
105#endif
106#ifndef DISABLE_RGB_MATRIX_DIGITAL_RAIN
107 RGB_MATRIX_DIGITAL_RAIN,
108#endif
84#ifdef RGB_MATRIX_KEYPRESSES 109#ifdef RGB_MATRIX_KEYPRESSES
85 RGB_MATRIX_SOLID_REACTIVE, 110 #ifndef DISABLE_RGB_MATRIX_SOLID_REACTIVE
86 RGB_MATRIX_SPLASH, 111 RGB_MATRIX_SOLID_REACTIVE,
87 RGB_MATRIX_MULTISPLASH, 112 #endif
88 RGB_MATRIX_SOLID_SPLASH, 113 #ifndef DISABLE_RGB_MATRIX_SPLASH
89 RGB_MATRIX_SOLID_MULTISPLASH, 114 RGB_MATRIX_SPLASH,
115 #endif
116 #ifndef DISABLE_RGB_MATRIX_MULTISPLASH
117 RGB_MATRIX_MULTISPLASH,
118 #endif
119 #ifndef DISABLE_RGB_MATRIX_SOLID_SPLASH
120 RGB_MATRIX_SOLID_SPLASH,
121 #endif
122 #ifndef DISABLE_RGB_MATRIX_SOLID_MULTISPLASH
123 RGB_MATRIX_SOLID_MULTISPLASH,
124 #endif
90#endif 125#endif
91 RGB_MATRIX_EFFECT_MAX 126 RGB_MATRIX_EFFECT_MAX
92}; 127};
93 128
94void rgb_matrix_set_color( int index, uint8_t red, uint8_t green, uint8_t blue ); 129void rgb_matrix_set_color( int index, uint8_t red, uint8_t green, uint8_t blue );
130void rgb_matrix_set_color_all( uint8_t red, uint8_t green, uint8_t blue );
95 131
96// This runs after another backlight effect and replaces 132// This runs after another backlight effect and replaces
97// colors already set 133// colors already set
@@ -99,8 +135,6 @@ void rgb_matrix_indicators(void);
99void rgb_matrix_indicators_kb(void); 135void rgb_matrix_indicators_kb(void);
100void rgb_matrix_indicators_user(void); 136void rgb_matrix_indicators_user(void);
101 137
102void rgb_matrix_single_LED_test(void);
103
104void rgb_matrix_init(void); 138void rgb_matrix_init(void);
105void rgb_matrix_setup_drivers(void); 139void rgb_matrix_setup_drivers(void);
106 140
@@ -125,21 +159,65 @@ void rgb_matrix_decrease(void);
125// void backlight_get_key_color( uint8_t led, HSV *hsv ); 159// void backlight_get_key_color( uint8_t led, HSV *hsv );
126// void backlight_set_key_color( uint8_t row, uint8_t column, HSV hsv ); 160// void backlight_set_key_color( uint8_t row, uint8_t column, HSV hsv );
127 161
128void rgb_matrix_test_led( uint8_t index, bool red, bool green, bool blue );
129uint32_t rgb_matrix_get_tick(void); 162uint32_t rgb_matrix_get_tick(void);
130 163
131void rgblight_toggle(void); 164void rgb_matrix_toggle(void);
132void rgblight_step(void); 165void rgb_matrix_enable(void);
133void rgblight_step_reverse(void); 166void rgb_matrix_enable_noeeprom(void);
134void rgblight_increase_hue(void); 167void rgb_matrix_disable(void);
135void rgblight_decrease_hue(void); 168void rgb_matrix_disable_noeeprom(void);
136void rgblight_increase_sat(void); 169void rgb_matrix_step(void);
137void rgblight_decrease_sat(void); 170void rgb_matrix_sethsv(uint16_t hue, uint8_t sat, uint8_t val);
138void rgblight_increase_val(void); 171void rgb_matrix_sethsv_noeeprom(uint16_t hue, uint8_t sat, uint8_t val);
139void rgblight_decrease_val(void); 172void rgb_matrix_step_reverse(void);
140void rgblight_increase_speed(void); 173void rgb_matrix_increase_hue(void);
141void rgblight_decrease_speed(void); 174void rgb_matrix_decrease_hue(void);
142void rgblight_mode(uint8_t mode); 175void rgb_matrix_increase_sat(void);
143uint32_t rgblight_get_mode(void); 176void rgb_matrix_decrease_sat(void);
177void rgb_matrix_increase_val(void);
178void rgb_matrix_decrease_val(void);
179void rgb_matrix_increase_speed(void);
180void rgb_matrix_decrease_speed(void);
181void rgb_matrix_mode(uint8_t mode);
182void rgb_matrix_mode_noeeprom(uint8_t mode);
183uint8_t rgb_matrix_get_mode(void);
184
185#ifndef RGBLIGHT_ENABLE
186#define rgblight_toggle() rgb_matrix_toggle()
187#define rgblight_enable() rgb_matrix_enable()
188#define rgblight_enable_noeeprom() rgb_matrix_enable_noeeprom()
189#define rgblight_disable() rgb_matrix_disable()
190#define rgblight_disable_noeeprom() rgb_matrix_disable_noeeprom()
191#define rgblight_step() rgb_matrix_step()
192#define rgblight_sethsv(hue, sat, val) rgb_matrix_sethsv(hue, sat, val)
193#define rgblight_sethsv_noeeprom(hue, sat, val) rgb_matrix_sethsv_noeeprom(hue, sat, val)
194#define rgblight_step_reverse() rgb_matrix_step_reverse()
195#define rgblight_increase_hue() rgb_matrix_increase_hue()
196#define rgblight_decrease_hue() rgb_matrix_decrease_hue()
197#define rgblight_increase_sat() rgb_matrix_increase_sat()
198#define rgblight_decrease_sat() rgb_matrix_decrease_sat()
199#define rgblight_increase_val() rgb_matrix_increase_val()
200#define rgblight_decrease_val() rgb_matrix_decrease_val()
201#define rgblight_increase_speed() rgb_matrix_increase_speed()
202#define rgblight_decrease_speed() rgb_matrix_decrease_speed()
203#define rgblight_mode(mode) rgb_matrix_mode(mode)
204#define rgblight_mode_noeeprom(mode) rgb_matrix_mode_noeeprom(mode)
205#define rgblight_get_mode() rgb_matrix_get_mode()
206
207#endif
208
209typedef struct {
210 /* Perform any initialisation required for the other driver functions to work. */
211 void (*init)(void);
212
213 /* Set the colour of a single LED in the buffer. */
214 void (*set_color)(int index, uint8_t r, uint8_t g, uint8_t b);
215 /* Set the colour of all LEDS on the keyboard in the buffer. */
216 void (*set_color_all)(uint8_t r, uint8_t g, uint8_t b);
217 /* Flush any buffered changes to the hardware. */
218 void (*flush)(void);
219} rgb_matrix_driver_t;
220
221extern const rgb_matrix_driver_t rgb_matrix_driver;
144 222
145#endif 223#endif
diff --git a/quantum/rgb_matrix_drivers.c b/quantum/rgb_matrix_drivers.c
new file mode 100644
index 000000000..70b80293d
--- /dev/null
+++ b/quantum/rgb_matrix_drivers.c
@@ -0,0 +1,82 @@
1/* Copyright 2018 James Laird-Wah
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 "rgb_matrix.h"
18
19/* Each driver needs to define the struct
20 * const rgb_matrix_driver_t rgb_matrix_driver;
21 * All members must be provided.
22 * Keyboard custom drivers can define this in their own files, it should only
23 * be here if shared between boards.
24 */
25
26#if defined(IS31FL3731) || defined(IS31FL3733)
27
28#include "i2c_master.h"
29
30static void init( void )
31{
32 i2c_init();
33#ifdef IS31FL3731
34 IS31FL3731_init( DRIVER_ADDR_1 );
35 IS31FL3731_init( DRIVER_ADDR_2 );
36#else
37 IS31FL3733_init( DRIVER_ADDR_1 );
38#endif
39 for ( int index = 0; index < DRIVER_LED_TOTAL; index++ ) {
40 bool enabled = true;
41 // This only caches it for later
42#ifdef IS31FL3731
43 IS31FL3731_set_led_control_register( index, enabled, enabled, enabled );
44#else
45 IS31FL3733_set_led_control_register( index, enabled, enabled, enabled );
46#endif
47 }
48 // This actually updates the LED drivers
49#ifdef IS31FL3731
50 IS31FL3731_update_led_control_registers( DRIVER_ADDR_1, DRIVER_ADDR_2 );
51#else
52 IS31FL3733_update_led_control_registers( DRIVER_ADDR_1, DRIVER_ADDR_2 );
53#endif
54}
55
56#ifdef IS31FL3731
57static void flush( void )
58{
59 IS31FL3731_update_pwm_buffers( DRIVER_ADDR_1, DRIVER_ADDR_2 );
60}
61
62const rgb_matrix_driver_t rgb_matrix_driver = {
63 .init = init,
64 .flush = flush,
65 .set_color = IS31FL3731_set_color,
66 .set_color_all = IS31FL3731_set_color_all,
67};
68#else
69static void flush( void )
70{
71 IS31FL3733_update_pwm_buffers( DRIVER_ADDR_1, DRIVER_ADDR_2 );
72}
73
74const rgb_matrix_driver_t rgb_matrix_driver = {
75 .init = init,
76 .flush = flush,
77 .set_color = IS31FL3733_set_color,
78 .set_color_all = IS31FL3733_set_color_all,
79};
80#endif
81
82#endif
diff --git a/quantum/rgblight.c b/quantum/rgblight.c
index 4919ae4ab..23420ddd8 100644
--- a/quantum/rgblight.c
+++ b/quantum/rgblight.c
@@ -14,6 +14,7 @@
14 * along with this program. If not, see <http://www.gnu.org/licenses/>. 14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */ 15 */
16#include <math.h> 16#include <math.h>
17#include <string.h>
17#ifdef __AVR__ 18#ifdef __AVR__
18 #include <avr/eeprom.h> 19 #include <avr/eeprom.h>
19 #include <avr/interrupt.h> 20 #include <avr/interrupt.h>
@@ -29,23 +30,27 @@
29#define RGBLIGHT_LIMIT_VAL 255 30#define RGBLIGHT_LIMIT_VAL 255
30#endif 31#endif
31 32
33#define _RGBM_SINGLE_STATIC(sym) RGBLIGHT_MODE_ ## sym,
34#define _RGBM_SINGLE_DYNAMIC(sym)
35#define _RGBM_MULTI_STATIC(sym) RGBLIGHT_MODE_ ## sym,
36#define _RGBM_MULTI_DYNAMIC(sym)
37#define _RGBM_TMP_STATIC(sym) RGBLIGHT_MODE_ ## sym,
38#define _RGBM_TMP_DYNAMIC(sym)
39static uint8_t static_effect_table [] = {
40#include "rgblight.h"
41};
42
43static inline int is_static_effect(uint8_t mode) {
44 return memchr(static_effect_table, mode, sizeof(static_effect_table)) != NULL;
45}
46
32#define MIN(a,b) (((a)<(b))?(a):(b)) 47#define MIN(a,b) (((a)<(b))?(a):(b))
33#define MAX(a,b) (((a)>(b))?(a):(b)) 48#define MAX(a,b) (((a)>(b))?(a):(b))
34 49
35__attribute__ ((weak)) 50#ifdef RGBLIGHT_EFFECT_STATIC_GRADIENT
36const uint8_t RGBLED_BREATHING_INTERVALS[] PROGMEM = {30, 20, 10, 5};
37__attribute__ ((weak))
38const uint8_t RGBLED_RAINBOW_MOOD_INTERVALS[] PROGMEM = {120, 60, 30};
39__attribute__ ((weak))
40const uint8_t RGBLED_RAINBOW_SWIRL_INTERVALS[] PROGMEM = {100, 50, 20};
41__attribute__ ((weak))
42const uint8_t RGBLED_SNAKE_INTERVALS[] PROGMEM = {100, 50, 20};
43__attribute__ ((weak))
44const uint8_t RGBLED_KNIGHT_INTERVALS[] PROGMEM = {127, 63, 31};
45__attribute__ ((weak)) 51__attribute__ ((weak))
46const uint16_t RGBLED_GRADIENT_RANGES[] PROGMEM = {360, 240, 180, 120, 90}; 52const uint16_t RGBLED_GRADIENT_RANGES[] PROGMEM = {360, 240, 180, 120, 90};
47__attribute__ ((weak)) 53#endif
48const uint16_t RGBLED_RGBTEST_INTERVALS[] PROGMEM = {1024};
49 54
50rgblight_config_t rgblight_config; 55rgblight_config_t rgblight_config;
51 56
@@ -129,7 +134,7 @@ void eeconfig_update_rgblight(uint32_t val) {
129void eeconfig_update_rgblight_default(void) { 134void eeconfig_update_rgblight_default(void) {
130 //dprintf("eeconfig_update_rgblight_default\n"); 135 //dprintf("eeconfig_update_rgblight_default\n");
131 rgblight_config.enable = 1; 136 rgblight_config.enable = 1;
132 rgblight_config.mode = 1; 137 rgblight_config.mode = RGBLIGHT_MODE_STATIC_LIGHT;
133 rgblight_config.hue = 0; 138 rgblight_config.hue = 0;
134 rgblight_config.sat = 255; 139 rgblight_config.sat = 255;
135 rgblight_config.val = RGBLIGHT_LIMIT_VAL; 140 rgblight_config.val = RGBLIGHT_LIMIT_VAL;
@@ -163,9 +168,9 @@ void rgblight_init(void) {
163 } 168 }
164 eeconfig_debug_rgblight(); // display current eeprom values 169 eeconfig_debug_rgblight(); // display current eeprom values
165 170
166 #ifdef RGBLIGHT_ANIMATIONS 171#ifdef RGBLIGHT_USE_TIMER
167 rgblight_timer_init(); // setup the timer 172 rgblight_timer_init(); // setup the timer
168 #endif 173#endif
169 174
170 if (rgblight_config.enable) { 175 if (rgblight_config.enable) {
171 rgblight_mode_noeeprom(rgblight_config.mode); 176 rgblight_mode_noeeprom(rgblight_config.mode);
@@ -178,9 +183,9 @@ void rgblight_update_dword(uint32_t dword) {
178 if (rgblight_config.enable) 183 if (rgblight_config.enable)
179 rgblight_mode(rgblight_config.mode); 184 rgblight_mode(rgblight_config.mode);
180 else { 185 else {
181 #ifdef RGBLIGHT_ANIMATIONS 186#ifdef RGBLIGHT_USE_TIMER
182 rgblight_timer_disable(); 187 rgblight_timer_disable();
183 #endif 188#endif
184 rgblight_set(); 189 rgblight_set();
185 } 190 }
186} 191}
@@ -195,29 +200,41 @@ void rgblight_increase(void) {
195void rgblight_decrease(void) { 200void rgblight_decrease(void) {
196 uint8_t mode = 0; 201 uint8_t mode = 0;
197 // Mode will never be < 1. If it ever is, eeprom needs to be initialized. 202 // Mode will never be < 1. If it ever is, eeprom needs to be initialized.
198 if (rgblight_config.mode > 1) { 203 if (rgblight_config.mode > RGBLIGHT_MODE_STATIC_LIGHT) {
199 mode = rgblight_config.mode - 1; 204 mode = rgblight_config.mode - 1;
200 } 205 }
201 rgblight_mode(mode); 206 rgblight_mode(mode);
202} 207}
203void rgblight_step(void) { 208void rgblight_step_helper(bool write_to_eeprom) {
204 uint8_t mode = 0; 209 uint8_t mode = 0;
205 mode = rgblight_config.mode + 1; 210 mode = rgblight_config.mode + 1;
206 if (mode > RGBLIGHT_MODES) { 211 if (mode > RGBLIGHT_MODES) {
207 mode = 1; 212 mode = 1;
208 } 213 }
209 rgblight_mode(mode); 214 rgblight_mode_eeprom_helper(mode, write_to_eeprom);
210} 215}
211void rgblight_step_reverse(void) { 216void rgblight_step_noeeprom(void) {
217 rgblight_step_helper(false);
218}
219void rgblight_step(void) {
220 rgblight_step_helper(true);
221}
222void rgblight_step_reverse_helper(bool write_to_eeprom) {
212 uint8_t mode = 0; 223 uint8_t mode = 0;
213 mode = rgblight_config.mode - 1; 224 mode = rgblight_config.mode - 1;
214 if (mode < 1) { 225 if (mode < 1) {
215 mode = RGBLIGHT_MODES; 226 mode = RGBLIGHT_MODES;
216 } 227 }
217 rgblight_mode(mode); 228 rgblight_mode_eeprom_helper(mode, write_to_eeprom);
229}
230void rgblight_step_reverse_noeeprom(void) {
231 rgblight_step_reverse_helper(false);
232}
233void rgblight_step_reverse(void) {
234 rgblight_step_reverse_helper(true);
218} 235}
219 236
220uint32_t rgblight_get_mode(void) { 237uint8_t rgblight_get_mode(void) {
221 if (!rgblight_config.enable) { 238 if (!rgblight_config.enable) {
222 return false; 239 return false;
223 } 240 }
@@ -229,8 +246,8 @@ void rgblight_mode_eeprom_helper(uint8_t mode, bool write_to_eeprom) {
229 if (!rgblight_config.enable) { 246 if (!rgblight_config.enable) {
230 return; 247 return;
231 } 248 }
232 if (mode < 1) { 249 if (mode < RGBLIGHT_MODE_STATIC_LIGHT) {
233 rgblight_config.mode = 1; 250 rgblight_config.mode = RGBLIGHT_MODE_STATIC_LIGHT;
234 } else if (mode > RGBLIGHT_MODES) { 251 } else if (mode > RGBLIGHT_MODES) {
235 rgblight_config.mode = RGBLIGHT_MODES; 252 rgblight_config.mode = RGBLIGHT_MODES;
236 } else { 253 } else {
@@ -242,30 +259,14 @@ void rgblight_mode_eeprom_helper(uint8_t mode, bool write_to_eeprom) {
242 } else { 259 } else {
243 xprintf("rgblight mode [NOEEPROM]: %u\n", rgblight_config.mode); 260 xprintf("rgblight mode [NOEEPROM]: %u\n", rgblight_config.mode);
244 } 261 }
245 if (rgblight_config.mode == 1) { 262 if( is_static_effect(rgblight_config.mode) ) {
246 #ifdef RGBLIGHT_ANIMATIONS 263#ifdef RGBLIGHT_USE_TIMER
247 rgblight_timer_disable(); 264 rgblight_timer_disable();
248 #endif 265#endif
249 } else if ((rgblight_config.mode >= 2 && rgblight_config.mode <= 24) || 266 } else {
250 rgblight_config.mode == 35 || rgblight_config.mode == 36) { 267#ifdef RGBLIGHT_USE_TIMER
251 // MODE 2-5, breathing
252 // MODE 6-8, rainbow mood
253 // MODE 9-14, rainbow swirl
254 // MODE 15-20, snake
255 // MODE 21-23, knight
256 // MODE 24, xmas
257 // MODE 35 RGB test
258 // MODE 36, alterating
259
260 #ifdef RGBLIGHT_ANIMATIONS
261 rgblight_timer_enable(); 268 rgblight_timer_enable();
262 #endif 269#endif
263 } else if (rgblight_config.mode >= 25 && rgblight_config.mode <= 34) {
264 // MODE 25-34, static gradient
265
266 #ifdef RGBLIGHT_ANIMATIONS
267 rgblight_timer_disable();
268 #endif
269 } 270 }
270 rgblight_sethsv_noeeprom(rgblight_config.hue, rgblight_config.sat, rgblight_config.val); 271 rgblight_sethsv_noeeprom(rgblight_config.hue, rgblight_config.sat, rgblight_config.val);
271} 272}
@@ -317,9 +318,9 @@ void rgblight_disable(void) {
317 rgblight_config.enable = 0; 318 rgblight_config.enable = 0;
318 eeconfig_update_rgblight(rgblight_config.raw); 319 eeconfig_update_rgblight(rgblight_config.raw);
319 xprintf("rgblight disable [EEPROM]: rgblight_config.enable = %u\n", rgblight_config.enable); 320 xprintf("rgblight disable [EEPROM]: rgblight_config.enable = %u\n", rgblight_config.enable);
320 #ifdef RGBLIGHT_ANIMATIONS 321#ifdef RGBLIGHT_USE_TIMER
321 rgblight_timer_disable(); 322 rgblight_timer_disable();
322 #endif 323#endif
323 wait_ms(50); 324 wait_ms(50);
324 rgblight_set(); 325 rgblight_set();
325} 326}
@@ -327,76 +328,112 @@ void rgblight_disable(void) {
327void rgblight_disable_noeeprom(void) { 328void rgblight_disable_noeeprom(void) {
328 rgblight_config.enable = 0; 329 rgblight_config.enable = 0;
329 xprintf("rgblight disable [noEEPROM]: rgblight_config.enable = %u\n", rgblight_config.enable); 330 xprintf("rgblight disable [noEEPROM]: rgblight_config.enable = %u\n", rgblight_config.enable);
330 #ifdef RGBLIGHT_ANIMATIONS 331#ifdef RGBLIGHT_USE_TIMER
331 rgblight_timer_disable(); 332 rgblight_timer_disable();
332 #endif 333#endif
333 _delay_ms(50); 334 _delay_ms(50);
334 rgblight_set(); 335 rgblight_set();
335} 336}
336 337
337 338
338// Deals with the messy details of incrementing an integer 339// Deals with the messy details of incrementing an integer
339uint8_t increment( uint8_t value, uint8_t step, uint8_t min, uint8_t max ) { 340static uint8_t increment( uint8_t value, uint8_t step, uint8_t min, uint8_t max ) {
340 int16_t new_value = value; 341 int16_t new_value = value;
341 new_value += step; 342 new_value += step;
342 return MIN( MAX( new_value, min ), max ); 343 return MIN( MAX( new_value, min ), max );
343} 344}
344 345
345uint8_t decrement( uint8_t value, uint8_t step, uint8_t min, uint8_t max ) { 346static uint8_t decrement( uint8_t value, uint8_t step, uint8_t min, uint8_t max ) {
346 int16_t new_value = value; 347 int16_t new_value = value;
347 new_value -= step; 348 new_value -= step;
348 return MIN( MAX( new_value, min ), max ); 349 return MIN( MAX( new_value, min ), max );
349} 350}
350 351
351void rgblight_increase_hue(void) { 352void rgblight_increase_hue_helper(bool write_to_eeprom) {
352 uint16_t hue; 353 uint16_t hue;
353 hue = (rgblight_config.hue+RGBLIGHT_HUE_STEP) % 360; 354 hue = (rgblight_config.hue+RGBLIGHT_HUE_STEP) % 360;
354 rgblight_sethsv(hue, rgblight_config.sat, rgblight_config.val); 355 rgblight_sethsv_eeprom_helper(hue, rgblight_config.sat, rgblight_config.val, write_to_eeprom);
355} 356}
356void rgblight_decrease_hue(void) { 357void rgblight_increase_hue_noeeprom(void) {
358 rgblight_increase_hue_helper(false);
359}
360void rgblight_increase_hue(void) {
361 rgblight_increase_hue_helper(true);
362}
363void rgblight_decrease_hue_helper(bool write_to_eeprom) {
357 uint16_t hue; 364 uint16_t hue;
358 if (rgblight_config.hue-RGBLIGHT_HUE_STEP < 0) { 365 if (rgblight_config.hue-RGBLIGHT_HUE_STEP < 0) {
359 hue = (rgblight_config.hue + 360 - RGBLIGHT_HUE_STEP) % 360; 366 hue = (rgblight_config.hue + 360 - RGBLIGHT_HUE_STEP) % 360;
360 } else { 367 } else {
361 hue = (rgblight_config.hue - RGBLIGHT_HUE_STEP) % 360; 368 hue = (rgblight_config.hue - RGBLIGHT_HUE_STEP) % 360;
362 } 369 }
363 rgblight_sethsv(hue, rgblight_config.sat, rgblight_config.val); 370 rgblight_sethsv_eeprom_helper(hue, rgblight_config.sat, rgblight_config.val, write_to_eeprom);
364} 371}
365void rgblight_increase_sat(void) { 372void rgblight_decrease_hue_noeeprom(void) {
373 rgblight_decrease_hue_helper(false);
374}
375void rgblight_decrease_hue(void) {
376 rgblight_decrease_hue_helper(true);
377}
378void rgblight_increase_sat_helper(bool write_to_eeprom) {
366 uint8_t sat; 379 uint8_t sat;
367 if (rgblight_config.sat + RGBLIGHT_SAT_STEP > 255) { 380 if (rgblight_config.sat + RGBLIGHT_SAT_STEP > 255) {
368 sat = 255; 381 sat = 255;
369 } else { 382 } else {
370 sat = rgblight_config.sat + RGBLIGHT_SAT_STEP; 383 sat = rgblight_config.sat + RGBLIGHT_SAT_STEP;
371 } 384 }
372 rgblight_sethsv(rgblight_config.hue, sat, rgblight_config.val); 385 rgblight_sethsv_eeprom_helper(rgblight_config.hue, sat, rgblight_config.val, write_to_eeprom);
373} 386}
374void rgblight_decrease_sat(void) { 387void rgblight_increase_sat_noeeprom(void) {
388 rgblight_increase_sat_helper(false);
389}
390void rgblight_increase_sat(void) {
391 rgblight_increase_sat_helper(true);
392}
393void rgblight_decrease_sat_helper(bool write_to_eeprom) {
375 uint8_t sat; 394 uint8_t sat;
376 if (rgblight_config.sat - RGBLIGHT_SAT_STEP < 0) { 395 if (rgblight_config.sat - RGBLIGHT_SAT_STEP < 0) {
377 sat = 0; 396 sat = 0;
378 } else { 397 } else {
379 sat = rgblight_config.sat - RGBLIGHT_SAT_STEP; 398 sat = rgblight_config.sat - RGBLIGHT_SAT_STEP;
380 } 399 }
381 rgblight_sethsv(rgblight_config.hue, sat, rgblight_config.val); 400 rgblight_sethsv_eeprom_helper(rgblight_config.hue, sat, rgblight_config.val, write_to_eeprom);
382} 401}
383void rgblight_increase_val(void) { 402void rgblight_decrease_sat_noeeprom(void) {
403 rgblight_decrease_sat_helper(false);
404}
405void rgblight_decrease_sat(void) {
406 rgblight_decrease_sat_helper(true);
407}
408void rgblight_increase_val_helper(bool write_to_eeprom) {
384 uint8_t val; 409 uint8_t val;
385 if (rgblight_config.val + RGBLIGHT_VAL_STEP > RGBLIGHT_LIMIT_VAL) { 410 if (rgblight_config.val + RGBLIGHT_VAL_STEP > RGBLIGHT_LIMIT_VAL) {
386 val = RGBLIGHT_LIMIT_VAL; 411 val = RGBLIGHT_LIMIT_VAL;
387 } else { 412 } else {
388 val = rgblight_config.val + RGBLIGHT_VAL_STEP; 413 val = rgblight_config.val + RGBLIGHT_VAL_STEP;
389 } 414 }
390 rgblight_sethsv(rgblight_config.hue, rgblight_config.sat, val); 415 rgblight_sethsv_eeprom_helper(rgblight_config.hue, rgblight_config.sat, val, write_to_eeprom);
391} 416}
392void rgblight_decrease_val(void) { 417void rgblight_increase_val_noeeprom(void) {
418 rgblight_increase_val_helper(false);
419}
420void rgblight_increase_val(void) {
421 rgblight_increase_val_helper(true);
422}
423void rgblight_decrease_val_helper(bool write_to_eeprom) {
393 uint8_t val; 424 uint8_t val;
394 if (rgblight_config.val - RGBLIGHT_VAL_STEP < 0) { 425 if (rgblight_config.val - RGBLIGHT_VAL_STEP < 0) {
395 val = 0; 426 val = 0;
396 } else { 427 } else {
397 val = rgblight_config.val - RGBLIGHT_VAL_STEP; 428 val = rgblight_config.val - RGBLIGHT_VAL_STEP;
398 } 429 }
399 rgblight_sethsv(rgblight_config.hue, rgblight_config.sat, val); 430 rgblight_sethsv_eeprom_helper(rgblight_config.hue, rgblight_config.sat, val, write_to_eeprom);
431}
432void rgblight_decrease_val_noeeprom(void) {
433 rgblight_decrease_val_helper(false);
434}
435void rgblight_decrease_val(void) {
436 rgblight_decrease_val_helper(true);
400} 437}
401void rgblight_increase_speed(void) { 438void rgblight_increase_speed(void) {
402 rgblight_config.speed = increment( rgblight_config.speed, 1, 0, 3 ); 439 rgblight_config.speed = increment( rgblight_config.speed, 1, 0, 3 );
@@ -419,24 +456,43 @@ void rgblight_sethsv_noeeprom_old(uint16_t hue, uint8_t sat, uint8_t val) {
419 456
420void rgblight_sethsv_eeprom_helper(uint16_t hue, uint8_t sat, uint8_t val, bool write_to_eeprom) { 457void rgblight_sethsv_eeprom_helper(uint16_t hue, uint8_t sat, uint8_t val, bool write_to_eeprom) {
421 if (rgblight_config.enable) { 458 if (rgblight_config.enable) {
422 if (rgblight_config.mode == 1) { 459 if (rgblight_config.mode == RGBLIGHT_MODE_STATIC_LIGHT) {
423 // same static color 460 // same static color
424 LED_TYPE tmp_led; 461 LED_TYPE tmp_led;
425 sethsv(hue, sat, val, &tmp_led); 462 sethsv(hue, sat, val, &tmp_led);
426 rgblight_setrgb(tmp_led.r, tmp_led.g, tmp_led.b); 463 rgblight_setrgb(tmp_led.r, tmp_led.g, tmp_led.b);
427 } else { 464 } else {
428 // all LEDs in same color 465 // all LEDs in same color
429 if (rgblight_config.mode >= 2 && rgblight_config.mode <= 5) { 466 if ( 1 == 0 ) { //dummy
467 }
468#ifdef RGBLIGHT_EFFECT_BREATHING
469 else if (rgblight_config.mode >= RGBLIGHT_MODE_BREATHING &&
470 rgblight_config.mode <= RGBLIGHT_MODE_BREATHING_end) {
430 // breathing mode, ignore the change of val, use in memory value instead 471 // breathing mode, ignore the change of val, use in memory value instead
431 val = rgblight_config.val; 472 val = rgblight_config.val;
432 } else if (rgblight_config.mode >= 6 && rgblight_config.mode <= 14) { 473 }
433 // rainbow mood and rainbow swirl, ignore the change of hue 474#endif
475#ifdef RGBLIGHT_EFFECT_RAINBOW_MOOD
476 else if (rgblight_config.mode >= RGBLIGHT_MODE_RAINBOW_MOOD &&
477 rgblight_config.mode <= RGBLIGHT_MODE_RAINBOW_MOOD_end) {
478 // rainbow mood, ignore the change of hue
434 hue = rgblight_config.hue; 479 hue = rgblight_config.hue;
435 } else if (rgblight_config.mode >= 25 && rgblight_config.mode <= 34) { 480 }
481#endif
482#ifdef RGBLIGHT_EFFECT_RAINBOW_SWIRL
483 else if (rgblight_config.mode >= RGBLIGHT_MODE_RAINBOW_SWIRL &&
484 rgblight_config.mode <= RGBLIGHT_MODE_RAINBOW_SWIRL_end) {
485 // rainbow swirl, ignore the change of hue
486 hue = rgblight_config.hue;
487 }
488#endif
489#ifdef RGBLIGHT_EFFECT_STATIC_GRADIENT
490 else if (rgblight_config.mode >= RGBLIGHT_MODE_STATIC_GRADIENT &&
491 rgblight_config.mode <= RGBLIGHT_MODE_STATIC_GRADIENT_end) {
436 // static gradient 492 // static gradient
437 uint16_t _hue; 493 uint16_t _hue;
438 int8_t direction = ((rgblight_config.mode - 25) % 2) ? -1 : 1; 494 int8_t direction = ((rgblight_config.mode - RGBLIGHT_MODE_STATIC_GRADIENT) % 2) ? -1 : 1;
439 uint16_t range = pgm_read_word(&RGBLED_GRADIENT_RANGES[(rgblight_config.mode - 25) / 2]); 495 uint16_t range = pgm_read_word(&RGBLED_GRADIENT_RANGES[(rgblight_config.mode - RGBLIGHT_MODE_STATIC_GRADIENT) / 2]);
440 for (uint8_t i = 0; i < RGBLED_NUM; i++) { 496 for (uint8_t i = 0; i < RGBLED_NUM; i++) {
441 _hue = (range / RGBLED_NUM * i * direction + hue + 360) % 360; 497 _hue = (range / RGBLED_NUM * i * direction + hue + 360) % 360;
442 dprintf("rgblight rainbow set hsv: %u,%u,%d,%u\n", i, _hue, direction, range); 498 dprintf("rgblight rainbow set hsv: %u,%u,%d,%u\n", i, _hue, direction, range);
@@ -444,6 +500,7 @@ void rgblight_sethsv_eeprom_helper(uint16_t hue, uint8_t sat, uint8_t val, bool
444 } 500 }
445 rgblight_set(); 501 rgblight_set();
446 } 502 }
503#endif
447 } 504 }
448 rgblight_config.hue = hue; 505 rgblight_config.hue = hue;
449 rgblight_config.sat = sat; 506 rgblight_config.sat = sat;
@@ -528,7 +585,7 @@ void rgblight_set(void) {
528} 585}
529#endif 586#endif
530 587
531#ifdef RGBLIGHT_ANIMATIONS 588#ifdef RGBLIGHT_USE_TIMER
532 589
533// Animation timer -- AVR Timer3 590// Animation timer -- AVR Timer3
534void rgblight_timer_init(void) { 591void rgblight_timer_init(void) {
@@ -564,41 +621,77 @@ void rgblight_timer_toggle(void) {
564 621
565void rgblight_show_solid_color(uint8_t r, uint8_t g, uint8_t b) { 622void rgblight_show_solid_color(uint8_t r, uint8_t g, uint8_t b) {
566 rgblight_enable(); 623 rgblight_enable();
567 rgblight_mode(1); 624 rgblight_mode(RGBLIGHT_MODE_STATIC_LIGHT);
568 rgblight_setrgb(r, g, b); 625 rgblight_setrgb(r, g, b);
569} 626}
570 627
571void rgblight_task(void) { 628void rgblight_task(void) {
572 if (rgblight_timer_enabled) { 629 if (rgblight_timer_enabled) {
573 // mode = 1, static light, do nothing here 630 // static light mode, do nothing here
574 if (rgblight_config.mode >= 2 && rgblight_config.mode <= 5) { 631 if ( 1 == 0 ) { //dummy
575 // mode = 2 to 5, breathing mode 632 }
576 rgblight_effect_breathing(rgblight_config.mode - 2); 633#ifdef RGBLIGHT_EFFECT_BREATHING
577 } else if (rgblight_config.mode >= 6 && rgblight_config.mode <= 8) { 634 else if (rgblight_config.mode >= RGBLIGHT_MODE_BREATHING &&
578 // mode = 6 to 8, rainbow mood mod 635 rgblight_config.mode <= RGBLIGHT_MODE_BREATHING_end) {
579 rgblight_effect_rainbow_mood(rgblight_config.mode - 6); 636 // breathing mode
580 } else if (rgblight_config.mode >= 9 && rgblight_config.mode <= 14) { 637 rgblight_effect_breathing(rgblight_config.mode - RGBLIGHT_MODE_BREATHING );
581 // mode = 9 to 14, rainbow swirl mode 638 }
582 rgblight_effect_rainbow_swirl(rgblight_config.mode - 9); 639#endif
583 } else if (rgblight_config.mode >= 15 && rgblight_config.mode <= 20) { 640#ifdef RGBLIGHT_EFFECT_RAINBOW_MOOD
584 // mode = 15 to 20, snake mode 641 else if (rgblight_config.mode >= RGBLIGHT_MODE_RAINBOW_MOOD &&
585 rgblight_effect_snake(rgblight_config.mode - 15); 642 rgblight_config.mode <= RGBLIGHT_MODE_RAINBOW_MOOD_end) {
586 } else if (rgblight_config.mode >= 21 && rgblight_config.mode <= 23) { 643 // rainbow mood mode
587 // mode = 21 to 23, knight mode 644 rgblight_effect_rainbow_mood(rgblight_config.mode - RGBLIGHT_MODE_RAINBOW_MOOD);
588 rgblight_effect_knight(rgblight_config.mode - 21); 645 }
589 } else if (rgblight_config.mode == 24) { 646#endif
590 // mode = 24, christmas mode 647#ifdef RGBLIGHT_EFFECT_RAINBOW_SWIRL
648 else if (rgblight_config.mode >= RGBLIGHT_MODE_RAINBOW_SWIRL &&
649 rgblight_config.mode <= RGBLIGHT_MODE_RAINBOW_SWIRL_end) {
650 // rainbow swirl mode
651 rgblight_effect_rainbow_swirl(rgblight_config.mode - RGBLIGHT_MODE_RAINBOW_SWIRL);
652 }
653#endif
654#ifdef RGBLIGHT_EFFECT_SNAKE
655 else if (rgblight_config.mode >= RGBLIGHT_MODE_SNAKE &&
656 rgblight_config.mode <= RGBLIGHT_MODE_SNAKE_end) {
657 // snake mode
658 rgblight_effect_snake(rgblight_config.mode - RGBLIGHT_MODE_SNAKE);
659 }
660#endif
661#ifdef RGBLIGHT_EFFECT_KNIGHT
662 else if (rgblight_config.mode >= RGBLIGHT_MODE_KNIGHT &&
663 rgblight_config.mode <= RGBLIGHT_MODE_KNIGHT_end) {
664 // knight mode
665 rgblight_effect_knight(rgblight_config.mode - RGBLIGHT_MODE_KNIGHT);
666 }
667#endif
668#ifdef RGBLIGHT_EFFECT_CHRISTMAS
669 else if (rgblight_config.mode == RGBLIGHT_MODE_CHRISTMAS) {
670 // christmas mode
591 rgblight_effect_christmas(); 671 rgblight_effect_christmas();
592 } else if (rgblight_config.mode == 35) { 672 }
593 // mode = 35, RGB test 673#endif
674#ifdef RGBLIGHT_EFFECT_RGB_TEST
675 else if (rgblight_config.mode == RGBLIGHT_MODE_RGB_TEST) {
676 // RGB test mode
594 rgblight_effect_rgbtest(); 677 rgblight_effect_rgbtest();
595 } else if (rgblight_config.mode == 36){ 678 }
679#endif
680#ifdef RGBLIGHT_EFFECT_ALTERNATING
681 else if (rgblight_config.mode == RGBLIGHT_MODE_ALTERNATING){
596 rgblight_effect_alternating(); 682 rgblight_effect_alternating();
597 } 683 }
684#endif
598 } 685 }
599} 686}
600 687
688#endif /* RGBLIGHT_USE_TIMER */
689
601// Effects 690// Effects
691#ifdef RGBLIGHT_EFFECT_BREATHING
692__attribute__ ((weak))
693const uint8_t RGBLED_BREATHING_INTERVALS[] PROGMEM = {30, 20, 10, 5};
694
602void rgblight_effect_breathing(uint8_t interval) { 695void rgblight_effect_breathing(uint8_t interval) {
603 static uint8_t pos = 0; 696 static uint8_t pos = 0;
604 static uint16_t last_timer = 0; 697 static uint16_t last_timer = 0;
@@ -609,12 +702,17 @@ void rgblight_effect_breathing(uint8_t interval) {
609 } 702 }
610 last_timer = timer_read(); 703 last_timer = timer_read();
611 704
612
613 // http://sean.voisen.org/blog/2011/10/breathing-led-with-arduino/ 705 // http://sean.voisen.org/blog/2011/10/breathing-led-with-arduino/
614 val = (exp(sin((pos/255.0)*M_PI)) - RGBLIGHT_EFFECT_BREATHE_CENTER/M_E)*(RGBLIGHT_EFFECT_BREATHE_MAX/(M_E-1/M_E)); 706 val = (exp(sin((pos/255.0)*M_PI)) - RGBLIGHT_EFFECT_BREATHE_CENTER/M_E)*(RGBLIGHT_EFFECT_BREATHE_MAX/(M_E-1/M_E));
615 rgblight_sethsv_noeeprom_old(rgblight_config.hue, rgblight_config.sat, val); 707 rgblight_sethsv_noeeprom_old(rgblight_config.hue, rgblight_config.sat, val);
616 pos = (pos + 1) % 256; 708 pos = (pos + 1) % 256;
617} 709}
710#endif
711
712#ifdef RGBLIGHT_EFFECT_RAINBOW_MOOD
713__attribute__ ((weak))
714const uint8_t RGBLED_RAINBOW_MOOD_INTERVALS[] PROGMEM = {120, 60, 30};
715
618void rgblight_effect_rainbow_mood(uint8_t interval) { 716void rgblight_effect_rainbow_mood(uint8_t interval) {
619 static uint16_t current_hue = 0; 717 static uint16_t current_hue = 0;
620 static uint16_t last_timer = 0; 718 static uint16_t last_timer = 0;
@@ -626,6 +724,16 @@ void rgblight_effect_rainbow_mood(uint8_t interval) {
626 rgblight_sethsv_noeeprom_old(current_hue, rgblight_config.sat, rgblight_config.val); 724 rgblight_sethsv_noeeprom_old(current_hue, rgblight_config.sat, rgblight_config.val);
627 current_hue = (current_hue + 1) % 360; 725 current_hue = (current_hue + 1) % 360;
628} 726}
727#endif
728
729#ifdef RGBLIGHT_EFFECT_RAINBOW_SWIRL
730#ifndef RGBLIGHT_RAINBOW_SWIRL_RANGE
731 #define RGBLIGHT_RAINBOW_SWIRL_RANGE 360
732#endif
733
734__attribute__ ((weak))
735const uint8_t RGBLED_RAINBOW_SWIRL_INTERVALS[] PROGMEM = {100, 50, 20};
736
629void rgblight_effect_rainbow_swirl(uint8_t interval) { 737void rgblight_effect_rainbow_swirl(uint8_t interval) {
630 static uint16_t current_hue = 0; 738 static uint16_t current_hue = 0;
631 static uint16_t last_timer = 0; 739 static uint16_t last_timer = 0;
@@ -636,7 +744,7 @@ void rgblight_effect_rainbow_swirl(uint8_t interval) {
636 } 744 }
637 last_timer = timer_read(); 745 last_timer = timer_read();
638 for (i = 0; i < RGBLED_NUM; i++) { 746 for (i = 0; i < RGBLED_NUM; i++) {
639 hue = (360 / RGBLED_NUM * i + current_hue) % 360; 747 hue = (RGBLIGHT_RAINBOW_SWIRL_RANGE / RGBLED_NUM * i + current_hue) % 360;
640 sethsv(hue, rgblight_config.sat, rgblight_config.val, (LED_TYPE *)&led[i]); 748 sethsv(hue, rgblight_config.sat, rgblight_config.val, (LED_TYPE *)&led[i]);
641 } 749 }
642 rgblight_set(); 750 rgblight_set();
@@ -651,6 +759,12 @@ void rgblight_effect_rainbow_swirl(uint8_t interval) {
651 } 759 }
652 } 760 }
653} 761}
762#endif
763
764#ifdef RGBLIGHT_EFFECT_SNAKE
765__attribute__ ((weak))
766const uint8_t RGBLED_SNAKE_INTERVALS[] PROGMEM = {100, 50, 20};
767
654void rgblight_effect_snake(uint8_t interval) { 768void rgblight_effect_snake(uint8_t interval) {
655 static uint8_t pos = 0; 769 static uint8_t pos = 0;
656 static uint16_t last_timer = 0; 770 static uint16_t last_timer = 0;
@@ -689,6 +803,12 @@ void rgblight_effect_snake(uint8_t interval) {
689 pos = (pos + 1) % RGBLED_NUM; 803 pos = (pos + 1) % RGBLED_NUM;
690 } 804 }
691} 805}
806#endif
807
808#ifdef RGBLIGHT_EFFECT_KNIGHT
809__attribute__ ((weak))
810const uint8_t RGBLED_KNIGHT_INTERVALS[] PROGMEM = {127, 63, 31};
811
692void rgblight_effect_knight(uint8_t interval) { 812void rgblight_effect_knight(uint8_t interval) {
693 static uint16_t last_timer = 0; 813 static uint16_t last_timer = 0;
694 if (timer_elapsed(last_timer) < pgm_read_byte(&RGBLED_KNIGHT_INTERVALS[interval])) { 814 if (timer_elapsed(last_timer) < pgm_read_byte(&RGBLED_KNIGHT_INTERVALS[interval])) {
@@ -730,8 +850,9 @@ void rgblight_effect_knight(uint8_t interval) {
730 increment = -increment; 850 increment = -increment;
731 } 851 }
732} 852}
853#endif
733 854
734 855#ifdef RGBLIGHT_EFFECT_CHRISTMAS
735void rgblight_effect_christmas(void) { 856void rgblight_effect_christmas(void) {
736 static uint16_t current_offset = 0; 857 static uint16_t current_offset = 0;
737 static uint16_t last_timer = 0; 858 static uint16_t last_timer = 0;
@@ -748,6 +869,11 @@ void rgblight_effect_christmas(void) {
748 } 869 }
749 rgblight_set(); 870 rgblight_set();
750} 871}
872#endif
873
874#ifdef RGBLIGHT_EFFECT_RGB_TEST
875__attribute__ ((weak))
876const uint16_t RGBLED_RGBTEST_INTERVALS[] PROGMEM = {1024};
751 877
752void rgblight_effect_rgbtest(void) { 878void rgblight_effect_rgbtest(void) {
753 static uint8_t pos = 0; 879 static uint8_t pos = 0;
@@ -774,7 +900,9 @@ void rgblight_effect_rgbtest(void) {
774 rgblight_setrgb(r, g, b); 900 rgblight_setrgb(r, g, b);
775 pos = (pos + 1) % 3; 901 pos = (pos + 1) % 3;
776} 902}
903#endif
777 904
905#ifdef RGBLIGHT_EFFECT_ALTERNATING
778void rgblight_effect_alternating(void){ 906void rgblight_effect_alternating(void){
779 static uint16_t last_timer = 0; 907 static uint16_t last_timer = 0;
780 static uint16_t pos = 0; 908 static uint16_t pos = 0;
@@ -784,16 +912,15 @@ void rgblight_effect_alternating(void){
784 last_timer = timer_read(); 912 last_timer = timer_read();
785 913
786 for(int i = 0; i<RGBLED_NUM; i++){ 914 for(int i = 0; i<RGBLED_NUM; i++){
787 if(i<RGBLED_NUM/2 && pos){ 915 if(i<RGBLED_NUM/2 && pos){
788 rgblight_sethsv_at(rgblight_config.hue, rgblight_config.sat, rgblight_config.val, i); 916 sethsv(rgblight_config.hue, rgblight_config.sat, rgblight_config.val, (LED_TYPE *)&led[i]);
789 }else if (i>=RGBLED_NUM/2 && !pos){ 917 }else if (i>=RGBLED_NUM/2 && !pos){
790 rgblight_sethsv_at(rgblight_config.hue, rgblight_config.sat, rgblight_config.val, i); 918 sethsv(rgblight_config.hue, rgblight_config.sat, rgblight_config.val, (LED_TYPE *)&led[i]);
791 }else{ 919 }else{
792 rgblight_sethsv_at(rgblight_config.hue, rgblight_config.sat, 0, i); 920 sethsv(rgblight_config.hue, rgblight_config.sat, 0, (LED_TYPE *)&led[i]);
793 } 921 }
794 } 922 }
795 rgblight_set(); 923 rgblight_set();
796 pos = (pos + 1) % 2; 924 pos = (pos + 1) % 2;
797} 925}
798 926#endif
799#endif /* RGBLIGHT_ANIMATIONS */
diff --git a/quantum/rgblight.h b/quantum/rgblight.h
index ba010dfae..65dda3f52 100644
--- a/quantum/rgblight.h
+++ b/quantum/rgblight.h
@@ -16,11 +16,69 @@
16#ifndef RGBLIGHT_H 16#ifndef RGBLIGHT_H
17#define RGBLIGHT_H 17#define RGBLIGHT_H
18 18
19#ifdef RGBLIGHT_ANIMATIONS 19#include "rgblight_reconfig.h"
20 #define RGBLIGHT_MODES 36 20
21#else 21/***** rgblight_mode(mode)/rgblight_mode_noeeprom(mode) ****
22 #define RGBLIGHT_MODES 1 22
23#endif 23 old mode number (before 0.6.117) to new mode name table
24
25|-----------------|-----------------------------------|
26| old mode number | new mode name |
27|-----------------|-----------------------------------|
28| 1 | RGBLIGHT_MODE_STATIC_LIGHT |
29| 2 | RGBLIGHT_MODE_BREATHING |
30| 3 | RGBLIGHT_MODE_BREATHING + 1 |
31| 4 | RGBLIGHT_MODE_BREATHING + 2 |
32| 5 | RGBLIGHT_MODE_BREATHING + 3 |
33| 6 | RGBLIGHT_MODE_RAINBOW_MOOD |
34| 7 | RGBLIGHT_MODE_RAINBOW_MOOD + 1 |
35| 8 | RGBLIGHT_MODE_RAINBOW_MOOD + 2 |
36| 9 | RGBLIGHT_MODE_RAINBOW_SWIRL |
37| 10 | RGBLIGHT_MODE_RAINBOW_SWIRL + 1 |
38| 11 | RGBLIGHT_MODE_RAINBOW_SWIRL + 2 |
39| 12 | RGBLIGHT_MODE_RAINBOW_SWIRL + 3 |
40| 13 | RGBLIGHT_MODE_RAINBOW_SWIRL + 4 |
41| 14 | RGBLIGHT_MODE_RAINBOW_SWIRL + 5 |
42| 15 | RGBLIGHT_MODE_SNAKE |
43| 16 | RGBLIGHT_MODE_SNAKE + 1 |
44| 17 | RGBLIGHT_MODE_SNAKE + 2 |
45| 18 | RGBLIGHT_MODE_SNAKE + 3 |
46| 19 | RGBLIGHT_MODE_SNAKE + 4 |
47| 20 | RGBLIGHT_MODE_SNAKE + 5 |
48| 21 | RGBLIGHT_MODE_KNIGHT |
49| 22 | RGBLIGHT_MODE_KNIGHT + 1 |
50| 23 | RGBLIGHT_MODE_KNIGHT + 2 |
51| 24 | RGBLIGHT_MODE_CHRISTMAS |
52| 25 | RGBLIGHT_MODE_STATIC_GRADIENT |
53| 26 | RGBLIGHT_MODE_STATIC_GRADIENT + 1 |
54| 27 | RGBLIGHT_MODE_STATIC_GRADIENT + 2 |
55| 28 | RGBLIGHT_MODE_STATIC_GRADIENT + 3 |
56| 29 | RGBLIGHT_MODE_STATIC_GRADIENT + 4 |
57| 30 | RGBLIGHT_MODE_STATIC_GRADIENT + 5 |
58| 31 | RGBLIGHT_MODE_STATIC_GRADIENT + 6 |
59| 32 | RGBLIGHT_MODE_STATIC_GRADIENT + 7 |
60| 33 | RGBLIGHT_MODE_STATIC_GRADIENT + 8 |
61| 34 | RGBLIGHT_MODE_STATIC_GRADIENT + 9 |
62| 35 | RGBLIGHT_MODE_RGB_TEST |
63| 36 | RGBLIGHT_MODE_ALTERNATING |
64|-----------------|-----------------------------------|
65 *****/
66
67#define _RGBM_SINGLE_STATIC(sym) RGBLIGHT_MODE_ ## sym,
68#define _RGBM_SINGLE_DYNAMIC(sym) RGBLIGHT_MODE_ ## sym,
69#define _RGBM_MULTI_STATIC(sym) RGBLIGHT_MODE_ ## sym,
70#define _RGBM_MULTI_DYNAMIC(sym) RGBLIGHT_MODE_ ## sym,
71#define _RGBM_TMP_STATIC(sym) RGBLIGHT_MODE_ ## sym,
72#define _RGBM_TMP_DYNAMIC(sym) RGBLIGHT_MODE_ ## sym,
73enum RGBLIGHT_EFFECT_MODE {
74 RGBLIGHT_MODE_zero = 0,
75#include "rgblight.h"
76 RGBLIGHT_MODE_last
77};
78
79#ifndef RGBLIGHT_H_DUMMY_DEFINE
80
81#define RGBLIGHT_MODES (RGBLIGHT_MODE_last-1)
24 82
25#ifndef RGBLIGHT_EFFECT_BREATHE_CENTER 83#ifndef RGBLIGHT_EFFECT_BREATHE_CENTER
26#define RGBLIGHT_EFFECT_BREATHE_CENTER 1.85 // 1-2.7 84#define RGBLIGHT_EFFECT_BREATHE_CENTER 1.85 // 1-2.7
@@ -109,7 +167,7 @@ void rgblight_enable(void);
109void rgblight_disable(void); 167void rgblight_disable(void);
110void rgblight_step(void); 168void rgblight_step(void);
111void rgblight_step_reverse(void); 169void rgblight_step_reverse(void);
112uint32_t rgblight_get_mode(void); 170uint8_t rgblight_get_mode(void);
113void rgblight_mode(uint8_t mode); 171void rgblight_mode(uint8_t mode);
114void rgblight_set(void); 172void rgblight_set(void);
115void rgblight_update_dword(uint32_t dword); 173void rgblight_update_dword(uint32_t dword);
@@ -145,6 +203,14 @@ void rgblight_mode_noeeprom(uint8_t mode);
145void rgblight_toggle_noeeprom(void); 203void rgblight_toggle_noeeprom(void);
146void rgblight_enable_noeeprom(void); 204void rgblight_enable_noeeprom(void);
147void rgblight_disable_noeeprom(void); 205void rgblight_disable_noeeprom(void);
206void rgblight_step_noeeprom(void);
207void rgblight_step_reverse_noeeprom(void);
208void rgblight_increase_hue_noeeprom(void);
209void rgblight_decrease_hue_noeeprom(void);
210void rgblight_increase_sat_noeeprom(void);
211void rgblight_decrease_sat_noeeprom(void);
212void rgblight_increase_val_noeeprom(void);
213void rgblight_decrease_val_noeeprom(void);
148 214
149void rgblight_sethsv_eeprom_helper(uint16_t hue, uint8_t sat, uint8_t val, bool write_to_eeprom); 215void rgblight_sethsv_eeprom_helper(uint16_t hue, uint8_t sat, uint8_t val, bool write_to_eeprom);
150void rgblight_mode_eeprom_helper(uint8_t mode, bool write_to_eeprom); 216void rgblight_mode_eeprom_helper(uint8_t mode, bool write_to_eeprom);
@@ -168,4 +234,73 @@ void rgblight_effect_christmas(void);
168void rgblight_effect_rgbtest(void); 234void rgblight_effect_rgbtest(void);
169void rgblight_effect_alternating(void); 235void rgblight_effect_alternating(void);
170 236
237#endif // #ifndef RGBLIGHT_H_DUMMY_DEFINE
238#endif // RGBLIGHT_H
239
240#ifdef _RGBM_SINGLE_STATIC
241 _RGBM_SINGLE_STATIC( STATIC_LIGHT )
242 #ifdef RGBLIGHT_EFFECT_BREATHING
243 _RGBM_MULTI_DYNAMIC( BREATHING )
244 _RGBM_TMP_DYNAMIC( breathing_3 )
245 _RGBM_TMP_DYNAMIC( breathing_4 )
246 _RGBM_TMP_DYNAMIC( BREATHING_end )
247 #endif
248 #ifdef RGBLIGHT_EFFECT_RAINBOW_MOOD
249 _RGBM_MULTI_DYNAMIC( RAINBOW_MOOD )
250 _RGBM_TMP_DYNAMIC( rainbow_mood_7 )
251 _RGBM_TMP_DYNAMIC( RAINBOW_MOOD_end )
252 #endif
253 #ifdef RGBLIGHT_EFFECT_RAINBOW_SWIRL
254 _RGBM_MULTI_DYNAMIC( RAINBOW_SWIRL )
255 _RGBM_TMP_DYNAMIC( rainbow_swirl_10 )
256 _RGBM_TMP_DYNAMIC( rainbow_swirl_11 )
257 _RGBM_TMP_DYNAMIC( rainbow_swirl_12 )
258 _RGBM_TMP_DYNAMIC( rainbow_swirl_13 )
259 _RGBM_TMP_DYNAMIC( RAINBOW_SWIRL_end )
260 #endif
261 #ifdef RGBLIGHT_EFFECT_SNAKE
262 _RGBM_MULTI_DYNAMIC( SNAKE )
263 _RGBM_TMP_DYNAMIC( snake_16 )
264 _RGBM_TMP_DYNAMIC( snake_17 )
265 _RGBM_TMP_DYNAMIC( snake_18 )
266 _RGBM_TMP_DYNAMIC( snake_19 )
267 _RGBM_TMP_DYNAMIC( SNAKE_end )
268 #endif
269 #ifdef RGBLIGHT_EFFECT_KNIGHT
270 _RGBM_MULTI_DYNAMIC( KNIGHT )
271 _RGBM_TMP_DYNAMIC( knight_22 )
272 _RGBM_TMP_DYNAMIC( KNIGHT_end )
273 #endif
274 #ifdef RGBLIGHT_EFFECT_CHRISTMAS
275 _RGBM_SINGLE_DYNAMIC( CHRISTMAS )
276 #endif
277 #ifdef RGBLIGHT_EFFECT_STATIC_GRADIENT
278 _RGBM_MULTI_STATIC( STATIC_GRADIENT )
279 _RGBM_TMP_STATIC( static_gradient_26 )
280 _RGBM_TMP_STATIC( static_gradient_27 )
281 _RGBM_TMP_STATIC( static_gradient_28 )
282 _RGBM_TMP_STATIC( static_gradient_29 )
283 _RGBM_TMP_STATIC( static_gradient_30 )
284 _RGBM_TMP_STATIC( static_gradient_31 )
285 _RGBM_TMP_STATIC( static_gradient_32 )
286 _RGBM_TMP_STATIC( static_gradient_33 )
287 _RGBM_TMP_STATIC( STATIC_GRADIENT_end )
288 #endif
289 #ifdef RGBLIGHT_EFFECT_RGB_TEST
290 _RGBM_SINGLE_DYNAMIC( RGB_TEST )
291 #endif
292 #ifdef RGBLIGHT_EFFECT_ALTERNATING
293 _RGBM_SINGLE_DYNAMIC( ALTERNATING )
294 #endif
295 //// Add a new mode here.
296 // #ifdef RGBLIGHT_EFFECT_<name>
297 // _RGBM_<SINGLE|MULTI>_<STATIC|DYNAMIC>( <name> )
298 // #endif
171#endif 299#endif
300
301#undef _RGBM_SINGLE_STATIC
302#undef _RGBM_SINGLE_DYNAMIC
303#undef _RGBM_MULTI_STATIC
304#undef _RGBM_MULTI_DYNAMIC
305#undef _RGBM_TMP_STATIC
306#undef _RGBM_TMP_DYNAMIC
diff --git a/quantum/rgblight_reconfig.h b/quantum/rgblight_reconfig.h
new file mode 100644
index 000000000..11bd4fd11
--- /dev/null
+++ b/quantum/rgblight_reconfig.h
@@ -0,0 +1,36 @@
1#ifndef RGBLIGHT_RECONFIG_H
2#define RGBLIGHT_RECONFIG_H
3
4#ifdef RGBLIGHT_ANIMATIONS
5 // for backward compatibility
6 #define RGBLIGHT_EFFECT_BREATHING
7 #define RGBLIGHT_EFFECT_RAINBOW_MOOD
8 #define RGBLIGHT_EFFECT_RAINBOW_SWIRL
9 #define RGBLIGHT_EFFECT_SNAKE
10 #define RGBLIGHT_EFFECT_KNIGHT
11 #define RGBLIGHT_EFFECT_CHRISTMAS
12 #define RGBLIGHT_EFFECT_STATIC_GRADIENT
13 #define RGBLIGHT_EFFECT_RGB_TEST
14 #define RGBLIGHT_EFFECT_ALTERNATING
15#endif
16
17#ifdef RGBLIGHT_STATIC_PATTERNS
18 #define RGBLIGHT_EFFECT_STATIC_GRADIENT
19#endif
20
21// check dynamic animation effects chose ?
22#if defined(RGBLIGHT_EFFECT_BREATHING) || \
23 defined(RGBLIGHT_EFFECT_RAINBOW_MOOD) || \
24 defined(RGBLIGHT_EFFECT_RAINBOW_SWIRL) || \
25 defined(RGBLIGHT_EFFECT_SNAKE) || \
26 defined(RGBLIGHT_EFFECT_KNIGHT) || \
27 defined(RGBLIGHT_EFFECT_CHRISTMAS) || \
28 defined(RGBLIGHT_EFFECT_RGB_TEST) || \
29 defined(RGBLIGHT_EFFECT_ALTERNATING)
30 #define RGBLIGHT_USE_TIMER
31 #ifndef RGBLIGHT_ANIMATIONS
32 #define RGBLIGHT_ANIMATIONS // for backward compatibility
33 #endif
34#endif
35
36#endif // RGBLIGHT_RECONFIG_H
diff --git a/quantum/split_common/i2c.c b/quantum/split_common/i2c.c
index b3d7fcc68..45e958b39 100644
--- a/quantum/split_common/i2c.c
+++ b/quantum/split_common/i2c.c
@@ -7,8 +7,6 @@
7#include "i2c.h" 7#include "i2c.h"
8#include "split_flags.h" 8#include "split_flags.h"
9 9
10#if defined(USE_I2C) || defined(EH)
11
12// Limits the amount of we wait for any one i2c transaction. 10// Limits the amount of we wait for any one i2c transaction.
13// Since were running SCL line 100kHz (=> 10μs/bit), and each transactions is 11// Since were running SCL line 100kHz (=> 10μs/bit), and each transactions is
14// 9 bits, a single transaction will take around 90μs to complete. 12// 9 bits, a single transaction will take around 90μs to complete.
@@ -184,4 +182,3 @@ ISR(TWI_vect) {
184 // Reset everything, so we are ready for the next TWI interrupt 182 // Reset everything, so we are ready for the next TWI interrupt
185 TWCR |= (1<<TWIE) | (1<<TWINT) | (ack<<TWEA) | (1<<TWEN); 183 TWCR |= (1<<TWIE) | (1<<TWINT) | (ack<<TWEA) | (1<<TWEN);
186} 184}
187#endif
diff --git a/quantum/split_common/matrix.c b/quantum/split_common/matrix.c
index 4af90209f..2c37053f8 100644
--- a/quantum/split_common/matrix.c
+++ b/quantum/split_common/matrix.c
@@ -20,21 +20,15 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
20 */ 20 */
21#include <stdint.h> 21#include <stdint.h>
22#include <stdbool.h> 22#include <stdbool.h>
23#include <avr/io.h>
24#include "wait.h" 23#include "wait.h"
25#include "print.h"
26#include "debug.h"
27#include "util.h" 24#include "util.h"
28#include "matrix.h" 25#include "matrix.h"
29#include "split_util.h" 26#include "split_util.h"
30#include "pro_micro.h"
31#include "config.h" 27#include "config.h"
32#include "timer.h" 28#include "timer.h"
33#include "split_flags.h" 29#include "split_flags.h"
30#include "quantum.h"
34 31
35#ifdef RGBLIGHT_ENABLE
36# include "rgblight.h"
37#endif
38#ifdef BACKLIGHT_ENABLE 32#ifdef BACKLIGHT_ENABLE
39# include "backlight.h" 33# include "backlight.h"
40 extern backlight_config_t backlight_config; 34 extern backlight_config_t backlight_config;
@@ -55,6 +49,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
55 static bool debouncing = false; 49 static bool debouncing = false;
56#endif 50#endif
57 51
52#if defined(USE_I2C) || defined(EH)
53
58#if (MATRIX_COLS <= 8) 54#if (MATRIX_COLS <= 8)
59# define print_matrix_header() print("\nr/c 01234567\n") 55# define print_matrix_header() print("\nr/c 01234567\n")
60# define print_matrix_row(row) print_bin_reverse8(matrix_get_row(row)) 56# define print_matrix_row(row) print_bin_reverse8(matrix_get_row(row))
@@ -63,6 +59,27 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
63#else 59#else
64# error "Currently only supports 8 COLS" 60# error "Currently only supports 8 COLS"
65#endif 61#endif
62
63#else // USE_SERIAL
64
65#if (MATRIX_COLS <= 8)
66# define print_matrix_header() print("\nr/c 01234567\n")
67# define print_matrix_row(row) print_bin_reverse8(matrix_get_row(row))
68# define matrix_bitpop(i) bitpop(matrix[i])
69# define ROW_SHIFTER ((uint8_t)1)
70#elif (MATRIX_COLS <= 16)
71# define print_matrix_header() print("\nr/c 0123456789ABCDEF\n")
72# define print_matrix_row(row) print_bin_reverse16(matrix_get_row(row))
73# define matrix_bitpop(i) bitpop16(matrix[i])
74# define ROW_SHIFTER ((uint16_t)1)
75#elif (MATRIX_COLS <= 32)
76# define print_matrix_header() print("\nr/c 0123456789ABCDEF0123456789ABCDEF\n")
77# define print_matrix_row(row) print_bin_reverse32(matrix_get_row(row))
78# define matrix_bitpop(i) bitpop32(matrix[i])
79# define ROW_SHIFTER ((uint32_t)1)
80#endif
81
82#endif
66static matrix_row_t matrix_debouncing[MATRIX_ROWS]; 83static matrix_row_t matrix_debouncing[MATRIX_ROWS];
67 84
68#define ERROR_DISCONNECT_COUNT 5 85#define ERROR_DISCONNECT_COUNT 5
@@ -71,8 +88,8 @@ static matrix_row_t matrix_debouncing[MATRIX_ROWS];
71 88
72static uint8_t error_count = 0; 89static uint8_t error_count = 0;
73 90
74static const uint8_t row_pins[MATRIX_ROWS] = MATRIX_ROW_PINS; 91static pin_t row_pins[MATRIX_ROWS] = MATRIX_ROW_PINS;
75static const uint8_t col_pins[MATRIX_COLS] = MATRIX_COL_PINS; 92static pin_t col_pins[MATRIX_COLS] = MATRIX_COL_PINS;
76 93
77/* matrix state(1:on, 0:off) */ 94/* matrix state(1:on, 0:off) */
78static matrix_row_t matrix[MATRIX_ROWS]; 95static matrix_row_t matrix[MATRIX_ROWS];
@@ -128,15 +145,24 @@ uint8_t matrix_cols(void)
128 145
129void matrix_init(void) 146void matrix_init(void)
130{ 147{
131#ifdef DISABLE_JTAG
132 // JTAG disable for PORT F. write JTD bit twice within four cycles.
133 MCUCR |= (1<<JTD);
134 MCUCR |= (1<<JTD);
135#endif
136
137 debug_enable = true; 148 debug_enable = true;
138 debug_matrix = true; 149 debug_matrix = true;
139 debug_mouse = true; 150 debug_mouse = true;
151
152 // Set pinout for right half if pinout for that half is defined
153 if (!isLeftHand) {
154#ifdef MATRIX_ROW_PINS_RIGHT
155 const uint8_t row_pins_right[MATRIX_ROWS] = MATRIX_ROW_PINS_RIGHT;
156 for (uint8_t i = 0; i < MATRIX_ROWS; i++)
157 row_pins[i] = row_pins_right[i];
158#endif
159#ifdef MATRIX_COL_PINS_RIGHT
160 const uint8_t col_pins_right[MATRIX_COLS] = MATRIX_COL_PINS_RIGHT;
161 for (uint8_t i = 0; i < MATRIX_COLS; i++)
162 col_pins[i] = col_pins_right[i];
163#endif
164 }
165
140 // initialize row and col 166 // initialize row and col
141#if (DIODE_DIRECTION == COL2ROW) 167#if (DIODE_DIRECTION == COL2ROW)
142 unselect_rows(); 168 unselect_rows();
@@ -277,24 +303,48 @@ i2c_error: // the cable is disconnceted, or something else went wrong
277 303
278#else // USE_SERIAL 304#else // USE_SERIAL
279 305
306
307typedef struct _Serial_s2m_buffer_t {
308 // TODO: if MATRIX_COLS > 8 change to uint8_t packed_matrix[] for pack/unpack
309 matrix_row_t smatrix[ROWS_PER_HAND];
310} Serial_s2m_buffer_t;
311
312volatile Serial_s2m_buffer_t serial_s2m_buffer = {};
313volatile Serial_m2s_buffer_t serial_m2s_buffer = {};
314uint8_t volatile status0 = 0;
315
316SSTD_t transactions[] = {
317 { (uint8_t *)&status0,
318 sizeof(serial_m2s_buffer), (uint8_t *)&serial_m2s_buffer,
319 sizeof(serial_s2m_buffer), (uint8_t *)&serial_s2m_buffer
320 }
321};
322
323void serial_master_init(void)
324{ soft_serial_initiator_init(transactions, TID_LIMIT(transactions)); }
325
326void serial_slave_init(void)
327{ soft_serial_target_init(transactions, TID_LIMIT(transactions)); }
328
280int serial_transaction(void) { 329int serial_transaction(void) {
281 int slaveOffset = (isLeftHand) ? (ROWS_PER_HAND) : 0; 330 int slaveOffset = (isLeftHand) ? (ROWS_PER_HAND) : 0;
282 331
283 if (serial_update_buffers()) { 332 if (soft_serial_transaction()) {
284 return 1; 333 return 1;
285 } 334 }
286 335
336 // TODO: if MATRIX_COLS > 8 change to unpack()
287 for (int i = 0; i < ROWS_PER_HAND; ++i) { 337 for (int i = 0; i < ROWS_PER_HAND; ++i) {
288 matrix[slaveOffset+i] = serial_slave_buffer[i]; 338 matrix[slaveOffset+i] = serial_s2m_buffer.smatrix[i];
289 } 339 }
290 340
291 #ifdef RGBLIGHT_ENABLE 341 #if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT)
292 // Code to send RGB over serial goes here (not implemented yet) 342 // Code to send RGB over serial goes here (not implemented yet)
293 #endif 343 #endif
294 344
295 #ifdef BACKLIGHT_ENABLE 345 #ifdef BACKLIGHT_ENABLE
296 // Write backlight level for slave to read 346 // Write backlight level for slave to read
297 serial_master_buffer[SERIAL_BACKLIT_START] = backlight_config.enable ? backlight_config.level : 0; 347 serial_m2s_buffer.backlight_level = backlight_config.enable ? backlight_config.level : 0;
298 #endif 348 #endif
299 349
300 return 0; 350 return 0;
@@ -337,27 +387,10 @@ void matrix_slave_scan(void) {
337 i2c_slave_buffer[I2C_KEYMAP_START+i] = matrix[offset+i]; 387 i2c_slave_buffer[I2C_KEYMAP_START+i] = matrix[offset+i];
338 } 388 }
339#else // USE_SERIAL 389#else // USE_SERIAL
390 // TODO: if MATRIX_COLS > 8 change to pack()
340 for (int i = 0; i < ROWS_PER_HAND; ++i) { 391 for (int i = 0; i < ROWS_PER_HAND; ++i) {
341 serial_slave_buffer[i] = matrix[offset+i]; 392 serial_s2m_buffer.smatrix[i] = matrix[offset+i];
342 }
343#endif
344#ifdef USE_I2C
345#ifdef BACKLIGHT_ENABLE
346 // Read backlight level sent from master and update level on slave
347 backlight_set(i2c_slave_buffer[0]);
348#endif
349 for (int i = 0; i < ROWS_PER_HAND; ++i) {
350 i2c_slave_buffer[i+1] = matrix[offset+i];
351 }
352#else // USE_SERIAL
353 for (int i = 0; i < ROWS_PER_HAND; ++i) {
354 serial_slave_buffer[i] = matrix[offset+i];
355 } 393 }
356
357#ifdef BACKLIGHT_ENABLE
358 // Read backlight level sent from master and update level on slave
359 backlight_set(serial_master_buffer[SERIAL_BACKLIT_START]);
360#endif
361#endif 394#endif
362 matrix_slave_scan_user(); 395 matrix_slave_scan_user();
363} 396}
@@ -404,9 +437,7 @@ uint8_t matrix_key_count(void)
404static void init_cols(void) 437static void init_cols(void)
405{ 438{
406 for(uint8_t x = 0; x < MATRIX_COLS; x++) { 439 for(uint8_t x = 0; x < MATRIX_COLS; x++) {
407 uint8_t pin = col_pins[x]; 440 setPinInputHigh(col_pins[x]);
408 _SFR_IO8((pin >> 4) + 1) &= ~_BV(pin & 0xF); // IN
409 _SFR_IO8((pin >> 4) + 2) |= _BV(pin & 0xF); // HI
410 } 441 }
411} 442}
412 443
@@ -424,13 +455,8 @@ static bool read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row)
424 455
425 // For each col... 456 // For each col...
426 for(uint8_t col_index = 0; col_index < MATRIX_COLS; col_index++) { 457 for(uint8_t col_index = 0; col_index < MATRIX_COLS; col_index++) {
427
428 // Select the col pin to read (active low)
429 uint8_t pin = col_pins[col_index];
430 uint8_t pin_state = (_SFR_IO8(pin >> 4) & _BV(pin & 0xF));
431
432 // Populate the matrix row with the state of the col pin 458 // Populate the matrix row with the state of the col pin
433 current_matrix[current_row] |= pin_state ? 0 : (ROW_SHIFTER << col_index); 459 current_matrix[current_row] |= readPin(col_pins[col_index]) ? 0 : (ROW_SHIFTER << col_index);
434 } 460 }
435 461
436 // Unselect row 462 // Unselect row
@@ -441,24 +467,19 @@ static bool read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row)
441 467
442static void select_row(uint8_t row) 468static void select_row(uint8_t row)
443{ 469{
444 uint8_t pin = row_pins[row]; 470 writePinLow(row_pins[row]);
445 _SFR_IO8((pin >> 4) + 1) |= _BV(pin & 0xF); // OUT 471 setPinOutput(row_pins[row]);
446 _SFR_IO8((pin >> 4) + 2) &= ~_BV(pin & 0xF); // LOW
447} 472}
448 473
449static void unselect_row(uint8_t row) 474static void unselect_row(uint8_t row)
450{ 475{
451 uint8_t pin = row_pins[row]; 476 setPinInputHigh(row_pins[row]);
452 _SFR_IO8((pin >> 4) + 1) &= ~_BV(pin & 0xF); // IN
453 _SFR_IO8((pin >> 4) + 2) |= _BV(pin & 0xF); // HI
454} 477}
455 478
456static void unselect_rows(void) 479static void unselect_rows(void)
457{ 480{
458 for(uint8_t x = 0; x < ROWS_PER_HAND; x++) { 481 for(uint8_t x = 0; x < ROWS_PER_HAND; x++) {
459 uint8_t pin = row_pins[x]; 482 setPinInputHigh(row_pins[x]);
460 _SFR_IO8((pin >> 4) + 1) &= ~_BV(pin & 0xF); // IN
461 _SFR_IO8((pin >> 4) + 2) |= _BV(pin & 0xF); // HI
462 } 483 }
463} 484}
464 485
@@ -467,9 +488,7 @@ static void unselect_rows(void)
467static void init_rows(void) 488static void init_rows(void)
468{ 489{
469 for(uint8_t x = 0; x < ROWS_PER_HAND; x++) { 490 for(uint8_t x = 0; x < ROWS_PER_HAND; x++) {
470 uint8_t pin = row_pins[x]; 491 setPinInputHigh(row_pins[x]);
471 _SFR_IO8((pin >> 4) + 1) &= ~_BV(pin & 0xF); // IN
472 _SFR_IO8((pin >> 4) + 2) |= _BV(pin & 0xF); // HI
473 } 492 }
474} 493}
475 494
@@ -489,15 +508,15 @@ static bool read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col)
489 matrix_row_t last_row_value = current_matrix[row_index]; 508 matrix_row_t last_row_value = current_matrix[row_index];
490 509
491 // Check row pin state 510 // Check row pin state
492 if ((_SFR_IO8(row_pins[row_index] >> 4) & _BV(row_pins[row_index] & 0xF)) == 0) 511 if (readPin(row_pins[row_index]))
493 { 512 {
494 // Pin LO, set col bit 513 // Pin HI, clear col bit
495 current_matrix[row_index] |= (ROW_SHIFTER << current_col); 514 current_matrix[row_index] &= ~(ROW_SHIFTER << current_col);
496 } 515 }
497 else 516 else
498 { 517 {
499 // Pin HI, clear col bit 518 // Pin LO, set col bit
500 current_matrix[row_index] &= ~(ROW_SHIFTER << current_col); 519 current_matrix[row_index] |= (ROW_SHIFTER << current_col);
501 } 520 }
502 521
503 // Determine if the matrix changed state 522 // Determine if the matrix changed state
@@ -515,24 +534,19 @@ static bool read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col)
515 534
516static void select_col(uint8_t col) 535static void select_col(uint8_t col)
517{ 536{
518 uint8_t pin = col_pins[col]; 537 writePinLow(col_pins[col]);
519 _SFR_IO8((pin >> 4) + 1) |= _BV(pin & 0xF); // OUT 538 setPinOutput(col_pins[col]);
520 _SFR_IO8((pin >> 4) + 2) &= ~_BV(pin & 0xF); // LOW
521} 539}
522 540
523static void unselect_col(uint8_t col) 541static void unselect_col(uint8_t col)
524{ 542{
525 uint8_t pin = col_pins[col]; 543 setPinInputHigh(col_pins[col]);
526 _SFR_IO8((pin >> 4) + 1) &= ~_BV(pin & 0xF); // IN
527 _SFR_IO8((pin >> 4) + 2) |= _BV(pin & 0xF); // HI
528} 544}
529 545
530static void unselect_cols(void) 546static void unselect_cols(void)
531{ 547{
532 for(uint8_t x = 0; x < MATRIX_COLS; x++) { 548 for(uint8_t x = 0; x < MATRIX_COLS; x++) {
533 uint8_t pin = col_pins[x]; 549 setPinInputHigh(col_pins[x]);
534 _SFR_IO8((pin >> 4) + 1) &= ~_BV(pin & 0xF); // IN
535 _SFR_IO8((pin >> 4) + 2) |= _BV(pin & 0xF); // HI
536 } 550 }
537} 551}
538 552
diff --git a/quantum/split_common/matrix.h b/quantum/split_common/matrix.h
new file mode 100644
index 000000000..b5cb45bae
--- /dev/null
+++ b/quantum/split_common/matrix.h
@@ -0,0 +1,31 @@
1#ifndef SPLIT_COMMON_MATRIX_H
2#define SPLIT_COMMON_MATRIX_H
3
4#include <common/matrix.h>
5
6#ifdef RGBLIGHT_ENABLE
7# include "rgblight.h"
8#endif
9
10typedef struct _Serial_m2s_buffer_t {
11#ifdef BACKLIGHT_ENABLE
12 uint8_t backlight_level;
13#endif
14#if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT)
15 rgblight_config_t rgblight_config; //not yet use
16 //
17 // When MCUs on both sides drive their respective RGB LED chains,
18 // it is necessary to synchronize, so it is necessary to communicate RGB information.
19 // In that case, define the RGBLIGHT_SPLIT macro.
20 //
21 // Otherwise, if the master side MCU drives both sides RGB LED chains,
22 // there is no need to communicate.
23#endif
24} Serial_m2s_buffer_t;
25
26extern volatile Serial_m2s_buffer_t serial_m2s_buffer;
27
28void serial_master_init(void);
29void serial_slave_init(void);
30
31#endif
diff --git a/quantum/split_common/serial.c b/quantum/split_common/serial.c
index 74bcbb6bf..1315377a3 100644
--- a/quantum/split_common/serial.c
+++ b/quantum/split_common/serial.c
@@ -1,5 +1,10 @@
1/* 1/*
2 * WARNING: be careful changing this code, it is very timing dependent 2 * WARNING: be careful changing this code, it is very timing dependent
3 *
4 * 2018-10-28 checked
5 * avr-gcc 4.9.2
6 * avr-gcc 5.4.0
7 * avr-gcc 7.3.0
3 */ 8 */
4 9
5#ifndef F_CPU 10#ifndef F_CPU
@@ -9,220 +14,533 @@
9#include <avr/io.h> 14#include <avr/io.h>
10#include <avr/interrupt.h> 15#include <avr/interrupt.h>
11#include <util/delay.h> 16#include <util/delay.h>
17#include <stddef.h>
12#include <stdbool.h> 18#include <stdbool.h>
13#include "serial.h" 19#include "serial.h"
20//#include <pro_micro.h>
21
22#ifdef SOFT_SERIAL_PIN
23
24#ifdef __AVR_ATmega32U4__
25 // if using ATmega32U4 I2C, can not use PD0 and PD1 in soft serial.
26 #ifdef USE_AVR_I2C
27 #if SOFT_SERIAL_PIN == D0 || SOFT_SERIAL_PIN == D1
28 #error Using ATmega32U4 I2C, so can not use PD0, PD1
29 #endif
30 #endif
31
32 #if SOFT_SERIAL_PIN >= D0 && SOFT_SERIAL_PIN <= D3
33 #define SERIAL_PIN_DDR DDRD
34 #define SERIAL_PIN_PORT PORTD
35 #define SERIAL_PIN_INPUT PIND
36 #if SOFT_SERIAL_PIN == D0
37 #define SERIAL_PIN_MASK _BV(PD0)
38 #define EIMSK_BIT _BV(INT0)
39 #define EICRx_BIT (~(_BV(ISC00) | _BV(ISC01)))
40 #define SERIAL_PIN_INTERRUPT INT0_vect
41 #elif SOFT_SERIAL_PIN == D1
42 #define SERIAL_PIN_MASK _BV(PD1)
43 #define EIMSK_BIT _BV(INT1)
44 #define EICRx_BIT (~(_BV(ISC10) | _BV(ISC11)))
45 #define SERIAL_PIN_INTERRUPT INT1_vect
46 #elif SOFT_SERIAL_PIN == D2
47 #define SERIAL_PIN_MASK _BV(PD2)
48 #define EIMSK_BIT _BV(INT2)
49 #define EICRx_BIT (~(_BV(ISC20) | _BV(ISC21)))
50 #define SERIAL_PIN_INTERRUPT INT2_vect
51 #elif SOFT_SERIAL_PIN == D3
52 #define SERIAL_PIN_MASK _BV(PD3)
53 #define EIMSK_BIT _BV(INT3)
54 #define EICRx_BIT (~(_BV(ISC30) | _BV(ISC31)))
55 #define SERIAL_PIN_INTERRUPT INT3_vect
56 #endif
57 #elif SOFT_SERIAL_PIN == E6
58 #define SERIAL_PIN_DDR DDRE
59 #define SERIAL_PIN_PORT PORTE
60 #define SERIAL_PIN_INPUT PINE
61 #define SERIAL_PIN_MASK _BV(PE6)
62 #define EIMSK_BIT _BV(INT6)
63 #define EICRx_BIT (~(_BV(ISC60) | _BV(ISC61)))
64 #define SERIAL_PIN_INTERRUPT INT6_vect
65 #else
66 #error invalid SOFT_SERIAL_PIN value
67 #endif
68
69#else
70 #error serial.c now support ATmega32U4 only
71#endif
14 72
15#ifndef USE_I2C 73#define ALWAYS_INLINE __attribute__((always_inline))
74#define NO_INLINE __attribute__((noinline))
75#define _delay_sub_us(x) __builtin_avr_delay_cycles(x)
76
77// parity check
78#define ODD_PARITY 1
79#define EVEN_PARITY 0
80#define PARITY EVEN_PARITY
81
82#ifdef SERIAL_DELAY
83 // custom setup in config.h
84 // #define TID_SEND_ADJUST 2
85 // #define SERIAL_DELAY 6 // micro sec
86 // #define READ_WRITE_START_ADJUST 30 // cycles
87 // #define READ_WRITE_WIDTH_ADJUST 8 // cycles
88#else
89// ============ Standard setups ============
90
91#ifndef SELECT_SOFT_SERIAL_SPEED
92#define SELECT_SOFT_SERIAL_SPEED 1
93// 0: about 189kbps (Experimental only)
94// 1: about 137kbps (default)
95// 2: about 75kbps
96// 3: about 39kbps
97// 4: about 26kbps
98// 5: about 20kbps
99#endif
16 100
17// Serial pulse period in microseconds. Its probably a bad idea to lower this 101#if __GNUC__ < 6
18// value. 102 #define TID_SEND_ADJUST 14
19#define SERIAL_DELAY 24 103#else
104 #define TID_SEND_ADJUST 2
105#endif
20 106
21uint8_t volatile serial_slave_buffer[SERIAL_SLAVE_BUFFER_LENGTH] = {0}; 107#if SELECT_SOFT_SERIAL_SPEED == 0
22uint8_t volatile serial_master_buffer[SERIAL_MASTER_BUFFER_LENGTH] = {0}; 108 // Very High speed
109 #define SERIAL_DELAY 4 // micro sec
110 #if __GNUC__ < 6
111 #define READ_WRITE_START_ADJUST 33 // cycles
112 #define READ_WRITE_WIDTH_ADJUST 3 // cycles
113 #else
114 #define READ_WRITE_START_ADJUST 34 // cycles
115 #define READ_WRITE_WIDTH_ADJUST 7 // cycles
116 #endif
117#elif SELECT_SOFT_SERIAL_SPEED == 1
118 // High speed
119 #define SERIAL_DELAY 6 // micro sec
120 #if __GNUC__ < 6
121 #define READ_WRITE_START_ADJUST 30 // cycles
122 #define READ_WRITE_WIDTH_ADJUST 3 // cycles
123 #else
124 #define READ_WRITE_START_ADJUST 33 // cycles
125 #define READ_WRITE_WIDTH_ADJUST 7 // cycles
126 #endif
127#elif SELECT_SOFT_SERIAL_SPEED == 2
128 // Middle speed
129 #define SERIAL_DELAY 12 // micro sec
130 #define READ_WRITE_START_ADJUST 30 // cycles
131 #if __GNUC__ < 6
132 #define READ_WRITE_WIDTH_ADJUST 3 // cycles
133 #else
134 #define READ_WRITE_WIDTH_ADJUST 7 // cycles
135 #endif
136#elif SELECT_SOFT_SERIAL_SPEED == 3
137 // Low speed
138 #define SERIAL_DELAY 24 // micro sec
139 #define READ_WRITE_START_ADJUST 30 // cycles
140 #if __GNUC__ < 6
141 #define READ_WRITE_WIDTH_ADJUST 3 // cycles
142 #else
143 #define READ_WRITE_WIDTH_ADJUST 7 // cycles
144 #endif
145#elif SELECT_SOFT_SERIAL_SPEED == 4
146 // Very Low speed
147 #define SERIAL_DELAY 36 // micro sec
148 #define READ_WRITE_START_ADJUST 30 // cycles
149 #if __GNUC__ < 6
150 #define READ_WRITE_WIDTH_ADJUST 3 // cycles
151 #else
152 #define READ_WRITE_WIDTH_ADJUST 7 // cycles
153 #endif
154#elif SELECT_SOFT_SERIAL_SPEED == 5
155 // Ultra Low speed
156 #define SERIAL_DELAY 48 // micro sec
157 #define READ_WRITE_START_ADJUST 30 // cycles
158 #if __GNUC__ < 6
159 #define READ_WRITE_WIDTH_ADJUST 3 // cycles
160 #else
161 #define READ_WRITE_WIDTH_ADJUST 7 // cycles
162 #endif
163#else
164#error invalid SELECT_SOFT_SERIAL_SPEED value
165#endif /* SELECT_SOFT_SERIAL_SPEED */
166#endif /* SERIAL_DELAY */
167
168#define SERIAL_DELAY_HALF1 (SERIAL_DELAY/2)
169#define SERIAL_DELAY_HALF2 (SERIAL_DELAY - SERIAL_DELAY/2)
170
171#define SLAVE_INT_WIDTH_US 1
172#ifndef SERIAL_USE_MULTI_TRANSACTION
173 #define SLAVE_INT_RESPONSE_TIME SERIAL_DELAY
174#else
175 #define SLAVE_INT_ACK_WIDTH_UNIT 2
176 #define SLAVE_INT_ACK_WIDTH 4
177#endif
23 178
24#define SLAVE_DATA_CORRUPT (1<<0) 179static SSTD_t *Transaction_table = NULL;
25volatile uint8_t status = 0; 180static uint8_t Transaction_table_size = 0;
26 181
182inline static void serial_delay(void) ALWAYS_INLINE;
27inline static 183inline static
28void serial_delay(void) { 184void serial_delay(void) {
29 _delay_us(SERIAL_DELAY); 185 _delay_us(SERIAL_DELAY);
30} 186}
31 187
188inline static void serial_delay_half1(void) ALWAYS_INLINE;
189inline static
190void serial_delay_half1(void) {
191 _delay_us(SERIAL_DELAY_HALF1);
192}
193
194inline static void serial_delay_half2(void) ALWAYS_INLINE;
195inline static
196void serial_delay_half2(void) {
197 _delay_us(SERIAL_DELAY_HALF2);
198}
199
200inline static void serial_output(void) ALWAYS_INLINE;
32inline static 201inline static
33void serial_output(void) { 202void serial_output(void) {
34 SERIAL_PIN_DDR |= SERIAL_PIN_MASK; 203 SERIAL_PIN_DDR |= SERIAL_PIN_MASK;
35} 204}
36 205
37// make the serial pin an input with pull-up resistor 206// make the serial pin an input with pull-up resistor
207inline static void serial_input_with_pullup(void) ALWAYS_INLINE;
38inline static 208inline static
39void serial_input(void) { 209void serial_input_with_pullup(void) {
40 SERIAL_PIN_DDR &= ~SERIAL_PIN_MASK; 210 SERIAL_PIN_DDR &= ~SERIAL_PIN_MASK;
41 SERIAL_PIN_PORT |= SERIAL_PIN_MASK; 211 SERIAL_PIN_PORT |= SERIAL_PIN_MASK;
42} 212}
43 213
214inline static uint8_t serial_read_pin(void) ALWAYS_INLINE;
44inline static 215inline static
45uint8_t serial_read_pin(void) { 216uint8_t serial_read_pin(void) {
46 return !!(SERIAL_PIN_INPUT & SERIAL_PIN_MASK); 217 return !!(SERIAL_PIN_INPUT & SERIAL_PIN_MASK);
47} 218}
48 219
220inline static void serial_low(void) ALWAYS_INLINE;
49inline static 221inline static
50void serial_low(void) { 222void serial_low(void) {
51 SERIAL_PIN_PORT &= ~SERIAL_PIN_MASK; 223 SERIAL_PIN_PORT &= ~SERIAL_PIN_MASK;
52} 224}
53 225
226inline static void serial_high(void) ALWAYS_INLINE;
54inline static 227inline static
55void serial_high(void) { 228void serial_high(void) {
56 SERIAL_PIN_PORT |= SERIAL_PIN_MASK; 229 SERIAL_PIN_PORT |= SERIAL_PIN_MASK;
57} 230}
58 231
59void serial_master_init(void) { 232void soft_serial_initiator_init(SSTD_t *sstd_table, int sstd_table_size)
60 serial_output(); 233{
61 serial_high(); 234 Transaction_table = sstd_table;
235 Transaction_table_size = (uint8_t)sstd_table_size;
236 serial_output();
237 serial_high();
62} 238}
63 239
64void serial_slave_init(void) { 240void soft_serial_target_init(SSTD_t *sstd_table, int sstd_table_size)
65 serial_input(); 241{
66 242 Transaction_table = sstd_table;
67 // Enable INT0 243 Transaction_table_size = (uint8_t)sstd_table_size;
68 EIMSK |= _BV(INT0); 244 serial_input_with_pullup();
69 // Trigger on falling edge of INT0 245
70 EICRA &= ~(_BV(ISC00) | _BV(ISC01)); 246 // Enable INT0-INT3,INT6
247 EIMSK |= EIMSK_BIT;
248#if SERIAL_PIN_MASK == _BV(PE6)
249 // Trigger on falling edge of INT6
250 EICRB &= EICRx_BIT;
251#else
252 // Trigger on falling edge of INT0-INT3
253 EICRA &= EICRx_BIT;
254#endif
71} 255}
72 256
73// Used by the master to synchronize timing with the slave. 257// Used by the sender to synchronize timing with the reciver.
258static void sync_recv(void) NO_INLINE;
74static 259static
75void sync_recv(void) { 260void sync_recv(void) {
76 serial_input(); 261 for (uint8_t i = 0; i < SERIAL_DELAY*5 && serial_read_pin(); i++ ) {
77 // This shouldn't hang if the slave disconnects because the 262 }
78 // serial line will float to high if the slave does disconnect. 263 // This shouldn't hang if the target disconnects because the
264 // serial line will float to high if the target does disconnect.
79 while (!serial_read_pin()); 265 while (!serial_read_pin());
80 serial_delay();
81} 266}
82 267
83// Used by the slave to send a synchronization signal to the master. 268// Used by the reciver to send a synchronization signal to the sender.
269static void sync_send(void) NO_INLINE;
84static 270static
85void sync_send(void) { 271void sync_send(void) {
86 serial_output();
87
88 serial_low(); 272 serial_low();
89 serial_delay(); 273 serial_delay();
90
91 serial_high(); 274 serial_high();
92} 275}
93 276
94// Reads a byte from the serial line 277// Reads a byte from the serial line
95static 278static uint8_t serial_read_chunk(uint8_t *pterrcount, uint8_t bit) NO_INLINE;
96uint8_t serial_read_byte(void) { 279static uint8_t serial_read_chunk(uint8_t *pterrcount, uint8_t bit) {
97 uint8_t byte = 0; 280 uint8_t byte, i, p, pb;
98 serial_input(); 281
99 for ( uint8_t i = 0; i < 8; ++i) { 282 _delay_sub_us(READ_WRITE_START_ADJUST);
100 byte = (byte << 1) | serial_read_pin(); 283 for( i = 0, byte = 0, p = PARITY; i < bit; i++ ) {
101 serial_delay(); 284 serial_delay_half1(); // read the middle of pulses
102 _delay_us(1); 285 if( serial_read_pin() ) {
286 byte = (byte << 1) | 1; p ^= 1;
287 } else {
288 byte = (byte << 1) | 0; p ^= 0;
289 }
290 _delay_sub_us(READ_WRITE_WIDTH_ADJUST);
291 serial_delay_half2();
103 } 292 }
293 /* recive parity bit */
294 serial_delay_half1(); // read the middle of pulses
295 pb = serial_read_pin();
296 _delay_sub_us(READ_WRITE_WIDTH_ADJUST);
297 serial_delay_half2();
298
299 *pterrcount += (p != pb)? 1 : 0;
104 300
105 return byte; 301 return byte;
106} 302}
107 303
108// Sends a byte with MSB ordering 304// Sends a byte with MSB ordering
109static 305void serial_write_chunk(uint8_t data, uint8_t bit) NO_INLINE;
110void serial_write_byte(uint8_t data) { 306void serial_write_chunk(uint8_t data, uint8_t bit) {
111 uint8_t b = 8; 307 uint8_t b, p;
112 serial_output(); 308 for( p = PARITY, b = 1<<(bit-1); b ; b >>= 1) {
113 while( b-- ) { 309 if(data & b) {
114 if(data & (1 << b)) { 310 serial_high(); p ^= 1;
115 serial_high(); 311 } else {
116 } else { 312 serial_low(); p ^= 0;
117 serial_low(); 313 }
314 serial_delay();
118 } 315 }
316 /* send parity bit */
317 if(p & 1) { serial_high(); }
318 else { serial_low(); }
119 serial_delay(); 319 serial_delay();
120 }
121}
122 320
123// interrupt handle to be used by the slave device 321 serial_low(); // sync_send() / senc_recv() need raise edge
124ISR(SERIAL_PIN_INTERRUPT) { 322}
125 sync_send();
126 323
127 uint8_t checksum = 0; 324static void serial_send_packet(uint8_t *buffer, uint8_t size) NO_INLINE;
128 for (int i = 0; i < SERIAL_SLAVE_BUFFER_LENGTH; ++i) { 325static
129 serial_write_byte(serial_slave_buffer[i]); 326void serial_send_packet(uint8_t *buffer, uint8_t size) {
327 for (uint8_t i = 0; i < size; ++i) {
328 uint8_t data;
329 data = buffer[i];
130 sync_send(); 330 sync_send();
131 checksum += serial_slave_buffer[i]; 331 serial_write_chunk(data,8);
132 } 332 }
133 serial_write_byte(checksum); 333}
134 sync_send();
135 334
136 // wait for the sync to finish sending 335static uint8_t serial_recive_packet(uint8_t *buffer, uint8_t size) NO_INLINE;
137 serial_delay(); 336static
337uint8_t serial_recive_packet(uint8_t *buffer, uint8_t size) {
338 uint8_t pecount = 0;
339 for (uint8_t i = 0; i < size; ++i) {
340 uint8_t data;
341 sync_recv();
342 data = serial_read_chunk(&pecount, 8);
343 buffer[i] = data;
344 }
345 return pecount == 0;
346}
138 347
139 // read the middle of pulses 348inline static
140 _delay_us(SERIAL_DELAY/2); 349void change_sender2reciver(void) {
350 sync_send(); //0
351 serial_delay_half1(); //1
352 serial_low(); //2
353 serial_input_with_pullup(); //2
354 serial_delay_half1(); //3
355}
141 356
142 uint8_t checksum_computed = 0; 357inline static
143 for (int i = 0; i < SERIAL_MASTER_BUFFER_LENGTH; ++i) { 358void change_reciver2sender(void) {
144 serial_master_buffer[i] = serial_read_byte(); 359 sync_recv(); //0
145 sync_send(); 360 serial_delay(); //1
146 checksum_computed += serial_master_buffer[i]; 361 serial_low(); //3
362 serial_output(); //3
363 serial_delay_half1(); //4
364}
365
366static inline uint8_t nibble_bits_count(uint8_t bits)
367{
368 bits = (bits & 0x5) + (bits >> 1 & 0x5);
369 bits = (bits & 0x3) + (bits >> 2 & 0x3);
370 return bits;
371}
372
373// interrupt handle to be used by the target device
374ISR(SERIAL_PIN_INTERRUPT) {
375
376#ifndef SERIAL_USE_MULTI_TRANSACTION
377 serial_low();
378 serial_output();
379 SSTD_t *trans = Transaction_table;
380#else
381 // recive transaction table index
382 uint8_t tid, bits;
383 uint8_t pecount = 0;
384 sync_recv();
385 bits = serial_read_chunk(&pecount,7);
386 tid = bits>>3;
387 bits = (bits&7) != nibble_bits_count(tid);
388 if( bits || pecount> 0 || tid > Transaction_table_size ) {
389 return;
147 } 390 }
148 uint8_t checksum_received = serial_read_byte(); 391 serial_delay_half1();
149 sync_send();
150 392
151 serial_input(); // end transaction 393 serial_high(); // response step1 low->high
394 serial_output();
395 _delay_sub_us(SLAVE_INT_ACK_WIDTH_UNIT*SLAVE_INT_ACK_WIDTH);
396 SSTD_t *trans = &Transaction_table[tid];
397 serial_low(); // response step2 ack high->low
398#endif
152 399
153 if ( checksum_computed != checksum_received ) { 400 // target send phase
154 status |= SLAVE_DATA_CORRUPT; 401 if( trans->target2initiator_buffer_size > 0 )
402 serial_send_packet((uint8_t *)trans->target2initiator_buffer,
403 trans->target2initiator_buffer_size);
404 // target switch to input
405 change_sender2reciver();
406
407 // target recive phase
408 if( trans->initiator2target_buffer_size > 0 ) {
409 if (serial_recive_packet((uint8_t *)trans->initiator2target_buffer,
410 trans->initiator2target_buffer_size) ) {
411 *trans->status = TRANSACTION_ACCEPTED;
412 } else {
413 *trans->status = TRANSACTION_DATA_ERROR;
414 }
155 } else { 415 } else {
156 status &= ~SLAVE_DATA_CORRUPT; 416 *trans->status = TRANSACTION_ACCEPTED;
157 } 417 }
158}
159 418
160inline 419 sync_recv(); //weit initiator output to high
161bool serial_slave_DATA_CORRUPT(void) {
162 return status & SLAVE_DATA_CORRUPT;
163} 420}
164 421
165// Copies the serial_slave_buffer to the master and sends the 422/////////
166// serial_master_buffer to the slave. 423// start transaction by initiator
424//
425// int soft_serial_transaction(int sstd_index)
167// 426//
168// Returns: 427// Returns:
169// 0 => no error 428// TRANSACTION_END
170// 1 => slave did not respond 429// TRANSACTION_NO_RESPONSE
171int serial_update_buffers(void) { 430// TRANSACTION_DATA_ERROR
172 // this code is very time dependent, so we need to disable interrupts 431// this code is very time dependent, so we need to disable interrupts
432#ifndef SERIAL_USE_MULTI_TRANSACTION
433int soft_serial_transaction(void) {
434 SSTD_t *trans = Transaction_table;
435#else
436int soft_serial_transaction(int sstd_index) {
437 if( sstd_index > Transaction_table_size )
438 return TRANSACTION_TYPE_ERROR;
439 SSTD_t *trans = &Transaction_table[sstd_index];
440#endif
173 cli(); 441 cli();
174 442
175 // signal to the slave that we want to start a transaction 443 // signal to the target that we want to start a transaction
176 serial_output(); 444 serial_output();
177 serial_low(); 445 serial_low();
178 _delay_us(1); 446 _delay_us(SLAVE_INT_WIDTH_US);
179 447
180 // wait for the slaves response 448#ifndef SERIAL_USE_MULTI_TRANSACTION
181 serial_input(); 449 // wait for the target response
182 serial_high(); 450 serial_input_with_pullup();
183 _delay_us(SERIAL_DELAY); 451 _delay_us(SLAVE_INT_RESPONSE_TIME);
184 452
185 // check if the slave is present 453 // check if the target is present
186 if (serial_read_pin()) { 454 if (serial_read_pin()) {
187 // slave failed to pull the line low, assume not present 455 // target failed to pull the line low, assume not present
456 serial_output();
457 serial_high();
458 *trans->status = TRANSACTION_NO_RESPONSE;
188 sei(); 459 sei();
189 return 1; 460 return TRANSACTION_NO_RESPONSE;
190 } 461 }
191 462
192 // if the slave is present syncronize with it 463#else
193 sync_recv(); 464 // send transaction table index
194 465 int tid = (sstd_index<<3) | (7 & nibble_bits_count(sstd_index));
195 uint8_t checksum_computed = 0; 466 sync_send();
196 // receive data from the slave 467 _delay_sub_us(TID_SEND_ADJUST);
197 for (int i = 0; i < SERIAL_SLAVE_BUFFER_LENGTH; ++i) { 468 serial_write_chunk(tid, 7);
198 serial_slave_buffer[i] = serial_read_byte(); 469 serial_delay_half1();
199 sync_recv(); 470
200 checksum_computed += serial_slave_buffer[i]; 471 // wait for the target response (step1 low->high)
472 serial_input_with_pullup();
473 while( !serial_read_pin() ) {
474 _delay_sub_us(2);
201 } 475 }
202 uint8_t checksum_received = serial_read_byte();
203 sync_recv();
204 476
205 if (checksum_computed != checksum_received) { 477 // check if the target is present (step2 high->low)
206 sei(); 478 for( int i = 0; serial_read_pin(); i++ ) {
207 return 1; 479 if (i > SLAVE_INT_ACK_WIDTH + 1) {
480 // slave failed to pull the line low, assume not present
481 serial_output();
482 serial_high();
483 *trans->status = TRANSACTION_NO_RESPONSE;
484 sei();
485 return TRANSACTION_NO_RESPONSE;
486 }
487 _delay_sub_us(SLAVE_INT_ACK_WIDTH_UNIT);
208 } 488 }
489#endif
209 490
210 uint8_t checksum = 0; 491 // initiator recive phase
211 // send data to the slave 492 // if the target is present syncronize with it
212 for (int i = 0; i < SERIAL_MASTER_BUFFER_LENGTH; ++i) { 493 if( trans->target2initiator_buffer_size > 0 ) {
213 serial_write_byte(serial_master_buffer[i]); 494 if (!serial_recive_packet((uint8_t *)trans->target2initiator_buffer,
214 sync_recv(); 495 trans->target2initiator_buffer_size) ) {
215 checksum += serial_master_buffer[i]; 496 serial_output();
497 serial_high();
498 *trans->status = TRANSACTION_DATA_ERROR;
499 sei();
500 return TRANSACTION_DATA_ERROR;
501 }
502 }
503
504 // initiator switch to output
505 change_reciver2sender();
506
507 // initiator send phase
508 if( trans->initiator2target_buffer_size > 0 ) {
509 serial_send_packet((uint8_t *)trans->initiator2target_buffer,
510 trans->initiator2target_buffer_size);
216 } 511 }
217 serial_write_byte(checksum);
218 sync_recv();
219 512
220 // always, release the line when not in use 513 // always, release the line when not in use
221 serial_output(); 514 sync_send();
222 serial_high();
223 515
516 *trans->status = TRANSACTION_END;
224 sei(); 517 sei();
225 return 0; 518 return TRANSACTION_END;
226} 519}
227 520
521#ifdef SERIAL_USE_MULTI_TRANSACTION
522int soft_serial_get_and_clean_status(int sstd_index) {
523 SSTD_t *trans = &Transaction_table[sstd_index];
524 cli();
525 int retval = *trans->status;
526 *trans->status = 0;;
527 sei();
528 return retval;
529}
530#endif
531
228#endif 532#endif
533
534// Helix serial.c history
535// 2018-1-29 fork from let's split and add PD2, modify sync_recv() (#2308, bceffdefc)
536// 2018-6-28 bug fix master to slave comm and speed up (#3255, 1038bbef4)
537// (adjusted with avr-gcc 4.9.2)
538// 2018-7-13 remove USE_SERIAL_PD2 macro (#3374, f30d6dd78)
539// (adjusted with avr-gcc 4.9.2)
540// 2018-8-11 add support multi-type transaction (#3608, feb5e4aae)
541// (adjusted with avr-gcc 4.9.2)
542// 2018-10-21 fix serial and RGB animation conflict (#4191, 4665e4fff)
543// (adjusted with avr-gcc 7.3.0)
544// 2018-10-28 re-adjust compiler depend value of delay (#4269, 8517f8a66)
545// (adjusted with avr-gcc 5.4.0, 7.3.0)
546// 2018-12-17 copy to TOP/quantum/split_common/ and remove backward compatibility code (#4669)
diff --git a/quantum/split_common/serial.h b/quantum/split_common/serial.h
index e566eb8a0..b6638b3bd 100644
--- a/quantum/split_common/serial.h
+++ b/quantum/split_common/serial.h
@@ -1,29 +1,65 @@
1#ifndef MY_SERIAL_H 1#ifndef SOFT_SERIAL_H
2#define MY_SERIAL_H 2#define SOFT_SERIAL_H
3 3
4#include "config.h"
5#include <stdbool.h> 4#include <stdbool.h>
6 5
7/* TODO: some defines for interrupt setup */ 6// /////////////////////////////////////////////////////////////////
8#define SERIAL_PIN_DDR DDRD 7// Need Soft Serial defines in config.h
9#define SERIAL_PIN_PORT PORTD 8// /////////////////////////////////////////////////////////////////
10#define SERIAL_PIN_INPUT PIND 9// ex.
11#define SERIAL_PIN_MASK _BV(PD0) 10// #define SOFT_SERIAL_PIN ?? // ?? = D0,D1,D2,D3,E6
12#define SERIAL_PIN_INTERRUPT INT0_vect 11// OPTIONAL: #define SELECT_SOFT_SERIAL_SPEED ? // ? = 1,2,3,4,5
12// // 1: about 137kbps (default)
13// // 2: about 75kbps
14// // 3: about 39kbps
15// // 4: about 26kbps
16// // 5: about 20kbps
17//
18// //// USE simple API (using signle-type transaction function)
19// /* nothing */
20// //// USE flexible API (using multi-type transaction function)
21// #define SERIAL_USE_MULTI_TRANSACTION
22//
23// /////////////////////////////////////////////////////////////////
13 24
14#define SERIAL_SLAVE_BUFFER_LENGTH MATRIX_ROWS/2 25// Soft Serial Transaction Descriptor
15#define SERIAL_MASTER_BUFFER_LENGTH 1 26typedef struct _SSTD_t {
27 uint8_t *status;
28 uint8_t initiator2target_buffer_size;
29 uint8_t *initiator2target_buffer;
30 uint8_t target2initiator_buffer_size;
31 uint8_t *target2initiator_buffer;
32} SSTD_t;
33#define TID_LIMIT( table ) (sizeof(table) / sizeof(SSTD_t))
16 34
17// Address location defines 35// initiator is transaction start side
18#define SERIAL_BACKLIT_START 0x00 36void soft_serial_initiator_init(SSTD_t *sstd_table, int sstd_table_size);
37// target is interrupt accept side
38void soft_serial_target_init(SSTD_t *sstd_table, int sstd_table_size);
19 39
20// Buffers for master - slave communication 40// initiator resullt
21extern volatile uint8_t serial_slave_buffer[SERIAL_SLAVE_BUFFER_LENGTH]; 41#define TRANSACTION_END 0
22extern volatile uint8_t serial_master_buffer[SERIAL_MASTER_BUFFER_LENGTH]; 42#define TRANSACTION_NO_RESPONSE 0x1
23 43#define TRANSACTION_DATA_ERROR 0x2
24void serial_master_init(void); 44#define TRANSACTION_TYPE_ERROR 0x4
25void serial_slave_init(void); 45#ifndef SERIAL_USE_MULTI_TRANSACTION
26int serial_update_buffers(void); 46int soft_serial_transaction(void);
27bool serial_slave_data_corrupt(void); 47#else
48int soft_serial_transaction(int sstd_index);
49#endif
28 50
51// target status
52// *SSTD_t.status has
53// initiator:
54// TRANSACTION_END
55// or TRANSACTION_NO_RESPONSE
56// or TRANSACTION_DATA_ERROR
57// target:
58// TRANSACTION_DATA_ERROR
59// or TRANSACTION_ACCEPTED
60#define TRANSACTION_ACCEPTED 0x8
61#ifdef SERIAL_USE_MULTI_TRANSACTION
62int soft_serial_get_and_clean_status(int sstd_index);
29#endif 63#endif
64
65#endif /* SOFT_SERIAL_H */
diff --git a/quantum/split_common/split_util.c b/quantum/split_common/split_util.c
index 13b09d5b8..e41b6f638 100644
--- a/quantum/split_common/split_util.c
+++ b/quantum/split_common/split_util.c
@@ -1,31 +1,21 @@
1#include <avr/io.h>
2#include <avr/wdt.h>
3#include <avr/power.h>
4#include <avr/interrupt.h>
5#include <util/delay.h>
6#include <avr/eeprom.h>
7#include "split_util.h" 1#include "split_util.h"
8#include "matrix.h" 2#include "matrix.h"
9#include "keyboard.h" 3#include "keyboard.h"
10#include "config.h" 4#include "config.h"
11#include "timer.h" 5#include "timer.h"
12#include "split_flags.h" 6#include "split_flags.h"
7#include "quantum.h"
13 8
14#ifdef RGBLIGHT_ENABLE 9#ifdef EE_HANDS
15# include "rgblight.h" 10# include "tmk_core/common/eeprom.h"
16#endif 11#endif
12
17#ifdef BACKLIGHT_ENABLE 13#ifdef BACKLIGHT_ENABLE
18# include "backlight.h" 14# include "backlight.h"
19#endif 15#endif
20 16
21#ifdef SPLIT_HAND_PIN
22# include "pincontrol.h"
23#endif
24
25#if defined(USE_I2C) || defined(EH) 17#if defined(USE_I2C) || defined(EH)
26# include "i2c.h" 18# include "i2c.h"
27#else
28# include "serial.h"
29#endif 19#endif
30 20
31volatile bool isLeftHand = true; 21volatile bool isLeftHand = true;
@@ -35,14 +25,13 @@ volatile uint8_t setTries = 0;
35static void setup_handedness(void) { 25static void setup_handedness(void) {
36 #ifdef SPLIT_HAND_PIN 26 #ifdef SPLIT_HAND_PIN
37 // Test pin SPLIT_HAND_PIN for High/Low, if low it's right hand 27 // Test pin SPLIT_HAND_PIN for High/Low, if low it's right hand
38 pinMode(SPLIT_HAND_PIN, PinDirectionInput); 28 setPinInput(SPLIT_HAND_PIN);
39 isLeftHand = digitalRead(SPLIT_HAND_PIN); 29 isLeftHand = readPin(SPLIT_HAND_PIN);
40 #else 30 #else
41 #ifdef EE_HANDS 31 #ifdef EE_HANDS
42 isLeftHand = eeprom_read_byte(EECONFIG_HANDEDNESS); 32 isLeftHand = eeprom_read_byte(EECONFIG_HANDEDNESS);
43 #else 33 #else
44 // I2C_MASTER_RIGHT is deprecated, use MASTER_RIGHT instead, since this works for both serial and i2c 34 #ifdef MASTER_RIGHT
45 #if defined(I2C_MASTER_RIGHT) || defined(MASTER_RIGHT)
46 isLeftHand = !has_usb(); 35 isLeftHand = !has_usb();
47 #else 36 #else
48 isLeftHand = has_usb(); 37 isLeftHand = has_usb();
@@ -94,7 +83,7 @@ void split_keyboard_setup(void) {
94 83
95void keyboard_slave_loop(void) { 84void keyboard_slave_loop(void) {
96 matrix_init(); 85 matrix_init();
97 86
98 //Init RGB 87 //Init RGB
99 #ifdef RGBLIGHT_ENABLE 88 #ifdef RGBLIGHT_ENABLE
100 rgblight_init(); 89 rgblight_init();
@@ -103,17 +92,17 @@ void keyboard_slave_loop(void) {
103 while (1) { 92 while (1) {
104 // Matrix Slave Scan 93 // Matrix Slave Scan
105 matrix_slave_scan(); 94 matrix_slave_scan();
106 95
107 // Read Backlight Info 96 // Read Backlight Info
108 #ifdef BACKLIGHT_ENABLE 97 #ifdef BACKLIGHT_ENABLE
109 if (BACKLIT_DIRTY) { 98 #ifdef USE_I2C
110 #ifdef USE_I2C 99 if (BACKLIT_DIRTY) {
111 backlight_set(i2c_slave_buffer[I2C_BACKLIT_START]); 100 backlight_set(i2c_slave_buffer[I2C_BACKLIT_START]);
112 #else // USE_SERIAL 101 BACKLIT_DIRTY = false;
113 backlight_set(serial_master_buffer[SERIAL_BACKLIT_START]); 102 }
114 #endif 103 #else // USE_SERIAL
115 BACKLIT_DIRTY = false; 104 backlight_set(serial_m2s_buffer.backlight_level);
116 } 105 #endif
117 #endif 106 #endif
118 // Read RGB Info 107 // Read RGB Info
119 #ifdef RGBLIGHT_ENABLE 108 #ifdef RGBLIGHT_ENABLE
@@ -122,14 +111,14 @@ void keyboard_slave_loop(void) {
122 // Disable interupts (RGB data is big) 111 // Disable interupts (RGB data is big)
123 cli(); 112 cli();
124 // Create new DWORD for RGB data 113 // Create new DWORD for RGB data
125 uint32_t dword; 114 uint32_t dword;
126 115
127 // Fill the new DWORD with the data that was sent over 116 // Fill the new DWORD with the data that was sent over
128 uint8_t *dword_dat = (uint8_t *)(&dword); 117 uint8_t *dword_dat = (uint8_t *)(&dword);
129 for (int i = 0; i < 4; i++) { 118 for (int i = 0; i < 4; i++) {
130 dword_dat[i] = i2c_slave_buffer[I2C_RGB_START+i]; 119 dword_dat[i] = i2c_slave_buffer[I2C_RGB_START+i];
131 } 120 }
132 121
133 // Update the RGB now with the new data and set RGB_DIRTY to false 122 // Update the RGB now with the new data and set RGB_DIRTY to false
134 rgblight_update_dword(dword); 123 rgblight_update_dword(dword);
135 RGB_DIRTY = false; 124 RGB_DIRTY = false;
@@ -137,7 +126,9 @@ void keyboard_slave_loop(void) {
137 sei(); 126 sei();
138 } 127 }
139 #else // USE_SERIAL 128 #else // USE_SERIAL
129 #ifdef RGBLIGHT_SPLIT
140 // Add serial implementation for RGB here 130 // Add serial implementation for RGB here
131 #endif
141 #endif 132 #endif
142 #endif 133 #endif
143 } 134 }
diff --git a/quantum/template/avr/config.h b/quantum/template/avr/config.h
index caa72af0c..eed50e5c0 100644
--- a/quantum/template/avr/config.h
+++ b/quantum/template/avr/config.h
@@ -48,17 +48,35 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
48/* COL2ROW, ROW2COL, or CUSTOM_MATRIX */ 48/* COL2ROW, ROW2COL, or CUSTOM_MATRIX */
49#define DIODE_DIRECTION COL2ROW 49#define DIODE_DIRECTION COL2ROW
50 50
51/*
52 * Split Keyboard specific options, make sure you have 'SPLIT_KEYBOARD = yes' in your rules.mk, and define SOFT_SERIAL_PIN.
53 */
54#define SOFT_SERIAL_PIN D0 // or D1, D2, D3, E6
55
51// #define BACKLIGHT_PIN B7 56// #define BACKLIGHT_PIN B7
52// #define BACKLIGHT_BREATHING 57// #define BACKLIGHT_BREATHING
53// #define BACKLIGHT_LEVELS 3 58// #define BACKLIGHT_LEVELS 3
54 59
55// #define RGB_DI_PIN E2 60// #define RGB_DI_PIN E2
56// #ifdef RGB_DI_PIN 61// #ifdef RGB_DI_PIN
57// #define RGBLIGHT_ANIMATIONS 62// #define RGBLED_NUM 16
58// #define RGBLED_NUM 16 63// #define RGBLIGHT_HUE_STEP 8
59// #define RGBLIGHT_HUE_STEP 8 64// #define RGBLIGHT_SAT_STEP 8
60// #define RGBLIGHT_SAT_STEP 8 65// #define RGBLIGHT_VAL_STEP 8
61// #define RGBLIGHT_VAL_STEP 8 66// #define RGBLIGHT_LIMIT_VAL 255 /* The maximum brightness level */
67// #define RGBLIGHT_SLEEP /* If defined, the RGB lighting will be switched off when the host goes to sleep */
68// /*== all animations enable ==*/
69// #define RGBLIGHT_ANIMATIONS
70// /*== or choose animations ==*/
71// #define RGBLIGHT_EFFECT_BREATHING
72// #define RGBLIGHT_EFFECT_RAINBOW_MOOD
73// #define RGBLIGHT_EFFECT_RAINBOW_SWIRL
74// #define RGBLIGHT_EFFECT_SNAKE
75// #define RGBLIGHT_EFFECT_KNIGHT
76// #define RGBLIGHT_EFFECT_CHRISTMAS
77// #define RGBLIGHT_EFFECT_STATIC_GRADIENT
78// #define RGBLIGHT_EFFECT_RGB_TEST
79// #define RGBLIGHT_EFFECT_ALTERNATING
62// #endif 80// #endif
63 81
64/* Debounce reduces chatter (unintended double-presses) - set 0 if debouncing is not needed */ 82/* Debounce reduces chatter (unintended double-presses) - set 0 if debouncing is not needed */
@@ -222,3 +240,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
222#endif 240#endif
223*/ 241*/
224 242
243/* Bootmagic Lite key configuration */
244// #define BOOTMAGIC_LITE_ROW 0
245// #define BOOTMAGIC_LITE_COLUMN 0
diff --git a/quantum/template/avr/readme.md b/quantum/template/avr/readme.md
index d9349811d..d243c66a9 100644
--- a/quantum/template/avr/readme.md
+++ b/quantum/template/avr/readme.md
@@ -12,4 +12,4 @@ Make example for this keyboard (after setting up your build environment):
12 12
13 make %KEYBOARD%:default 13 make %KEYBOARD%:default
14 14
15See [build environment setup](https://docs.qmk.fm/build_environment_setup.html) then the [make instructions](https://docs.qmk.fm/make_instructions.html) for more information. \ No newline at end of file 15See the [build environment setup](https://docs.qmk.fm/#/getting_started_build_tools) and the [make instructions](https://docs.qmk.fm/#/getting_started_make_guide) for more information. Brand new to QMK? Start with our [Complete Newbs Guide](https://docs.qmk.fm/#/newbs).
diff --git a/quantum/template/avr/rules.mk b/quantum/template/avr/rules.mk
index 92f3a03a9..383a3594b 100644
--- a/quantum/template/avr/rules.mk
+++ b/quantum/template/avr/rules.mk
@@ -39,13 +39,24 @@ F_USB = $(F_CPU)
39OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT 39OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT
40 40
41 41
42# Boot Section Size in *bytes* 42# Bootloader selection
43# Teensy halfKay 512 43# Teensy halfkay
44# Teensy++ halfKay 1024 44# Pro Micro caterina
45# Atmel DFU loader 4096 45# Atmel DFU atmel-dfu
46# LUFA bootloader 4096 46# LUFA DFU lufa-dfu
47# USBaspLoader 2048 47# QMK DFU qmk-dfu
48OPT_DEFS += -DBOOTLOADER_SIZE=4096 48# atmega32a bootloadHID
49BOOTLOADER = atmel-dfu
50
51
52# If you don't know the bootloader type, then you can specify the
53# Boot Section Size in *bytes* by uncommenting out the OPT_DEFS line
54# Teensy halfKay 512
55# Teensy++ halfKay 1024
56# Atmel DFU loader 4096
57# LUFA bootloader 4096
58# USBaspLoader 2048
59# OPT_DEFS += -DBOOTLOADER_SIZE=4096
49 60
50 61
51# Build Options 62# Build Options
diff --git a/quantum/template/avr/template.h b/quantum/template/avr/template.h
index 031efc952..0d626ed50 100644
--- a/quantum/template/avr/template.h
+++ b/quantum/template/avr/template.h
@@ -18,12 +18,14 @@
18 18
19#include "quantum.h" 19#include "quantum.h"
20 20
21// This a shortcut to help you visually see your layout. 21/* This a shortcut to help you visually see your layout.
22// The following is an example using the Planck MIT layout 22 *
23// The first section contains all of the arguments representing the physical 23 * The first section contains all of the arguments representing the physical
24// layout of the board and position of the keys 24 * layout of the board and position of the keys.
25// The second converts the arguments into a two-dimensional array which 25 *
26// represents the switch matrix. 26 * The second converts the arguments into a two-dimensional array which
27 * represents the switch matrix.
28 */
27#define LAYOUT( \ 29#define LAYOUT( \
28 K00, K01, K02, \ 30 K00, K01, K02, \
29 K10, K11 \ 31 K10, K11 \
diff --git a/quantum/template/base/keymaps/default/keymap.c b/quantum/template/base/keymaps/default/keymap.c
index 14a8bc0f2..5f0730c8a 100644
--- a/quantum/template/base/keymaps/default/keymap.c
+++ b/quantum/template/base/keymaps/default/keymap.c
@@ -15,32 +15,40 @@
15 */ 15 */
16#include QMK_KEYBOARD_H 16#include QMK_KEYBOARD_H
17 17
18const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { 18// Defines the keycodes used by our macros in process_record_user
19[0] = LAYOUT( /* Base */ 19enum custom_keycodes {
20 KC_A, KC_1, KC_H, \ 20 QMKBEST = SAFE_RANGE,
21 KC_TAB, KC_SPC \ 21 QMKURL
22),
23}; 22};
24 23
25const uint16_t PROGMEM fn_actions[] = { 24const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
26 25 [0] = LAYOUT( /* Base */
26 KC_A, KC_1, KC_H, \
27 KC_TAB, KC_SPC \
28 ),
27}; 29};
28 30
29const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) 31bool process_record_user(uint16_t keycode, keyrecord_t *record) {
30{ 32 switch (keycode) {
31 // MACRODOWN only works in this function 33 case QMKBEST:
32 switch(id) { 34 if (record->event.pressed) {
33 case 0: 35 // when keycode QMKBEST is pressed
34 if (record->event.pressed) { 36 SEND_STRING("QMK is the best thing ever!");
35 register_code(KC_RSFT); 37 } else {
36 } else { 38 // when keycode QMKBEST is released
37 unregister_code(KC_RSFT);
38 }
39 break;
40 } 39 }
41 return MACRO_NONE; 40 break;
42}; 41 case QMKURL:
43 42 if (record->event.pressed) {
43 // when keycode QMKURL is pressed
44 SEND_STRING("https://qmk.fm/" SS_TAP(X_ENTER));
45 } else {
46 // when keycode QMKURL is released
47 }
48 break;
49 }
50 return true;
51}
44 52
45void matrix_init_user(void) { 53void matrix_init_user(void) {
46 54
@@ -50,10 +58,6 @@ void matrix_scan_user(void) {
50 58
51} 59}
52 60
53bool process_record_user(uint16_t keycode, keyrecord_t *record) {
54 return true;
55}
56
57void led_set_user(uint8_t usb_led) { 61void led_set_user(uint8_t usb_led) {
58 62
59} 63}
diff --git a/quantum/template/ps2avrgb/config.h b/quantum/template/ps2avrgb/config.h
index d2c83781f..4ff3513bc 100644
--- a/quantum/template/ps2avrgb/config.h
+++ b/quantum/template/ps2avrgb/config.h
@@ -44,3 +44,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
44 44
45/* key combination for command */ 45/* key combination for command */
46#define IS_COMMAND() (keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT))) 46#define IS_COMMAND() (keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)))
47
48/* Bootmagic Lite key configuration */
49// #define BOOTMAGIC_LITE_ROW 0
50// #define BOOTMAGIC_LITE_COLUMN 0
diff --git a/quantum/template/ps2avrgb/readme.md b/quantum/template/ps2avrgb/readme.md
index 1dcbe6e75..feec722a5 100644
--- a/quantum/template/ps2avrgb/readme.md
+++ b/quantum/template/ps2avrgb/readme.md
@@ -41,4 +41,4 @@ macOS:
414. Place your keyboard into reset. 414. Place your keyboard into reset.
425. Flash the board by typing `bootloadHID -r` followed by the path to your `.hex` file. 425. Flash the board by typing `bootloadHID -r` followed by the path to your `.hex` file.
43 43
44See [build environment setup](https://docs.qmk.fm/build_environment_setup.html) then the [make instructions](https://docs.qmk.fm/make_instructions.html) for more information. 44See the [build environment setup](https://docs.qmk.fm/#/getting_started_build_tools) and the [make instructions](https://docs.qmk.fm/#/getting_started_make_guide) for more information. Brand new to QMK? Start with our [Complete Newbs Guide](https://docs.qmk.fm/#/newbs).
diff --git a/quantum/template/ps2avrgb/rules.mk b/quantum/template/ps2avrgb/rules.mk
index 68d50aec6..85603f955 100644
--- a/quantum/template/ps2avrgb/rules.mk
+++ b/quantum/template/ps2avrgb/rules.mk
@@ -31,8 +31,8 @@ F_CPU = 12000000
31BOOTLOADER = bootloadHID 31BOOTLOADER = bootloadHID
32 32
33# build options 33# build options
34BOOTMAGIC_ENABLE = yes 34BOOTMAGIC_ENABLE = full
35MOUSEKEY_ENABLE = yes 35MOUSEKEY_ENABLE = no
36EXTRAKEY_ENABLE = yes 36EXTRAKEY_ENABLE = yes
37CONSOLE_ENABLE = yes 37CONSOLE_ENABLE = yes
38COMMAND_ENABLE = yes 38COMMAND_ENABLE = yes
diff --git a/quantum/template/ps2avrgb/template.h b/quantum/template/ps2avrgb/template.h
index c3924ee71..b4d6f4662 100644
--- a/quantum/template/ps2avrgb/template.h
+++ b/quantum/template/ps2avrgb/template.h
@@ -18,10 +18,14 @@
18 18
19#include "quantum.h" 19#include "quantum.h"
20 20
21// This a shortcut to help you visually see your layout. 21/* This a shortcut to help you visually see your layout.
22// The following is an example using the Planck MIT layout 22 *
23// The first section contains all of the arguments 23 * The first section contains all of the arguments representing the physical
24// The second converts the arguments into a two-dimensional array 24 * layout of the board and position of the keys.
25 *
26 * The second converts the arguments into a two-dimensional array which
27 * represents the switch matrix.
28 */
25#define LAYOUT( \ 29#define LAYOUT( \
26 k00, k01, k02, \ 30 k00, k01, k02, \
27 k10, k11 \ 31 k10, k11 \